GoogleMaps Tiled Multigraph
Deck.gl can allow us to put tiled layers onto GoogleMaps
<!DOCTYPE html>
<html>
<head>
<!-- Include google maps api -->
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&key=__your_google_api_key__" type="text/javascript"></script>
<!-- Include targomo googlemaps full build -->
<script src="https://releases.targomo.com/googlemaps/latest-full.min.js"></script>
<!-- Include deck.gl -->
<script src="https://unpkg.com/deck.gl@latest/dist.min.js"></script>
<script type="text/javascript">
const { MapboxLayer, MVTLayer } = deck;
</script>
<style>
body, html {
margin: 0; width: 100%; height: 100%;
font-family: Helvetica, Arial, Sans-Serif;
}
#map {
width: 100%;
height: calc(100% - 15px);
}
#attribution {
width: 100%; height: 15px;
background-color: #04343f;
display: flex;
justify-content: end;
align-items: center;
font-family: sans-serif;
}
#attribution > a {
font-size: 9px;
padding-right: 5px;
color: #ffffffa8;
text-decoration: none;
}
#tooltip {
background-color: #04343f;
color: #ffffffa8;
font-size: 9px;
padding: 5px;
border-radius: 4px;
display: none;
}
#select-container {
position: absolute; font-size: 11px;
top: 0px; right: 0px;
padding: 5px; z-index: 400;
background-color: white;
}
#select-container > input[type=radio] {
height: 11px;
}
</style>
</head><body>
<!-- where the map will live -->
<div id="map"></div>
<!-- checkbox used to change the mutigraph mode -->
<div id="select-container">
<input type="radio" id="hex" name="mode" value="hex" onchange="setLayer('hexagon')" checked>
<label for="hex">Hexagons</label>
<input type="radio" id="line" name="mode" value="line" onchange="setLayer('line')">
<label for="line">Lines</label>
</div>
<div id="tooltip" style="position: absolute; z-index: 1; pointer-events: none;"></div>
<div id="attribution"><a href="https://www.targomo.com/developers/resources/attribution/" target="_blank">© Targomo</a> <a href='https://www.openstreetmap.org/copyright' target='_blank'>© OpenStreetMap contributors</a></div>
<script>
// create targomo client
const client = new tgm.TargomoClient('northamerica', '__targomo_key_here__');
const sources = [{ id: 1, lat: 40.733831, lng: -74.002154 }, { id: 2, lat: 40.809765, lng: -73.950152 }];
// define the map
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 12, disableDefaultUI: true, zoomControl: true,
center: { lat: (sources[0].lat + sources[1].lat) / 2, lng: (sources[0].lng + sources[1].lng) / 2 },
});
var mapType = new google.maps.StyledMapType([{
featureType: "all", elementType: "all",
clickableIcons: false, draggableCursor:'',stylers: [ { saturation: -100 } ]}
], { name:"Grayscale" });
map.mapTypes.set('grayscale', mapType);
map.setMapTypeId('grayscale');
sources.forEach(source => {
const myLatlng = new google.maps.LatLng(source.lat, source.lng);
const marker = new google.maps.Marker({
position: myLatlng,
map: map
});
});
const deckOverlay = new deck.GoogleMapsOverlay({
layers: []
});
async function setLayer(mode){
const multigraphOptions = {
edgeWeight: "time",
useClientCache: true,
travelType: "transit",
maxEdgeWeight: 1800,
multigraph: {
aggregation: {
type: 'routing_union'
},
layer: {
geometryDetailPerTile: 5,
minGeometryDetailLevel: 5,
maxGeometryDetailLevel: 25,
type: mode === "hexagon" ? "hexagon" : "identity"
},
serialization: {
format: "mvt",
},
domain: {
type: "edge"
}
}
}
// get the MVT tile url for the multigraph tiles
const mgUrl = await client.multigraph.getTiledMultigraphUrl(
sources, multigraphOptions, "mvt"
);
const colors = [
[26, 152, 80], [145, 207, 96], [217, 239, 139],
[254, 224, 139], [252, 141, 89], [215, 48, 39]
];
const layer = new MVTLayer({
data: mgUrl,
pickable: true,
stroked: false,
filled: true,
minZoom: 0, maxZoom: 23,
getLineWidth: 1,
lineWidthMinPixels: 2,
opacity: mode === "hexagon" ? .5 : 1,
getFillColor: d => colors[Math.ceil((d.properties.w / 1800 * 6)) - 1],
getLineColor: d => colors[Math.ceil((d.properties.w / 1800 * 6)) - 1],
onHover: info => setTooltip(info.object, info.x, info.y)
})
deckOverlay.setProps({
layers: [ layer ]
});
deckOverlay.setMap(map);
}
function setTooltip(object, x, y) {
const el = document.getElementById('tooltip');
if (object) {
const travelTime = Math.ceil(object.properties.w / 60)
el.innerHTML = `<strong>Travel Time:</strong> ${travelTime} minutes`;
el.style.display = 'block'; el.style.left = x + 'px'; el.style.top = y + 'px';
} else {
el.style.display = 'none';
}
}
setLayer('hexagon');
</script>
</body>
</html>
Copied to clipboard