I want to do a check of GPS location against geofence polygons at intervals, perhaps once a minute. Based upon some example code I found, I've attemped to use GeometryEngine's within operation to compare the point geometry with the polygon geometry.
Using the markup/JS below, when I execute:
zoneBoundaries.queryFeatures(queryParameters);
I always get withinZone as false, even with one huge polygon geometry to test against. I'm having difficulty figuring out how to troubleshoot this. Any suggestions? I really like the GeometryEngine approach to this, and would like to get this working! Thanks for any tips/assistance. --Ray
//Feature service for spatial query
ServiceFeatureTable {
id: zoneBoundaries
url: "https://services3.arcgis.com/pKp5WOFjeV9KSSfr/ArcGIS/rest/services/fake_brushview_polygons/FeatureSe..."
onQueryFeaturesStatusChanged: {
if (queryFeaturesStatus === Enums.TaskStatusCompleted) {
//Create array for features
var features = []
// get the features
while (queryFeaturesResult.iterator.hasNext) {
console.log( "Counting.." );
features.push(queryFeaturesResult.iterator.next());
}
console.log( "number of features in array: ", features.length );
//assign geometry of first feature to var:
var zoneGeometry = features[0].geometry
console.log("zoneGeometry", zoneGeometry)
//Get the current map point
//var newPoint = mapView.currentViewpointCenter.center
var newPoint = mapView.locationDisplay.positionSource.position
console.log("newPoint", newPoint)
//Check to see if currrent point is within zone boundary
var withinZone = GeometryEngine.within(newPoint, zoneGeometry)
console.log("withinZone", withinZone)
}
}
}
//Parameters for query
QueryParameters {
id: queryParameters
whereClause: "1=1"
returnGeometry: true
}
Solved! Go to Solution.
Rayfield,
Use locationDisplay.location.position instead of
locationDisplay.positionSource.position
Hi Rayfield,
Try doing following first, before passing the geometries in "GeometryEngine.within". If it does work then eliminate one projection operation at a time and see which one is necessary.
var geom1 = GeometryEngine.project(<newPointGeometry>, SpatialReference.<whatever>());
var geom2 = GeometryEngine.project(<zoneGeometry>, SpatialReference.<must_be_same_as_above>);
GeometryEngine.within(geom1, geom2)
Kaushik
Great idea to try to get my SR's in sync, thanks for the response!
So I did this (code below). It didn't seem to solve my problem, but the console.log seems to show that the geom1 value becomes null. Does that mean that the newPoint that I'm passing to GeometryEngine is not really a "geometry", and could be part of my problem? Console.log shows newPoint as a QDeclarativePosition if I get it from the code below, and as a QMLPoint if I get it from mapView.currentViewpointCenter.center.
var newPoint = mapView.locationDisplay.positionSource.position
var geom1 = GeometryEngine.project( newPoint, mySpatialReference );
var geom2 = GeometryEngine.project( zoneGeometry, mySpatialReference );
var withinZone = GeometryEngine.within( geom1, geom2 )
console.log( "withinZone", withinZone, geom1, geom2 ) Edit: adding in my spatial reference object for good measure:SpatialReference {id: mySpatialReferencewkid: 4326}
Rayfield,
Use locationDisplay.location.position instead of
locationDisplay.positionSource.position
Excellent, this appears to have solved my problem!
Thanks so much
--Ray
Ray,
You might not be needing this but just an idea - you could also integrate cool features such as "vibrate" and "notification" in your geo-fending app.
For example:
// App notification
LocalNotification
{
id: notification
} if(GeometryEngine.within(geom1, geom2))
{
var notifiationId;
notifiationId = notification.schedule("Some kind of Alert", messageString, 1);
// Also vibrate if(Vibration.supported) {
Vibration.vibrate();
}
}