Forum Academy Marketplace Showcase Pricing Features

Integrate GeoFence Query Feature

Hello All. Am new to bubble so forgive me if I structure my question the wrong way. I need an api that will allow me to upload my GeoJSON file of marked areas. And as long as a user send his lat & lon the api will check if the user is in one of the marked region and return the region number. Also if the user is out of the listed regions the checks for the closest region and returns that region’s number. Not too sure if i need an api for this or if a plugin can achieve it

Hi there, I think you can probably leverage one of the map plugins in the marketplace if you want to display the GeoJSON file as a map layer in the UI. (there are a number to choose from). You should also be able to take an address and/or lat and lon to query your dataset. Providing the search and response part of your app will likely require you to store the geo data in the bubble database as well and with some relatively simple workflows should enable you to do what you want.

thanks for reaching out!!!
but I dont want to display the data set i was hoping to use the GeoJSON to create the regions, but it seems like thats not how you do it? the only was i figured out how to do it was with measuring the distance from a central point and in order to get thr curves of the area use smaller central points. Ive attached an example of what i am doing and what i realy want.
the black circles is what i am doing which is SUPER inefficient. and the Green is what I need. I need to make MANY of these so my current solution is very difficult

So basically i just need to know when a users location falls within these region so i can show specific data

any luck with being able to identify users in a specific location and then only send them specific data?

so i use the website geojson.org to make my region boundries


Then you need to label each region with a unique identifier. i used a row call “R#” and assigned it a unique number. Then i created a row called “Reg Name” and assigned it a name. so i can know the name of the region the number is assigned to.
Then copy all the text on the right side panel (including all brackets too) (at this point i had to learn some entry level java, but you luck since i learned it so you just have to follow instructions.) now save that text some where to be retreived later.

now install a free plugin called ToolBox

Now you can run this java script function how ever you like. (i had to reuse mine so its in a custom event. but in the work flow you select run plugin and select “Run JavaScript”
then you just copy the code provided below in the same format below.



The code:---------------
var polys = {
“type”: “FeatureCollection”,
“features”: [
{
“type”: “Feature”,
“properties”: {
“stroke”: “#555555”,
“stroke-width”: 2,
“stroke-opacity”: 1,
“fill”: “#555555”,
“fill-opacity”: 0.5,
“R#”: “0”,
“Reg Name”: “EBD”
},
“geometry”: {
“type”: “Polygon”,
“coordinates”: [
[
[
-58.159496784210205,
6.701125464206165
],
[
-58.15552711486817,
6.710811254272513
],
[
-58.187509775161736,
6.720262439060684
],
[
-58.1911039352417,
6.721509086705866
],
[
-58.191468715667725,
6.718781374883676
],
[
-58.19432258605958,
6.717353582126765
],
[
-58.192262649536126,
6.709948171883384
],
[
-58.18977355957031,
6.710022759310728
],
[
-58.18845391273498,
6.709208956584034
],
[
-58.159496784210205,
6.701125464206165
]
]
]
}
},
{
“type”: “Feature”,
“properties”: {
“stroke”: “#555555”,
“stroke-width”: 2,
“stroke-opacity”: 1,
“fill”: “#555555”,
“fill-opacity”: 0.5,
“R#”: 15,
“Reg Name”: “West Coast”
},
“geometry”: {
“type”: “Polygon”,
“coordinates”: [
[
[
-58.05182218551635,
6.789995192995705
],
[
-58.041973114013665,
6.786926950502525
],
[
-58.04579257965088,
6.774568553662913
],
[
-58.04034233093261,
6.7727786906137775
],
[
-58.033754825592034,
6.799412870651692
],
[
-58.03469896316528,
6.80284324585309
],
[
-58.0460286140442,
6.806742338224818
],
[
-58.0466079711914,
6.8050804338725115
],
[
-58.047380447387695,
6.805250885865716
],
[
-58.05182218551635,
6.789995192995705
]
]
]
}
}
]
}
function isPointInPoly(point, poly, itemNum) {
var x = point[0], y = point[1];
var inside = false;
for (var i = 0, j = poly[‘features’][itemNum][‘geometry’][‘coordinates’][0].length - 1; i < poly[‘features’][itemNum][‘geometry’][‘coordinates’][0].length; j = i++) {
var xi = poly[‘features’][itemNum][‘geometry’][‘coordinates’][0][i][0], yi = poly[‘features’][itemNum][‘geometry’][‘coordinates’][0][i][1];
var xj = poly[‘features’][itemNum][‘geometry’][‘coordinates’][0][j][0], yj = poly[‘features’][itemNum][‘geometry’][‘coordinates’][0][j][1];
var intersect = ((yi > y) != (yj > y))
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
};
var currentLocation = [Dynamic Val Goes Here]
for (var i = 0, j = polys[‘features’].length; i < j; i++) {
result = isPointInPoly(currentLocation ,polys, i)
if (result == true) {
bubble_fn_RegionPolySearch(polys[‘features’][i][‘properties’][‘R#’])
break
}
}

cODE ENDES HERE:------------
So a little explanation:
basically that function close to the end of the code “isPointInPoly” is used to calculate if the coords are located inside a closed polygon. the function loops through the list (The text copied from geojson.io) and returns the region number if true. (am not sure if the “break” keyword is still used at the end of the function, but who cares.)
The line close to the end with the next function “bubble_fn_RegionPolySearch(…)” this is used to return the value of the function to bubble app. ( so the words after “bubble_fn_” can be any thing you want but it has to correspond with the java element on the page, eg “bubble_fn_iAmHere”, “bubble_fn_whatIsLove”, etc, just make sure you get the appended text at the end right cause its case sensitive.)
now if you noticed in my bubble_fn_RegionPolySearch(…) function i have inside the bracket the path to the element name i want returned. (polys[‘features’][i][‘properites’]['R#])
the “R#” here is the path to my label name. so if on geojson.io you created a label name called “Mall Section Name” and need that value to be returned, just replace R# with “Mall Section Name” and what ever name that region has will be returned. just remember that everythin is CASE SENSITIVE. and as a tip on my part i will tell you. EVERY THING IS CASE SENSITIVE.
The part in the code above that says “var currentLocation = [Dynamic Val Goes Here]” the dynamic val is the current user coords. its seperated by only a comma ( , ) but you need to make sure thises values are resolved to numbers and not text. also as a side note to get the user current position with in a 3 meter accuracy you need 8 numerals after the decimal point eg. 6.27922812, -58.92870130
Also the element has to be visible on page load, so i made it a 1x1 size and tuck it away in a corner
so for the next part ** fed up typing yo**
now you add an element to your bubble page called JavascriptToBubble.


i think the highlighted part speaks for it self. so remember the text that you appended to the “bubble_fn_” you have to use that back here. its CASE SENSITIVE. so for my example its “bubble_fn_RegionPolySearch” so i use “RegionPolySearch”
just make sure those boxes are ticked and know what kind of element you want returned. originally i wanted to return an Integer but i had a few probs with it, you can play round with that if you like. but i ultimately choose to return a text.

now for the last step. FINALLY!!!

you need to run a work flow to retreive the javascript value, but thers a trick to it.


so you just have to point to the value of the javascript to bubble element that you added to the page. But the value wont publish until the javascript has already run completely.
so currently i have a little over 20 regions.which covers 35 miles, i need to prob double that to get the total amount of regions i need for my app. and with the current regions a device takes about 3-4 seconds to calculate the current region. so you need to wait that long befor trying to publish the value in the new workflow.

Annnnnnnd youre done.
this is the longest post ive ever made… you better use my solution yo.
but with this you have an idea as to how to do stuff from the java script side, you can prob run this work flow from the backend for a faster result and to freeup device resources but of course you would have to end up paying for the resource power. i just put up a loading screen when doing my calculations, and i also noticed that some devices take longer than5 secs, so i create a work flow that auto runs when a page state is empty called Error Auto fix, so the common user thinks magic is happening in the background when its just me giving the work flow time to run properly.

As a last tip, and the reason why i took ~2 weeks to figure out this solution… EVERY THING IS CASE SENSITIVE!!!

1 Like

thank you thank you thank you. Very detailed response (i appreciate it). I will try to implement and come back with any questions - wish me luck!

1 Like

Hey @akiempaul ,
We just released a plugin that should allow you to implement this feature really easily, and it supports GeoJSON :slightly_smiling_face: :santa:t3:

@brett.miles @justinramdeen

1 Like