[PLUGIN] - Google Maps Geometry/Drawing + W3W

why is the table All SetTracks empty when there’s a workflow running every 2 secss to populate it? It should have loads of data in it right?

1 Like

Hi all,

Just documenting a few changes that have happened recently.

The map can now be loaded using aa vector based map if you have a Map ID from Google. It enables 3D buildings and other tilt controls to be used. The option for this is in the main settings shown here.

image

You can get this by going into your Google Console and under the Map Management area, create a new Map ID and use the options below. You must have the map type option set to JavaScript with the 2 checkboxes enabled as shown.

When the map next loads, street view will be like this and you can hold SHIFT on the keyboard to freely move around and zoom into buildings.

If you’re using various shapes on the map, they all become 3 dimensional. Altitude options are not available at the moment but I may at some point in the future include the THREE.js library so markers and other objects can be rendered on top of the map using webGL overviews.


There’s been a new action added called Highlight state and it works in the same way as the Highlight country action. Provide a US state name and it’s edge locations will be used to outline that state, like so…

When using these actions, it’s important to note that no events or anything are setup, they’re just drawn onto the map and that’s it. The only states which is updated are “Center shape coordinates (latitude)” and “Center shape coordinates (longitude)” which could be used as a location point for a Google Places call. Both actions trigger the same event called country or state highlighted.

@boston85719 I’m leading up to trying to get what you wanted done.


Marker clustering has also been included. When switched it on, markers will be clustered so they don’t look so messy on the map when you have a large amount. When you click a cluster, the map zooms in and expands on the markers within that cluster. There’s an associated event called cluster is clicked and some minor styling for the yellow cluster SVG image.

image


Freehand drawing mode for mobiles

Enabled here and when on mobile, allows you to just draw polygons without having to click/tap to plot each new point in the shape, which is tricky on a mobile. On desktop, you can click and hold to draw the shape. Can be tested on the demo site using this small icon.

Polygons can have a huge amount of coordinates when drawn this way and can slow down the map. There’s a throttling option included, read the descriptions.

I think that’s about it for now!

Paul

2 Likes

Man, this is incredible. You just keep adding value with this plugin. I had a question come up recently, and I’m wondering if you might be able to offer some insight: Given a geolocation, I’m interested in calculating the distance to the closest point on a polyline. I know I could do this by calculating the distance to all coordinates that make up the polyline and then simply popping the shortest one from the list. That said, I’m wondering if there is a more elegant and/or performant way to do this that I’m simply overlooking. Thank you for any insights you might offer!

Cheers!

I’m pretty sure I can do that for you, probably not till next week though depending on the rest of my work load right now. I’ll get back to you on it soon.

1 Like

Thank you so much! No worries if it’s not top priority. Honestly, the more I think about it, the more I think the current implementation wouldn’t be that hard for my use case. But certainly would be a useful addition. Cheers!

@pork1977gm Sorry to circle back so soon, but I’m really struggling. Given a blob of coordinates from your plugin states, I am trying to figure out how to translate this into a list of geographic addresses (lat-long pairs) that can be saved to my database, so that I can find the nearest point on a polyline as referenced in my last post. I know I need to split into a list, separate into odd and even numbered indices and then concatenate every nth value from each list together. However, it seems there is no obvious way to do this in vanilla Bubble. I am sure I could make this happen using @keith’s excellent ListShifter plugin but just haven’t been able to work it out yet. It seems to me that even just publishing a list of geographic coordinates, in addition to the coordinate text, as a state would make this kind of thing infinitely easier. Have you considered this?

@ts11 I’m not sure if that actually would be possible in List Shifter (perhaps in multiple steps) though I’m not familiar with what it is that @pork1977gm’s plugin expects.

1 Like

Thanks for popping in, Keith! The plugin outputs a list of coordinates anytime a marker or shape is updated on a map. However, these coordinates are just a comma separated blob of lat-long pairs. I’m simply trying to separate out the individual pairs, so I can save them as geographic addresses in my db and perform bubble native geo calculations with them. It sounds like it should be a snap, but has proved to be tricky. I know you’ve probably harped on this more than anyone else, but it makes absolutely zero sense to me that Bubble doesn’t expose the index of list items to us.

I came across this useful thread which provides some javascript to split a list into even and odd-indexed items.

However, I still need to concatenate those two lists together. I guess I could do this with Process List, but it seems like there should be a less messy way of doing this.

Well, for those following along, I decided to ask ChatGPT for help, and this is what I got. Going to try to implement now via a server script but haven’t really done that before, so would appreciate any insights the community might offer:

const list = [1, 2, 3, 4, 5, 6];

const oddList = list.filter((_, index) => index % 2 === 1);
const evenList = list.filter((_, index) => index % 2 === 0);

const joinedList = [];

for (let i = 0; i < Math.min(oddList.length, evenList.length); i++) {
  joinedList.push(`${oddList[i]},${evenList[i]}`);
}

console.log(joinedList); // output: ["1,2", "3,4", "5,6"]

Oh got it. Yeah, you could do that with PROCESS List. The easiest way is with two List Shifters. I’ve called mine List Shifter Odds and List Shifter Evens. Put your full list of lat/lon pairs into List Shifter Odds as “List to Shift” OR just send your list of Lat/Lons as the “OR USE…” list as an expression when you do the PROCESS List action.

Both List Shifters should be set as type number and also their Process Output Type should be set to number.

Then, to split the odd values into one list (we’ll use List Shifter Odds Processed List), run PROCESS List set up like this (note this assumes Original List in LS Odds is your source list - if you want to use some other expression just put it in that second field:


STEP 1 figure out if List Item Index is odd


STEP 2 Get the List Item, set Push RS2 to Proc(essed) List, set Push/Sum/Set Only If to “Result Step 1”
This will only push the values at the odd indices (your Lats) to List Shifter Odd’s Processed List.

Now copy paste that action. Set the element to List Shifter Evens, Set “OR Use this List” to ListShifter Odd’s Original List (this assumes your full list is held in LS Odd, but this could be whatever expression contains your whole list) and just change the operator in Step 1 to “is even”. This will push the values at the even indices (your Lons) to List Shifter Even’s Processed List.

Runtime:

Shitty example page (see Make Pairs button): List-shifter-dev-test | Bubble Editor

This isn’t correct (of course) and running this on the backend would be wasteful. See my earlier reply for how to do this with PROCESS List. :wink:

1 Like

Haha figures. I’m sure if I asked why it was wrong, ChatGPT would tell me it was because of the prompt and that it had now, in its infinite wisdom, dispatched a task rabbit to my home to beat me into submission. Thank you, @keith, for the help!

1 Like

Hopefully, you don’t need those pairs as numeric ranges @ts11 . I tried to do that with PROCESS List but either something’s bugged with the “make numeric range [x,y]” operator or it’s (derp) not possible because of the way types work with the PROCESS List action. (Someday, when client-side actions can return values, I’ll rework PROCESS List into something much easier to use, but it’s unlikely I’ll fix it even if it’s bugged right now.)

Good call, good idea too.

So for polylines and polygons, if I created an object type of state that is a list which gets populated when the shape has drawn, would that work for you?

Each item in the two states would contain a pair of lat/lng values. Looks like this:

Then you could reference each items lat and each items lng values. Hopefully I got that right!

@ts11 are you using the draw shape action to draw the polyline?

Try this

Paul-testing-4 | Bubble Editor

I’ve pushed the update with 2 additional fields at the top of the settings

image

Each will produce a list of lat/lng pairs which make up a position. The states only get populate when using the draw shape action at the moment and don’t update or anything.

Let us know if I got any of it wrong and I fix it up.

1 Like

Hi Paul,

You have created a wonderful plugin here!

Quick question for you. I have a a Data Type called Activities. Currently when my user wants to create an activity, I create a Thing under the Activities data type, and then use the “Set List of Markers” function to plot it on the map. This part works fine.

I want to give my users the option to remove an activity from the Activities data type and conversely from the map as well. I tried doing this by removing the “Thing” from the Activity data type and then running a subsequent “Set List of Markers” function (i.e. essentially a map refresh); however, it doesn’t delete the point on the map go away (only deletes the entry in Activity data type). So naturally, I looked at the “Remove Marker/Shape” function, but in order to do that, I need a marker ID, and I can’t seem to find where that is stored. Is there a way to locate the marker ID? Ideally, when the user creates a new activity, I would like to have a field in the entry that is equal to the marker ID so that the two are tied.

Hi Jake,

Thank you!

I’m away this weekend so can’t get at my laptop to give you a proper answer, but when you create a new activity, create the marker afterwards and use the unique record ID of that activity to assign to the marker ID. That way, when you delete the activity record, you can reference that unique ID to remove the marker. Run the remove marker action before you remove the activity otherwise the ID won’t exist to use.

You should be able to get the marker ID if needed from the state.

If you make sure all marker ids use the unique id then you should be fine. When a marker is clicked, the marker id state will contain that and you can use it to search your activities table to find the marker.

Thanks for the quick reply Paul; just tested this out and it works! Much appreciated.
Enjoy the rest of the weekend!

You’re welcome, no probs