[GIS] How to synchronize a map (Google Map), Mapillary and Street View

google mapsgoogle-street-viewjavascriptmapillary

I've an HTML / Javascript page with three divs:

  • Mapillary images on the left
  • map (Google Map) at center
  • Google Street View images on the right

enter image description here

I'm using Google Maps API and Mapillary JS.

Here you are the code (NOTE: you need Mapillary key and Google API Key to execute it ….):

<html>
  <head>
    <meta charset="utf-8">
    <title>Street Image Compare View side-by-side</title>

    <!-- <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> -->

    <link href='https://unpkg.com/mapillary-js@2.5.0/dist/mapillary.min.css' rel='stylesheet'/>

    <script src='https://unpkg.com/mapillary-js@2.5.0/dist/mapillary.min.js'></script>
    <!-- <script src='https://maps.googleapis.com/maps/api/js'></script> -->


    <style>
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #mapillary, #map, #google_streetview {
        float: left;
        height: 100%;
        width: 33%;
      }
    </style>
  </head>
  <body>
    <div id="mapillary"></div>
    <div id="map"></div>
    <div id="google_streetview"></div>
    <script>
      function initialize() {
        var pegman_position = {lat: 42.345573, lng: -71.098326};

        var map = new google.maps.Map(document.getElementById('map'), {
          center: pegman_position,
          zoom: 14
        });

        var panorama = new google.maps.StreetViewPanorama(
            document.getElementById('google_streetview'), {
              position: pegman_position,
              pov: {
                heading: 34,
                pitch: 10
              }
            });


        var mly = new Mapillary.Viewer(
                'mapillary',
                '<PUT_YOUR_MAPILLARY_KEY_HERE>',
                'hUj1JPl_K1WGFZ0_Qs2XIw',
            {
                component: {
                    cover: false,
                },
            });

        mly.setCenter(pegman_position.lat, pegman_position.lon);




        map.setStreetView(panorama);
      }
    </script>
    <script async defer
        src="https://maps.googleapis.com/maps/api/js?key=<PUT_YOUR_GOOGLE_API_KEY_HERE>&callback=initialize">
    </script>
  </body>
</html>

When I click on the arrows on the Street View image (on the right …), I can see the pegman that moves on the map and this is what I want.

I'd like to see also the Mapillary images move in synchronize manner, but they don't move now.

Also I'd like to click on the arrows on Mapillary image (on the left …) and see that pegman moves (at the moment I can move the Mapillary images but pegman doesn't move …), and I'd like to see the Street View images move in synchronize manner.

Examples or suggestions?

Best Answer

I've solved in this way (NOTE: it works if you click on arrows in Google Street View you'll see that Google Mas, OSM maps and Mapillary are updated ...)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Street Image Compare View Side-by-Side</title>

    <link href='https://unpkg.com/mapillary-js@2.5.0/dist/mapillary.min.css' rel='stylesheet' />
    <link href='https://unpkg.com/leaflet@1.0.1/dist/leaflet.css' rel='stylesheet' />

    <script src='https://unpkg.com/mapillary-js@2.5.0/dist/mapillary.min.js'></script>
    <script src='https://unpkg.com/leaflet@1.0.1/dist/leaflet.js'></script>

    <style>
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }

      #mapillary, #google_map, #google_streetview , #osm_map {
        float: left;
        height: 50%;
        width: 50%;
      }
    </style>
  </head>
  <body>
    <!-- ### The page structure ... -->
    <div id="osm_map"></div>
    <div id="mapillary"></div>
    <div id="google_map"></div>
    <div id="google_streetview"></div>

    <script>
      function initialize() {
        //### The original pegman position ...
        var pegman_position = {lat: lat: 42.345573, lng: -71.098326};
        var marker;

        //### Add Google Map ...
        var google_map = new google.maps.Map(document.getElementById('google_map'), {
          center: pegman_position,
          zoom: 14
        });

        //### Add Google Street View ...
        var panorama = new google.maps.StreetViewPanorama(
            document.getElementById('google_streetview'), {
              position: pegman_position,
              pov: {
                heading: 34,
                pitch: 10
              }
            });
        google_map.setStreetView(panorama);

        panorama.addListener('position_changed', function(){
            var latLon = { lat: panorama.getPosition().lat(), lng: panorama.getPosition().lng() };
            marker.setLatLng(latLon);
            osm_map.setView(latLon);

            mly.moveCloseTo(panorama.getPosition().lat(), panorama.getPosition().lng())
                .then(
                    function(node) { console.log(node.key); },
                    function(error) { console.error(error); });

        });

        //### Add Open Street Map  ...
        var osm_map = L.map('osm_map').setView([lat: 42.345573, lng: -71.098326], 14);
        var osmUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
        var osmAttrib='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
        var osm = new L.TileLayer(osmUrl, { maxZoom: 18, attribution: osmAttrib});
        osm_map.addLayer(osm);

        //### Add Mapillary ...
        var mly = new Mapillary.Viewer(
                'mapillary',
                '<PUT_YOUR_MAPILLARY_KEY_HERE>',
                'hUj1JPl_K1WGFZ0_Qs2XIw',
            {
                component: {
                    cover: false,
                }
            }
          );
        mly.setCenter(pegman_position.lat, pegman_position.lon);

        //### Put a marker on OSM map and to synchronize it with Mapillary images locations  ...

        mly.on(Mapillary.Viewer.nodechanged, function (node) {
            var latLon = { lat: node.latLon.lat, lng: node.latLon.lon };

            if (!marker) {
                marker = L.marker(latLon);
                marker.addTo(osm_map);
            } else {
                marker.setLatLng(latLon);
            }
            osm_map.setView(latLon);
        });

        window.addEventListener('resize', function() { mly.resize(); });
      }
    </script>
    <script async defer
        src="https://maps.googleapis.com/maps/api/js?key=<PUT_YOUR_GOOGLE_API_KEY_HERE>&callback=initialize">
    </script>
  </body>
</html>
Related Question