Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Point in Polygon is not working as intended #150

Open
guppykang opened this issue May 29, 2024 · 0 comments
Open

Point in Polygon is not working as intended #150

guppykang opened this issue May 29, 2024 · 0 comments

Comments

@guppykang
Copy link

guppykang commented May 29, 2024

i have a feature collection in the form of a geojson. i used vscode's geojson visualizer and it shows me exactly what i'm expecting as seen below.

Screenshot 2024-05-28 at 7 22 28 PM

i test the following cases to see if my code is working correctly. all features are polygons and multi polygons.

MontanaCoordinates = ValidateLocationParams{
		Latitude:  46.8797,
		Longitude: -110.3626,
	} // should not work

	SanDiegoCoordinates = ValidateLocationParams{
		Latitude:  32.7157,
		Longitude: 117.1611,
	} // should work

	NewYorkCoordinates = ValidateLocationParams{
		Latitude:  40.7128,
		Longitude: 74.0060,
	} // should work

	TorontoCoordinates = ValidateLocationParams{
		Latitude:  43.65107,
		Longitude: 79.347015,
	} // should not work

	LondonCoordinates = ValidateLocationParams{
		Latitude:  51.5074,
		Longitude: 0.1278,
	} // should work

	IrelandCoordinates = ValidateLocationParams{
		Latitude:  53.1424,
		Longitude: 7.6921,
	} // should not work

	AfricaCoordinates = ValidateLocationParams{
		Latitude:  8.7832,
		Longitude: 34.5085,
	} // should not work

	HawaiiCoordinates = ValidateLocationParams{
		Latitude:  19.8968,
		Longitude: 155.5828,
	} // should work

the code below is what i use to see if a single coordinate is inside any of the polygons. it gets all the coordinates it should not work for correctly, but it fails to verify correctly the coordinates that should be working. my geojson looks something like this:

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "GEO_ID": "0400000US25",
                "STATE": "25",
                "NAME": "Massachusetts",
                "LSAD": "",
                "CENSUSAREA": 7800.058
            },
            "geometry": {
                "type": "MultiPolygon",
                "coordinates": [XXX],
             },
       },
      ...
      ...
func (s *service) ValidateDepositLocation(params ValidateLocationParams) error {
	if DepositRegions == nil {
		collection, err := s.readGeoJSONFile("operatingRegions.geojson")
		if err != nil {
			ctx.Errorf("Failed to process operatingRegions.geojson: %v", err)
			return err
		}
		DepositRegions = collection
	}

	if s.isInCollection(ctx, params.Latitude, params.Longitude, DepositRegions) {
		return nil
	}
	return ErrLocationNotValid
}

func (s *service) readGeoJSONFile(filename string) (*orb.Collection, error) {
	file, err := os.ReadFile(filename)
	if err != nil {
		return nil, fmt.Errorf("failed to read %s: %v", filename, err)
	}

	collection := orb.Collection{}
	fc, err := geojson.UnmarshalFeatureCollection(file)
	if err != nil {
		return nil, fmt.Errorf("failed to unmarshal %s: %v", filename, err)
	}

	for _, feature := range fc.Features {
		if feature.Geometry != nil {
			collection = append(collection, feature.Geometry)
		} else {
			return nil, fmt.Errorf("feature has no geometry %v", feature.ID)
		}
	}

	return &collection, nil
}

func (s *service) isInCollection(lat float64, lon float64, collection *orb.Collection) bool {
	if collection == nil {
		ctx.Error("Collection is nil")
		return false
	}

	point := orb.Point{lon, lat}

	for _, g := range *collection {
		switch geo := g.(type) {
		case orb.Polygon:
			if planar.PolygonContains(geo, point) {
				return true
			}
		case orb.MultiPolygon:
			if planar.MultiPolygonContains(geo, point) {
				return true
			}
		default:
			ctx.Errorf("Unsupported geometry type: %v", g.GeoJSONType())
		}
	}

	return false
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant