rapomon / geojson-places

Reverse geocoding to determine the location where it is contained (continent, country, region and state) from the latitude and longitude specified. This module also has tools to get lists of continents, country groupings, countries, regions and states in the specified language.
ISC License
55 stars 13 forks source link

lookUp method does not exclude inner hole #3

Closed black-hawk85 closed 1 year ago

black-hawk85 commented 1 year ago

Hey, first of all I want to compliment and thank you for the nice work.

I have noticed that the lookUp method will give me a result if coordinates are within outer boundaries but will not exclude the result if coordinates are also within the inner boundaries.

I'll give you an example with coordinates in Berlin

lookUp(52.5131, 13.4213)

The expected result would be Berlin but I am getting Brandenburg as it is surrounding Berlin

Berlin

black-hawk85 commented 1 year ago

I have made a quick fix to the reverseGeolocation-method. Not sure if it causes any other problems but it works for Berlin and Prag

 const reverseGeolocation = (lat, lng, dataType = null) => {
  if(typeof lat !== 'number' || typeof lng !== 'number') {
      return new Error('Wrong coordinates (lat: ' + lat + ',lng: ' + lng + ')');
  }

  let point = [lng, lat];
  let i = 0;
  let found = false;
  const countries = admin1.features;
  do {
      let country = countries[i];
      if(country.geometry.type === 'Polygon') {
          found = pointInPolygon(country.geometry.coordinates[0], point);
          // --- Fix by DJK: Exclude result when point is in inner hole
          if (found && country.geometry.coordinates.length > 1) {
            let j = 1;
            var exclude = false
            do {
                exclude = pointInPolygon(country.geometry.coordinates[j], point);
                j++;
            } while(j < country.geometry.coordinates.length && !exclude);
            if (exclude)
                found = false
          }
          // ---
      } else if(country.geometry.type === 'MultiPolygon') {
          let j = 0;
          do {
              found = pointInPolygon(country.geometry.coordinates[j][0], point);
              j++;
          } while(j < country.geometry.coordinates.length && !found);
      }
      i++;
  } while(i < countries.length && !found);

  let result = null;
  if(found) {
      if(dataType === 'raw') {
          result = {
              type: 'FeatureCollection',
              features: [ clone(countries[i-1]) ]
          };
      } else {
          let props = countries[i-1].properties;
          let properties = {};
          properties.continent_code = props.cont_code;
          properties.country_a2 = props.iso_a2;
          properties.country_a3 = props.adm0_a3;
          properties.region_code = props.region_code;
          if(props.iso_3166_2 !== '' && !props.iso_3166_2.endsWith('~')) {
              properties.state_code = props.iso_3166_2;
          }
          if(dataType === 'geojson') {
              result = {
                  type: 'FeatureCollection',
                  features: [{
                      type: 'Feature',
                      properties,
                      geometry: clone(countries[i-1].geometry)
                  }]
              };
          } else {
              result = clone(properties);
          }
      }
  }

  return result;
};
rapomon commented 1 year ago

Hi, thanks for the report. I'll check it.

rapomon commented 1 year ago

It should be fixed with version 1.0.7, can you check it? Thanks.

black-hawk85 commented 1 year ago

Hey, yes looks good now :-) thanks. I guess we can close this issue now.

rapomon commented 1 year ago

Ok, thank you!