Geofence. Extension. Check if a point (coordinates) is inside a polygon. Map

KIO4_Geofence.java

package com.KIO4_Geofence;
//  © Juan Antonio Villalpando 
// http://kio4.com/appinventor/251_exten_geofence_javascript.htm
// 2022/05/04

import com.google.appinventor.components.annotations.DesignerComponent;
import com.google.appinventor.components.annotations.DesignerProperty;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.annotations.SimpleObject;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.common.PropertyTypeConstants;
import com.google.appinventor.components.runtime.*;

@DesignerComponent(version = 1,
    description = "Geofence. Find out if a point is inside a polygon. " 
	+ "Juan Antonio Villalpando - KIO4.COM ",
    category = ComponentCategory.EXTENSION,
    nonVisible = true,
    iconName = "") 
@SimpleObject(external = true)
public class KIO4_Geofence extends AndroidNonvisibleComponent implements Component {

    private ComponentContainer container;
    public KIO4_Geofence(ComponentContainer container) {
        super(container.$form());
        this.container = container;
    }

////////////////////////// FUNCION /////////////////////////
@SimpleFunction(description = "Example String polygon: [[36.53,-6.27],[36.51,-6.28],[36.54,-6.29],[36.55,-6.22]]. Return boolean.")
public boolean Geofence(String polygon, String latitude, String longitude){
	float point[] = new float[2];
	point[0] = Float.valueOf(latitude);
	point[1] = Float.valueOf(longitude);

	int puntos = -1; // Vertices del poligono.
	 for (int i = 0; i < polygon.length(); i++) {
		if (polygon.charAt(i) == '[') {puntos++;}}
		
	float polygonF[][] = new float[puntos][puntos]; // Array float 2 dimensiones.
	polygon = polygon.replace("[", "").replace("]", "");		
	String[] polygonArray = polygon.split(",");
	
	 for (int i = 0; i < puntos; i++) {
		 polygonF[i][0] =  Float.valueOf(polygonArray[i*2]);
		 polygonF[i][1] =  Float.valueOf(polygonArray[i*2+1]);
	 }

	boolean odd = false;

	for (int i = 0, j = polygonF.length - 1; i < polygonF.length; i++) { 
		if (((polygonF[i][1] > point[1]) != (polygonF[j][1] > point[1])) 
			&& (point[0] < (polygonF[j][0] - polygonF[i][0]) * (point[1] - polygonF[i][1]) / (polygonF[j][1] - polygonF[i][1]) + polygonF[i][0])) {
			odd = !odd;
		}
		j = i;
	}
	return odd;
}

}	// ==> FIN

The code returns a boolean true or false.

4 Likes

2.- Check if the indicated coordinate is inside the polygon. Map.

p251_geofenceExtension_Mapa.aia (11.7 KB)

  • We draw a polygon in a Map using LineString.PointsFromString, note that the initial and final coordinates are the same so that the polygon closes:

LineString.PointsFromString=[[36.50318,-6.27281],[36.50226,-6.27231],[36.50198,-6.27311],[36.50291,-6.27361],[36.50263,-6.27298],[36.50318,-6.27281]]

  • We set the check polygon with these coordinates:

poligono = [[36.50318,-6.27281],[36.50226,-6.27231],[36.50198,-6.27311],[36.50291,-6.27361],[36.50263,-6.27298]]

  • We move by means of a Clock, a point horizontally:

punto = [36.5027,h]

  • We can stop the Clock using "Stop" and tap on the map, using the TapAtPoint block we can see if the point is inside or outside the polygon.

- Designer.

- Blocks.

- Comments.

  • It also works if we set the query polygon by repeating the initial coordinate at the end:
    poligono = [[36.50318,-6.27281],[36.50226,-6.27231],[36.50198,-6.27311],[36.50291,-6.27361],[36.50263,-6.27298],[36.50318,-6.27281]]
5 Likes