Plotting locations on Google Maps

Plotting locations on Google Maps

Postby TimStone » Fri Mar 03, 2017 10:50 pm

I've had no problem calling a Google map for a single location.

Now I want to do something different. I want to plot multiple locations ( pins ) on a Google Map from my database. The plan is to show where customers exist near a business.

Has anyone done this ? It's a very common activity on the web, so I assume people have done it with FWH.

Help is appreciated.
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2946
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: Plotting locations on Google Maps

Postby anserkk » Mon Mar 06, 2017 12:56 pm

Image

Code: Select all  Expand view  RUN
#Include "FiveWin.ch"
//-----------------------------
Function Main()
    Local aData:={ {'Antonio (Spain)'   , 36.510328, -4.882490},;
                   {'Sylvio (Italy)'    , 42.979704, 13.664149},;
                   {'Otto (Austria)'    , 46.752694,12.419472} }                  

    TestGoogleMap(aData)
Return NIL

//-----------------------------------------------------------------------/
Function TestGoogleMap(aData)
   Local cMapFile:="D:\GMaps.htm", cHtmlContent1,cHtmlContent2, oOle, i
   Local cAppendStr:="var locations = ["+CRLF
   
   For i:=1 to Len(aData)
       cAppendStr+=Space(4)+"['" +aData[i][1] +"',"+Ltrim(Str(aData[i][2]))+","+ Ltrim(Str(aData[i][3]))+ If( i < Len(aData), "],", "]") +CRLF
   Next
   cAppendStr+="];"+CRLF

TEXT INTO cHtmlContent1
   
    <html>
    <head>
     
      <title>Google Maps Multiple Markers</title>
      <script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>
    </head>
    <body>
      <div id="map" style="height: 100%; width: 100%;">
    </div>
    <script type="text/javascript">
   
ENDTEXT
   
   
TEXT INTO cHtmlContent2    
       
     var map = new google.maps.Map(document.getElementById('map'), {
     zoom: 0,          
      mapTypeId: google.maps.MapTypeId.ROADMAP
      });
     var bounds = new google.maps.LatLngBounds();
     var infowindow = new google.maps.InfoWindow();
   
     var marker, i;
   
    for (i = 0; i < locations.length; i++) {
         var position = new google.maps.LatLng(locations[i][1], locations[i][2]);
            bounds.extend(position);
            marker = new google.maps.Marker({
            position: new google.maps.LatLng(locations[i][1], locations[i][2]),        
            map: map
      });
   
      google.maps.event.addListener(marker, 'click', (function(marker, i) {
      return function() {
      infowindow.setContent(locations[i][0]);
      infowindow.open(map, marker);
      }
      })(marker, i));

      // Automatically center the map fitting all markers on the screen
      map.fitBounds(bounds);
         
    }
  </script>
  </body>
  </html>
   
ENDTEXT

   MEMOWRIT( cMapFile, cHtmlContent1+cAppendStr+cHtmlContent2 )

   oOle:=CreateObject("InternetExplorer.Application")
   oOle:width:=675
   oOle:height:=520
   oOle:Visible:=.t. // Displays the Browser
   oOle:ToolBar:=.f. // Disables the toolbar
   oOle:StatusBar:=.f. // Disables status bar
   oOle:MenuBar:=.f. // Disables the menu bar
   oOle:Navigate(cMapFile) // Open the Webpage
   SysRefresh()
   
Return
User avatar
anserkk
 
Posts: 1333
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Plotting locations on Google Maps

Postby Marc Venken » Mon Mar 06, 2017 1:34 pm

Very Nice !!

The FWH community on Google Maps :

Here we go :wink:

Marc Venken, Belgium , 51.053734 - 5.606073
Marc Venken
Using: FWH 23.04 with Harbour
User avatar
Marc Venken
 
Posts: 1447
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium

Re: Plotting locations on Google Maps

Postby Silvio.Falconi » Mon Mar 06, 2017 4:43 pm

Dear anserkk,
your test here not run ( I have win 7 64 bit ie, chrome,firefox )

many days ago I asked a question for the Google Map because On win7/8-7/10 the oldest my function not run ok
None answer to me, I hope you can help me

when I show the map I have script error

this is the test.prg
Code: Select all  Expand view  RUN
Function Mappa_google(cStreet,cCity,cCountry)
      local oFrmMappa, oActiveX

    DEFAULT    cCountry := PadR( "ITALY", 80 )
    DEFAULT  cStreet := PadR( "SAN MARINO", 80 )
    DEFAULT  cCity := PadR( "TERAMO", 80 )

   IF !IsGoogleup()
      MsgAlert("Non trovo la connessione a internet!"+CRLF+"Non posso visualizzare la mappa geografica")
      RETURN nil
   ENDIF

    Define DIALOG oFrmMappa TITLE "Mappa Geografica - con MapGoogle " ;
       FROM 452, 774 to 880, 1303 PIXEL COLOR 0, 14215660

       oActiveX&#058;=TActiveX():New(oFrmMappa, "Shell.Explorer", 5,5, 255, 140 )

         @   154,   5 SAY "Indirizzo.:" SIZE  80,   7 PIXEL  OF oFrmMappa  COLOR 0, 14215660
         @   168,   5 SAY "Località.:" SIZE  80,   7 PIXEL  OF oFrmMappa  COLOR 0, 14215660
         @   184,   5 SAY "Stato.:" SIZE  80,   7 PIXEL  OF oFrmMappa  COLOR 0, 14215660

         @   152,  30 GET cStreet  SIZE  160,  10 PIXEL OF oFrmMappa
         @   168,  30 GET cCity    SIZE  120,  10 PIXEL OF oFrmMappa
         @   182,  30 GET cCountry SIZE  100,  10 PIXEL OF oFrmMappa


       @  202,    2 BUTTON oButStampa    Prompt "&Stampa"    SIZE  45,  10 PIXEL  OF oFrmMappa ACTION NIL
       @  202,  157 BUTTON oButConferma Prompt "&Ricerca" SIZE  50,  10 PIXEL  OF oFrmMappa ;
                                                ACTION Show( cStreet, cCity, cCountry, oActiveX )
       @  202,  212 BUTTON oButAnnulla  Prompt "&Uscita"  SIZE  50,  10 PIXEL  OF oFrmMappa ACTION oFrmMappa:End()

     ACTIVATE DIALOG oFrmMappa CENTERED ;
      ON INIT Show( cStreet, cCity, cCountry, oActiveX )
     RETURN NIL

Function IsGoogleup()
MsgWait( "Sto provando se trovo una connessione a internet","Aspetta un momento",3 )
WSAStartup()
return  GetHostByName( "www.google.com" ) != "0.0.0.0"



 


this test use
local cHtml := MemoRead( ".\MAPPE\gmap.html" )
Have you a test where I can insert this html into prg code ?
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 7076
Joined: Thu Oct 18, 2012 7:17 pm

Re: Plotting locations on Google Maps

Postby TimStone » Mon Mar 06, 2017 5:37 pm

You are using coordinates. I have addresses. I know we can feed either to Google Maps, but what is the format for using street addresses instead ?

Thank you.
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2946
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: Plotting locations on Google Maps

Postby anserkk » Tue Mar 07, 2017 1:20 am

TimStone wrote:You are using coordinates. I have addresses. I know we can feed either to Google Maps, but what is the format for using street addresses instead ?

Thank you.


If you don't have LAT and LNG then you need to call Google API's with the address. If found, Google will return the LAT and LNG, you may then pass the received LAT and LNG from Google to display the Markers on Google Maps using the code I posted in this thread. Few months back, I had already shared the code to find out the LAT and LNG from the address of a place in the forum.

I shall try to create a sample with the latest Google API's.

Regards

Anser
User avatar
anserkk
 
Posts: 1333
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Plotting locations on Google Maps

Postby anserkk » Tue Mar 07, 2017 1:34 am

Silvio.Falconi wrote:your test here not run ( I have win 7 64 bit ie, chrome,firefox )

The sample that I posted uses OLE using Internet explorer. If you inspect the code then you would notice the following line at the bottom of the sample.
oOle:=CreateObject("InternetExplorer.Application")

My sample basically creates a .html file. So if you know the trick to call a .html file using Chrome or Firefox (Try shell command). Then it should work. You may modify the bottom portion of the sample code ie instead of calling Internet Explorer call your favorite Internet browser.

Silvio.Falconi wrote:many days ago I asked a question for the Google Map because On win7/8-7/10 the oldest my function not run ok
None answer to me, I hope you can help me

Google keeps changing their API's and you need to keep a watch on this and modify the code accordingly.

Silvio.Falconi wrote:Have you a test where I can insert this html into prg code ?

The sample that I have posted in this thread creates html inside the prg.
User avatar
anserkk
 
Posts: 1333
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Plotting locations on Google Maps

Postby anserkk » Tue Mar 07, 2017 4:18 am

TimStone wrote:You are using coordinates. I have addresses. I know we can feed either to Google Maps, but what is the format for using street addresses instead ?

Thank you.


Here is a complete sample that serves your purpose. You can provide Addresses, Google will find out the details (if available) and then displays on the map. The Map's zoom position adjusts itself in such a way that all the markers are displayed on a single screen.

Code: Select all  Expand view  RUN
#Include "FiveWin.ch"

//-----------------------------
Function Main()
    Local aLatLng:={}
    Local aAddress:={ {"Eiffel Tower","Champ de Mars"            , "5 Avenue Anatole France", "75007 Paris"         ,"France" },;
                      {"Taj Mahal"   ,"Dharmapuri, Forest Colony", "Tajganj, Agra"          , "Uttar Pradesh 282001","India"  } }
     
    // This function will grab the Lat and Lng information from Google and returns an array
    aLatLng:=GetLatLng( aAddress)

    // Displays Markers on a Google Map
    ViewGoogleMap(aLatLng)
Return NIL

//------------------------------------------//
Function GetLatLng(aData)
  Local i,cName,cAddress,cCity,cState,cCountry,aLatLng:={},nLatitude,nLongitude
  Local oHttp, cURL, lNetError, cResponse,hJson
 
  For i:=1 to Len(aData)
 
    cName:=STRTRAN(ALLTRIM(aData[i][1])," ","+")
    cName:=STRTRAN(ALLTRIM(aData[i][1]),"&"," E ")
    cAddress:=STRTRAN(ALLTRIM(aData[i][2]),",","")
    cAddress:=STRTRAN(ALLTRIM(aData[i][2])," ","+")
    cCity:=STRTRAN(ALLTRIM(aData[i][3])," ","+")
    cCountry:=STRTRAN(ALLTRIM(aData[i][5])," ","+")  
    cState:=aData[i][4]
   
    oHttp:=CreateObject("Microsoft.XMLHTTP")
    cURL:="http://maps.google.com/maps/api/geocode/json?address="+cAddress+"+"+cCity+"+-+"+cState+"+"+cCountry+"&sensor=false"
    oHttp:Open("GET",cURL,.F.)
    lNetError:=.F.
    TRY
        oHttp:Send()
    CATCH oError
        lNetError:=.T.
    END TRY
   
    IF !lNetError
      cResponse := oHttp:ResponseBody
    ELSE
      // Search Error. Could not find the details on Google Maps.
      Loop
    ENDIF    

    hb_jsonDecode(cResponse,@hJson)
    nLatitude:= hJson["results"][1]["geometry"]["location"]["lat"]
    nLongitude:=hJson["results"][1]["geometry"]["location"]["lng"]    
   
    Aadd(aLatLng,{aData[i][1],nLatitude, nLongitude} )
   
  Next
 
Return aLatLng

//-----------------------------------------------------------------------/
Function ViewGoogleMap(aData)
   Local cMapFile:="D:\GMaps.htm", cHtmlContent1,cHtmlContent2, oOle, i
   Local cAppendStr:="var locations = ["+CRLF
   
   For i:=1 to Len(aData)
   
       cAppendStr+=Space(4)+"['" +aData[i][1] +"',"+Ltrim(Str(aData[i][2]))+","+ Ltrim(Str(aData[i][3]))+ If( i < Len(aData), "],", "]") +CRLF
   
   Next
   cAppendStr+="];"+CRLF

TEXT INTO cHtmlContent1
   
    <html>
    <head>
     
      <title>Google Maps Multiple Markers</title>
      <script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>
    </head>
    <body>
      <div id="map" style="height: 100%; width: 100%;">
    </div>
    <script type="text/javascript">
   
ENDTEXT
   
   
TEXT INTO cHtmlContent2    
       
        var map = new google.maps.Map(document.getElementById('map'), {
          zoom: 0,          
          mapTypeId: google.maps.MapTypeId.ROADMAP
        });
        var bounds = new google.maps.LatLngBounds();
        var infowindow = new google.maps.InfoWindow();
   
        var marker, i;
   
        for (i = 0; i < locations.length; i++) {
         var position = new google.maps.LatLng(locations[i][1], locations[i][2]);
            bounds.extend(position);
          marker = new google.maps.Marker({
            position: new google.maps.LatLng(locations[i][1], locations[i][2]),        
            map: map
          });
   
          google.maps.event.addListener(marker, 'click', (function(marker, i) {
            return function() {
              infowindow.setContent(locations[i][0]);
              infowindow.open(map, marker);
            }
          })(marker, i));

          // Automatically center the map fitting all markers on the screen
          map.fitBounds(bounds);
         
        }
      </script>
    </body>
    </html>
   
ENDTEXT

     MEMOWRIT( cMapFile, cHtmlContent1+cAppendStr+cHtmlContent2 )
/*
     oOle:=CreateObject("InternetExplorer.Application")
     oOle:width:=675
     oOle:height:=520
     oOle:Visible:=.t. // Displays the Browser
     oOle:ToolBar:=.f. // Disables the toolbar
     oOle:StatusBar:=.f. // Disables status bar
     oOle:MenuBar:=.f. // Disables the menu bar
     oOle:Navigate(cMapFile) // Open the Webpage
     SysRefresh()
*/

    // Opens the Map using your default internet browser. A more generic solution
     Shellexecute( NIL, "open", cMapFile )  
   
Return


Regards
Anser
User avatar
anserkk
 
Posts: 1333
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Plotting locations on Google Maps

Postby brewster » Wed Mar 08, 2017 2:50 am

Mr Anserkk,

Thank you for your sharing of the sample.

I wonder if you have done any work with best route capability.

Meaning, have many stops/destinations and let Google figure out best route.

Thanks in advance.

Bruce S.
brewster
 
Posts: 43
Joined: Wed Jun 20, 2012 4:07 am

Re: Plotting locations on Google Maps

Postby TimStone » Thu Mar 09, 2017 4:55 pm

Thank you for the code.

I found that the GetLatLng( ) can fail. I have a list of addresses, and when submitted, the function returned a long stream of data with the message that the location was not found. Then the map fails. You trap for an error code, but this is what Google issues instead. I have seen this happen in a browser also, and the error pops up on the screen.

Also, in this case, you are using the geocode to get the locations and then plug them into the routine. Google Maps should be able to accept the addresses themselves and do the translation. It does this on the Static Maps. The problem with the static maps is there is no control to enlarge or shrink the view, nor can you move the map around.

Tim
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2946
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: Plotting locations on Google Maps

Postby Silvio.Falconi » Thu Mar 09, 2017 5:12 pm

here your first and last code not run
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 7076
Joined: Thu Oct 18, 2012 7:17 pm

Re: Plotting locations on Google Maps

Postby TimStone » Thu Mar 09, 2017 6:51 pm

After a lot of testing, I can create the MapFile ( but geolocation translation is very slow ), but it will not display.

Here is the mapfile that is created. Perhaps you can see an error.

Code: Select all  Expand view  RUN

        <html>
        <head>
            <title>Google Maps Multiple Markers </title>
            script src = "http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>
        </head>
        <body>
            <div id="map" style="height: 100%; width: 100%;">
            </div>
            <script type="text/javascript">
var locations = [
    ['25181 Derby Circle',33.5962614,-117.6977416],
    ['26691 Cortina Dr',33.592491,-117.663996],
    ['22482 Alma Aldea 308',33.6352467,-117.5928169],
    ['23242 La Mar Apt A',33.6243645,-117.6726187],
    ['25675 Taladro Circle B',33.6200999,-117.682796],
    ['5505-A Paseo del Lago W',33.6131753,-117.7422594],
    ['29092 Bouquet Canyon Rd',33.6916688,-117.6233598],
    ['24341 Fordview St',33.609178,-117.696739],
    ['5544-A Rayo Del Sol',33.6042954,-117.7470005],
    ['24272 Augustin St',33.609494,-117.681049],
    ['24631 Spadra Ln',33.605176,-117.662258]
];
        var map = new google.maps.Map(document.getElementBZyId('map'), {
            zoom 0,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        });
        var bounds = new google.maps.LatLngBound();
        var infowindow = new google.maps.InfoWindow();

        var marker, i;

        for (i=0, i < locations.length; i++ ) {
            var position = new google.maps.LatLng(locations[i][1, locations[i][2]);
            bounds.extend(position);
            marker = new google.maps.Marker({
                position: new google.maps.LatLng(locations[i][1], locations[i][2]),
                map: map
            });

            google.maps.event.addListener(marker, 'click', (function(marker,i) {
                return function() {
            infowindow.setContent(locations[i][0]) ;
            infowindow.pen(map, marker);
            }
            ))(marker, i));
            // Automatically center the map fitting all markers on the screen
            map.fitBounds(bounds);

        }
        </script>
        </body>
        </html>


 
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2946
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: Plotting locations on Google Maps

Postby cnavarro » Thu Mar 09, 2017 7:02 pm

Silvio.Falconi wrote:here your first and last code not run


For me, first and last code of Anserkk run OK
Cristobal Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
User avatar
cnavarro
 
Posts: 6549
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Plotting locations on Google Maps

Postby Ruth » Thu Mar 09, 2017 8:27 pm

Very nice that you also plot "Otto Atzwanger"´s location. Please don´t forget that in July (03-05 July 2017) this place will be the host of the 1st [xHarbour] INTERNATIONAL CONFERENCE ... hope you all take part. Here is the link to more details. Kind regards and sorry that I place this info a little bit out of topic :) Kind regards from Sillian Ruth
http://www.bergland.info/xharbour-2017-international-conference-20170703-20170705/
User avatar
Ruth
 
Posts: 172
Joined: Fri Dec 07, 2007 1:26 pm

Re: Plotting locations on Google Maps

Postby TimStone » Thu Mar 09, 2017 11:11 pm

The translation time for the geocode is quite long when creating a map. So I decided to get the codes and store them in the database for each address.

I have created a utility as a subset of what was provided above. All works fine except when Google cannot match the location, and at that point it doesn't create an error, but there is no value in the array ( or actually, there is not an array, so then FW errors.

Here is an extract of the code. nLEN is a variable to hold the value returned from the decode. If it is 0, then it should block the next steps ... but apparently it returns a value other than 0 in this process.

Code: Select all  Expand view  RUN

            IF !lNetError
                cResponse := oHttp:ResponseBody
            ELSE
                // Search Error. Could not find the details on Google Maps.
                LOOP
            ENDIF

            nLen := hb_jsonDecode(cResponse,@hJson)
      IF nLen == 0
                MsgInfo("No value returned")
            ELSE
                nLatitude := hJson["results"][1]["geometry"]["location"]["lat"]
                nLongitude := hJson["results"][1]["geometry"]["location"]["lng"]

          oMapClients2:clcus4 := TRIM(STR(nLatitude)) + " | " + TRIM(STR(nLongitude) )
          oMapClients2:save( )
      ENDIF

 


Unfortunately the database will have some bad addresses. For example, a mobile home located in a park, has an address 123 Main Street Sp 41, Toledo OH. The SP41 ( space 41 ) makes Google not find the address. Since this client ( like most ) has over 30 years of address data, there will be mistakes and thousands of records to be corrected.

Thoughts on trapping hjson values that do not have an array would be appreciated.
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2946
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Next

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 46 guests