Plotting locations on Google Maps

User avatar
TimStone
Posts: 2536
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA
Contact:

Plotting locations on Google Maps

Post by TimStone »

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
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
User avatar
anserkk
Posts: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Plotting locations on Google Maps

Post by anserkk »

Image

Code: Select all

#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
Marc Venken
Posts: 727
Joined: Tue Jun 14, 2016 7:51 am

Re: Plotting locations on Google Maps

Post by Marc Venken »

Very Nice !!

The FWH community on Google Maps :

Here we go :wink:

Marc Venken, Belgium , 51.053734 - 5.606073
Marc Venken
Using: FWH 20.08 with Harbour
User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

Re: Plotting locations on Google Maps

Post by Silvio.Falconi »

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

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 ?
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
User avatar
TimStone
Posts: 2536
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA
Contact:

Re: Plotting locations on Google Maps

Post by TimStone »

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
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
User avatar
anserkk
Posts: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Plotting locations on Google Maps

Post by anserkk »

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: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Plotting locations on Google Maps

Post by anserkk »

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: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Plotting locations on Google Maps

Post by anserkk »

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

#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
brewster
Posts: 43
Joined: Wed Jun 20, 2012 4:07 am

Re: Plotting locations on Google Maps

Post by brewster »

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.
User avatar
TimStone
Posts: 2536
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA
Contact:

Re: Plotting locations on Google Maps

Post by TimStone »

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
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

Re: Plotting locations on Google Maps

Post by Silvio.Falconi »

here your first and last code not run
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
User avatar
TimStone
Posts: 2536
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA
Contact:

Re: Plotting locations on Google Maps

Post by TimStone »

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

        <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
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
User avatar
cnavarro
Posts: 5792
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Plotting locations on Google Maps

Post by cnavarro »

Silvio.Falconi wrote:here your first and last code not run
For me, first and last code of Anserkk run OK
C. Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
User avatar
Ruth
Posts: 67
Joined: Fri Dec 07, 2007 1:26 pm
Contact:

Re: Plotting locations on Google Maps

Post by Ruth »

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- ... -20170705/
User avatar
TimStone
Posts: 2536
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA
Contact:

Re: Plotting locations on Google Maps

Post by TimStone »

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

            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
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
Post Reply