Google Maps for Servoy update
Google Maps for Servoy update
Today, we are going to reintroduce our component for Google Maps for putting map and geographic functionality into applications which are built in Spervoi. This is not the first time we’ve done a webinar about this particular feature. This is something quite common in a lot of our customer’s applications. But a couple of colleagues of mine recently updated this component because they had some customer requirements and yeah, this is somewhat of a major release and I think it warrants a webinar because the functionality has been enhanced a lot and a few things have changed. So what we have in store today, as you know, this is the 82nd edition of the Tech webinar series and we always like to start with a demo so you could see stuff first and then if you want to stick around we’ll go over what we just saw. And in today’s demo, I’m going to show some of the map marker properties and events that we’ve exposed and kind of go over how the API has changed. So then after that we’ll get to some overview of what’s new and run through just a quick batch of slides. So let’s get to the demo. I’m going to go over to something I have here already in the browser, a very simple application that I built this morning. There’s a more comprehensive sample solution that ships with the component and I’ll present the webinar. I’ll show you how to get to that which really shows how to use every part of the component. Today I’m just going to focus on what’s new. So first of all, you can see that I have some data. These are customers from the customer database or like sample database, the customer table and on the map you can see that there are markers for all the customers. If I do a search, say, France, you can see that it zooms in on the markers that match on the search keyword, France. What I want to do is go into Servoy Developer and show how this is set up and show what was different about adding the markers to the map that’s changed since the last release. So I’m coming into Servoy Developer, our IDE, looking at the form. You can see the search box, the grid and the map component. And if I move my Zoom controls that you can’t see, I can get to the properties. So you can see that on the map here we have the properties and there are, there is a property for markers and so you can directly bind to a found set and that’s a one common way to do that. But I’m going to show you how to do it programmatically, also using the new API for generating markers. So I’m going to come in here to the JavaScript file that is behind this form and I’ve made a method here called set markers and I’m going to go over this a little bit line by line because I did this so that it sets up some of the things that are new. So first of all, I clear all the markers from the map and then I start looping over the records in the found set. There’s only about 90 of them in this case so looping in this way makes sense. One thing that I want to point out quickly but we’ll come back to it because it’s a bit more, it’s not one of the core topics is that we did change the, we deprecated latitude and longitude from the map marker in favor of a property called position which is really a little object that has a lat and a long property. Some of the properties we deprecated are to bring it more in line really with the Google Maps marker class so that if you’re looking at how to do something in Google Maps and then you look at the API and Servoy they’re the same rather than put our own stuff in there so it’s more transparent to move between the two. Now there’s a position instead of a latitude and longitude separate properties. Something that we’ve always had is the ability to put in an address and allow Google Maps a geocode or to geocode it so that it can show up in the map. Something I’ve done here is if I added to the customer stable a lat and a long field and if those exist we use it meaning the record has already been geocoded otherwise we’d pass in the address and allow Google Maps to geocoded. Later I’ll show you how we actually save that back out. This improves performance and gets around some of the limitations for throttling what you’re using the geocode or API. So that’s just one thing I want to point out that now there’s this property called position. Moving into the marker itself we now have an API called create marker which returns the marker object that you can programmatically interact with. It’s a lot nicer than it used to be. The things that are required are you can pass in a I don’t know if it’s required but a big thing now is you can pass in an ID which seems simple enough but it allows you to link it to the actual record that you’re showing. So it’s very important that you pass in that ID because later when you handle all these new events then I’m going to show you you need to figure out oh yeah which record are we talking about. So we’re going to come back to that mark ID. Again the position is also new and tool tip was deprecated it’s now called, it’s now called it’s now called title and so I’m passing in the company name for title so you can see over on the map as I hover over these it’s showing the names of the of the companies in the tool tip. Pretty easy so far. Something else that you might have noticed is that there’s a bit of animation that’s been added. In this case I use the drop you get to use bounce or drop or nothing. So animation is a new feature so you can see the pins kind of drop on the map. So opacity is something that was added so you can add a value between 0 and 1 to have a translucent marker. So I put these at about 50%. So if I change my search I’ll put in USA. And so you can see the pins there I don’t know how quick the refresh is through the meeting. I’ll do it again put in Germany and you can see the pins dropping on the map when I recreate those markers. You also might notice that these are not really fully opaque in places where there’s probably multiple markers in the same place. You can see they’re a bit darker but I’m using that opacity property which is new. Another thing that we now handle are directly marker events and in the overview I’ll go over all the events. There’s actually quite a lot of events we support anything that Google Maps has. We just exposed those events as is one of them could be a click event. So you can see that if I click on San Francisco here that it highlights the record in the list here. So I’m changing the selection. I also updated the animation so that now you can see the selected record is bouncing. I can also do that advice first if I start selecting records here in the grid. You can see the record that I’m selecting is bouncing up and down. Let’s go back into the IDE and just see how we set that up. You can see that well I’ve got to go first to the form design. You have to enable which events you’re going to listen for so that’s step one. So there’s a new property here marker events and what you can do is you can click and add an event listener and then pick all of the exposed events there. I think a couple dozen events that you can listen to. You can see in my example I’m listening to the click and double click for the, that should be drag. I think I accidentally changed that drag end. I want. I want to get to that for another example. That would have messed me up. So you can see that for the marker events you add the events that you want to listen for. Then what you need to do is over here there’s an on marker event which kind of bundled those all together and I’ve handled that here. We see what it does is it passes in the event object and then you get the event type. So it’s going to be one of those many event types that you saw on the drop down. In this case I grabbed the type and I put it into a switch statement because there could be a lot and I check each case. So if the case was click all I’m doing here is calling foundset.selectrecord and this is where that marker ID comes back because you saw that when I was creating the marker I passed in the primary key of the record as the ID of the marker so that when it comes back to me through the event like they oh I know which record was select was clicked on because they’re linked with the ID and then I select it back in the foundset that’s linked to that grid. So that’s how that you when I should probably I actually edited a map some relaunch in the client. So you can see that when I I’m using a unreleased version of Servoy that I didn’t update and there’s this little bug where I have to reactivate this solution because one of the modules gets disconnected and I think this was already six just give me a second here. It wouldn’t be a demo without stuff like this and back to my solution. Don’t do demos with unreleased versions of your software. Okay. Let’s do the hook it back up now. No. That’s really weird. Evo this is the part where you ask a really interesting question. Do you want to distract the audience? Yeah. This happened this morning and I thought oh no this is going to happen in the demo unless I don’t modify the map and I actually modified it when I should have just hit on do. Let me try this one more then it’s just going to break the search. It doesn’t really affect the demo but it’s nice to be able to search and jump around and get a smaller subset. I did have a question shown when you selected a record or a point on the map of marker. Can you select two or three and then do things? Now you’re coming with hard questions. Yeah, you can because it handles yeah I didn’t think of that. Why didn’t I make that in the demo? Because you’re really just handling the low level click event. So knowing that a marker was clicked is all you need to know and Servoy supports a multi select based found set. So in fact you could pretty easily just add that to the set of selected indexes versus just saying this is the selected record. That would be a one line code change versus the example that I’m having. We’re going to try the search one more time. Oh geez it’s really weird. Okay well I should have updated to I’m running on the nightly build but then I didn’t update for many days so that’s what’s going on here. I think this was some issues that was fixed at some point. Anyway we can do this as zoomed way out or with all the records here. It’s not a big deal. You already saw how the search was was zooming in. What I was getting at here is that if I were to click one of these records you can see that it calls back and that’s based on that mark ID that links them together. To your question Evo yeah I could just I could handle a modifier on the click event like a shift or a control and find that out and then I could instead of set selected record I could or select record. I could there’s a method called set selected indexes and I could start to build up a list of the selections. It would be a more than one line of code. Be a couple lines of code to do it. The other way around was that I was selecting the record by also you can see how some of the pins read your op. because I’m switching the animation and I think there’s an issue switching it to none instead of drop. So I left it switching it back to drop so it redrops it. But you can see that as I click through the record selection on the left here it animates that. It also was changing the opacity. Now you can see that it that’s the other thing. So I wanted there was one other side of this that I didn’t show you which was if we go back to the event not the event of the click but the record selection event on the form. So as you know forms in Servoy are easily data bound. And so anytime that record selection happens in the grid or programmatically I’m handling the event and I have another method here which is show selected record on map. And here I did a little bit of work because I wanted to clear the selected the previous selected record. So I stored that in a little form variable by ID and here comes another API that was added having to do with the marker ID for linking. You can get marker by ID. So when I got the marker through the click event I pulled the ID to select the record. This is coming the other direction. The record has been selected. I grabbed the marker by ID using the customer ID of the record which you can see down here. So in this case I’m actually removing what I had set. So I put the animation back to null and I put the opacity back to 50% and then I clear the variable. But the important stuff is down here where I get the selected record of the found set. I get the marker by ID for the record that’s been selected and then I change the animation to that bounce and then I set the opacity to 100% and then I store it in that variable. So just showing here how again it’s linked by the records primary key and handling an event on the map or in the data binding. In this case the record selection I can interact with the markers through those new APIs. So that really gives you the full linkage between data binding in the form and also what’s happening on the map and that’s how I can go back and forth. Something else that I’m able to do is handle dragging. So suppose that I want to move this marker here to another location and then record it. I could click here and drag it, put it down, say in Florida and then it’s going to say marker moved, update this records position. So I put a little notification to the user. I can click cancel and I had to refresh the map in this case but I think that’s an issue we can get around. But you can see it went back to where it was or I can do it again and I can click yes. And now it will actually stay there. I wrote that back to the record. We have had applications in use cases where users want to actually edit on the map. They want to be able to move a feature to another location. You could reverse geocode it too and peg it to an address if you wanted to. So this kind of allows you to go both ways and you can interact with the geographic feature and then record what you did back to the record. So I’ll go back to the IDE. Again, if we go back to the map view and look at the properties I handled in the marker events that you’re at again and it goes back to that that bundler event here on marker event. And this time I go back to that switch statement that I showed before. You can see it’s a event was drag end. That means I’m done dragging. What I do is I selected the record that was dragged and then I show this input. I probably could have put this first before doing anything where I asked the question to the user. I’m going to minimize this. And then if the user says yes, then or doesn’t say yes, what I do is I revert it back to what was on the record. I set that position property. And in this case I had to call, I don’t know why that’s there. Maybe that was causing an issue. I call refresh on the map, but it should be that anytime because when I set opacity or animation it seems to update immediately but position for some reason I had to call map refresh. So I think that’s a small bug that I’m going to file after the webinar and we can look into because you shouldn’t have to call map refresh. In any event I reset the position back to what was in the record if they if they canceled. And then I return. But if they if they did accept it then I’m writing it to the record and you can see again I’m using that position property here and I write it right to the select record of the found set and I save it. Of course there could be some other process going on here. But if I actually close the client and reopen and you would see that that marker would still be in Florida even after the client session ended because it was it was fully persistent. And I’m going to check one more time if I cut rid of that issue with the searching. Yeah, the time it worked. Okay, it should be back in Florida. It’s not there. I don’t know what happened. I went off script a bit there. But I don’t think it was in maybe it wasn’t in the USA. Nope. I thought maybe it was Canadian. Not sure what happened there. But I was checking this before it was writing it back to the record but you get the idea that basically you handle the drag event and then you can update the record. Then you could also do this to click and add new features to the map paneling the click event. It’s really up to you because you have full programmatic control. Let me think here. There was something else I need to show you. One thing that I mentioned earlier was when I was making the markers you could see that I said if the lat long exists and the record use it, otherwise geocode the address. I have to come clean here. I cheated and I geocoded all of these before the webinar because there’s a bit of a performance. If you geocoding too quickly then the Google API will tell you you’re exceeding the limits and you’ll start to slow down artificially and it makes for a bad demo. So I did cheat and do that in advance and then stored those on the record but this would be a best practice anyway because you wouldn’t want your user to have that experience too. What you can do is geocode records that you have and store it so that it’s much faster. You can see those pins drop really quickly. There’s no calculating. I want to show you an event that was added to help you handle this. If you look at the properties of the map you can see that there’s yet another new event that was added on marker geocoded and I added a handler for that. It passes in the marker object and the new position which is also the same as the marker position. So what you can see is again I used that marker ID property to find the record and then if I find it I’m just editing that record and updating it with what was returned in the geocode or what was assigned back to the marker. I could have also used this lat long object to grab that position and then I write that back into the record so that when I’m going back to the set markers method where I’m first creating those it’s going to say yeah record dot lat does exist so I’m going to use it so I get a bit of that performance improvement but the very first time if I would go through and clear all those then it would regeocode them and the on geocode callback would write it to the record. There’s other ways you could do it you could do it fully programmatically like not through the map but directly through the API and that might be in a production use case that might be better where you sort of geocode them not for user session but in background batch operation or something. You get the idea that there’s a there’s an event to call back if it’s been geocoded and then I can I can know that it now has coordinates and use those instead so that that was added as well. Sorry I wanted to say your performance remark that you just made is raising a question by somebody they’re asking if there are any limits as to usage and it’s Google charging for some of the things that you can do with this. Right right yeah I sort of breeze through that. There are limits the API is free. One thing I didn’t show also is that you need an API key you can go to your Google developer console to get one I think there’s some instructions on the project wiki about that and you have to there’s a property to get your API key and this is covered in all those other webinars I talked about but you can just bind it to a form variable or a scope variable or something and I have one in there that I included otherwise it did won’t show the map so first of all you need an API key but that’s easily done. The second thing is that for their API is like the geocoding or reverse geocoding they will limit the number of calls you can make. I think it’s they call it queries per second or something and they throttle it to I don’t know 50 or I forget what it is so that if you start to exceed that then it starts returning a bad result and then fortunately our component will slow down the geocode it’s actually built in it will start to build in a slow down so that it throttles the request so you don’t get a in the end they’ll all be geocoded it’ll just slow it down for you so you don’t get the bad result from the API and then you’d have to handle that yourself and do the throttle in yourself but we actually put that in the component so you can give a list of 500 markers and send them to Google and they will geocode and we’ll throttle it for you but the result is is that unless you pay for a business license I think you can’t geocode really quickly on demand a bunch of markers even the there’s 90 records in the customer found set here even those there was a performance issue when I when I led it to just geocode them all at once so therefore it’s a good practice to to store the coordinates latitude and longitude if you’re going to if you know that you’re going to use them again if it’s something where you if you don’t know it then then yeah you got a geocode it on demand but hopefully you don’t have to do a big batch of them so there are limits there but it is free and you can get around it by by caching it cool there is a question about route mapping and maybe I got one too I saw it lately in my Amazon app that they tell you these days your driver is six stops away and you can actually see where he is right these that FedEx is doing stuff like that as well I don’t know if you can talk about that yeah sure and you might have noticed on the map properties here there is use a Google map directions on route changed so there’s some routing stuff there that I didn’t go over the reason is is that in a prior webinar I think it was the last webinar I did about this component we had added those and so when it’s something’s new we do a webinar and and and we introduce it so fortunately we have all of our webinars in our archives and if you if you go to and I’ll show the link at the end if you go to that then you can watch that webinar also there is what I can do I think it’s sample G maps this ships with oh I didn’t double click there we go there is another example solution so the example solution you saw I really did just build it this morning in like two hours before the webinar so it is it is easy and productive to do this kind of stuff but the and I will share it when we post the recording but there is a now it’s not this one I’m sorry Google Maps example must be that one yeah that looks more like it let me launch that in the client there is a get my API key okay everyone close your eyes don’t copy my API key and abuse it there is so that that was a good example what I was talking about so it won’t work without the API key obviously you don’t want to ask your user to plug it in so here you can see this ships with with the modules so you can get this off the project site and now you can see there’s there’s like a routing option and a phi oh let me pick two records here evo this is about to also you’re talking about multi-select here it goes the other way so you can see that if I put um two in here and I turn on routing it it’ll actually show the routing and then you can you can get the route info programmatically from the API so and there’s also if the routing changes there’s an event for that so there’s quite some stuff about routing as well so you can look at the documentation on the project site and watch the prior webinar very cool also well we’re on here there’s if you if you needed to show where you’re always showing like a dot or a marker for a point feature like a city but if you have other geographic data that you want to show there’s a standard for that called KML which is the markup language for adding other features like polygon or lines so for example if I click this this was in another webinar you can actually see the these are the metro lines in Chicago so you can overlay stuff onto onto your map as well if you want to show other features and interact with those a bit more advanced but you can do that as well you ready for another question of course somebody’s asking about location privacy yeah okay good yeah that location privacy so let me let me maybe restate the question because I think I know what which means suppose I want to show I don’t know I’m looking at Airbnb type thing and they don’t want to reveal the actual address but they want to show you the neighborhood that it’s in right in that case you might want to show a radius around something but not actually show the marker itself there is oh it’s right here there is a radius option let me just oh it’s really small that’s why yeah we could we could programmatically zoom in on this so so in this case I don’t show the marker itself but I show a radius around it to be fair it is centered on on the marker so you could kind of guess that it’s in the middle of the circle but it doesn’t have to be so you’re able to to do some privacy stuff if you want to using the radius option and again all of this stuff is in the example that ships with the module that you can get off the project and end in the documentation I should show that here if you go to well I’ll show it in the links at the end too but if you go to this is what’s new in this release but if you go to the project site and go to the wiki and you get all the API documentation here and it’s pretty complete so and the sample solution is in the releases while you can download I’ll go back to that in the assets you can always download the dot Servoy example there if you’re brand new to this you can also when you’re when you’re adding a component on the map you just if you don’t see it here you have to add the package you click add components and that launches the package manager and then you can pick one of you know all the many components that we ship that you would add to your project do we have other questions Evo? I think I ran through most of them. I remember somebody asking about normalizing an address but I don’t know if that’s a Google Maps thing or more. Okay I think I know what that is. Let me leave this up while we talk. Yeah if you maybe want to end you start entering in your address and then you you know you misspell the street a little bit or you call it a road instead of street and it’s really lane or whatever like that so they have address of validation and scrubbing API. There’s others other than Google that do that. Those are different APIs they don’t go through the Maps component so yeah if you want to shoot me an email or post on the forum that would be more ideal on forum.cirro.com there’s a there’s a a forum thread for this that goes on and on back to the beginning of the series and if you want to post your feedback and your questions there we can talk about address scrubbing and address validation because that’s a really nice feature when people start to enter you know an address and then you want to make sure they got it right so then after they enter you scrub it and show it back to them that’s a really common thing in business applications. Evo I’m going to skip all the slide overview but I’ll post it in the it basically goes over everything we saw but we’re getting long on time here and it really just goes over and some of the things we didn’t see maybe I should go over real quick. So I talked about Marker ID the title goes in the tool tip we went over animation you can say that a marker is not trackable they’re dragable by default no they’re not I had to set it trackable that was in that that set marker thing so you say marker dot dragable equals true and then then you can drag it otherwise it drags the map so switch solutions now otherwise it drags the map instead of the marker so you want to make that distinction when you’re making the marker and adding into the map it’s just one single property we added the opacity we saw that I was changing it when they selected it I put it to fully opaque I didn’t show this but you can also show it hide markers so if you want to if you want to not show them but still leave them on the map it’s really convenient because you don’t want to re-add it you want to just kind of fetch the marker and turn it off and then later fetch it again and turn it on Z index it’s just which markers show on top that’s nice when you have a cluster of them sitting together you maybe want to put the marker that was selected on top or something like that I had this in the example but I didn’t show it maybe I’ll do this real quick so if I go to my set markers method here to open this in script editor if I go to this so this was I said it’s a dragable true if I turn this off then you can’t drag the marker anymore it will pan the map instead so you do want to set that I forgot to point that out I was talking about the zoom controls always in my way sorry the icon media I missed that so that was here and I commented this out hoping to remind myself to go back over it so I’m going to I’m going to save that and go here now it’s broken again all I have to do is relaunch it and it’ll it’ll redraw up the pins now the pins are little Servoyicons and when I click them they turn opaque and bounce so you can you can bring media into your project so you can see that I brought in the Servoye marker and that here I use the media URL for that so if you have icons you just put them in your project and reference them and you can you can change the marker so that’s kind of fun and the other property that I was talking about was oh that was that was the one the events we added there’s a bunch of them I showed you click and I showed you drag and but they’re really the low-level events that are actually in the Google API so there’s all the click events plus the individual mouse components that might make that up like up down then click we have mouse over and mouse out so you could you could do things that they mouse over a marker for example and then the drag start drag end and well they’re dragging and those are just some of the events there’s even more a lot of them have to do with like property changes which might not be that useful because mostly you’re changing the properties from your own code anyway but you never know so it’s nice to know that if any of those properties changes like on Z index change or whatever you can get a callback for that and handle it so we support everything that the API supports the events are nearly identical for the map events especially the mouse and click events and drag events so if you want to change the map drag event to something other than panning you could you could do it it could be that you’re trying to draw a line on the map and you want to handle the drag event the click event instead of the normal click you could add a point to your map and then add a new record to your your found set so this really exposes the API and you can get busy with it and there’s a lot of the map change events too I think there’s even more map events the marker so those are all in the little drop down in the properties when you’re adding listeners for those events I talked about the geocode callback so I think that covers everything so I’ll just leave these up and if there’s any last few questions we’ll take them but we should probably wrap up that is a lot of remarks great demo great features nice components awesome again the recordings posted at the the tech series homepage I will push out notifications when it’s available probably later today on the forum on the IDE notifications and on our social channels the I showed you the homepage for the component there’s wiki documentation there also the example solution the second one that I showed when I post the recording I’ll also post the sample that I used which is much smaller but focused on what’s new and of course if you have any feedback please please put it on the forum we’d like to get your feedback good bad or otherwise and your questions there so everyone can benefit cool fantastic job was always so Sean thank you thank you goodbye everyone all right have a good day