A Pen by Andreas Borgen on CodePen.
Created
June 12, 2019 16:47
-
-
Save Sphinxxxx/31d33fbbaf3a48e767bab0360bbd52e5 to your computer and use it in GitHub Desktop.
Stolpejakten 2018
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<main> | |
<div id="map-canvas"></div> | |
<!--div id="summary" class="info-pane" ></div--> | |
</main> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
"use strict"; | |
console.clear(); | |
const _state = { | |
map: null, | |
markers: { | |
collection: null, | |
bounds: null, | |
}, | |
curr_info: null, // current marker dialog open | |
curr_info_pane: null, | |
}; | |
/** | |
* Add a marker to the Google Map | |
* @param {[type]} lat Latitude of marker | |
* @param {[type]} lon Longitude of marker | |
* @param {[type]} name Marker name | |
*/ | |
function addMarker(lat, lon, name) { | |
const pos = new google.maps.LatLng(lat, lon), | |
marker = new google.maps.Marker({ | |
//map: map, | |
position: pos, | |
//https://developers.google.com/maps/documentation/javascript/examples/icon-complex | |
icon: { | |
url: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='30' height='30' viewBox='0,0 170,170'%3E %3Cdefs%3E %3Cpath id='map-outline' d='M10,40 l 50,-30 50,30 50,-30 v120 l-50,30 -50,-30 -50,30z' /%3E %3CclipPath id='map-clip'%3E %3Cuse xlink:href='%23map-outline' /%3E %3C/clipPath%3E %3C/defs%3E %3Cg clip-path='url(%23map-clip)'%3E %3Crect width='200' height='200' fill='lime' /%3E %3Crect x='60' width='50' height='200' fill='white' /%3E %3C/g%3E %3Cuse xlink:href='%23map-outline' stroke-width='6' fill='none' stroke='black'/%3E %3C/svg%3E", | |
anchor: new google.maps.Point(15, 15), | |
}, | |
}), | |
info = { | |
name: name, | |
lat: lat, | |
lon: lon, | |
}; | |
//http://stackoverflow.com/questions/11378450/google-map-api-v3-how-to-add-custom-data-to-markers | |
marker.__markerInfo = info; | |
const m = _state.markers; | |
m.bounds.extend(pos); | |
m.collection.addMarker(marker); | |
google.maps.event.addListener(marker, 'click', function () { | |
showInfo([marker], marker); | |
}); | |
} | |
function pan_to(lat, lon) { | |
const map = _state.map, | |
pos = new google.maps.LatLng(lat, lon); | |
//var currZoom = map.getZoom(); | |
let zoom = 15; //Math.max(currZoom+2, 14); | |
//http://stackoverflow.com/questions/5054515/zoom-in-to-marker-google-maps | |
map.setZoom(zoom); | |
map.panTo(pos); | |
} | |
function showInfo(markers, target) { | |
const s = _state; | |
const html = createInfoContent(markers); | |
if(s.curr_info_pane) { | |
s.curr_info_pane.innerHTML = html; | |
} | |
else { | |
if(s.curr_info) { s.curr_info.close(); } | |
s.curr_info = new google.maps.InfoWindow({ | |
content: html, | |
}); | |
s.curr_info.open(s.map, target); | |
} | |
} | |
function createInfoContent(markers) { | |
var htmls = markers.map(marker => { | |
const info = marker.__markerInfo, | |
html = ` | |
<div class="info-window"> | |
<a class="jump" href="#" data-lat="${info.lat}" data-lon="${info.lon}"> | |
${info.name} | |
</a> | |
<!--div class="coords"> | |
Lat: ${info.lat.toFixed(5)}<br/> | |
Lon: ${info.lon.toFixed(5)}<br/> | |
</div--> | |
</div>`; | |
return html; | |
}); | |
var html = htmls.join(''); | |
return html; | |
} | |
/** | |
* Initialize the Google Map | |
*/ | |
function initialize() { | |
const s = _state, | |
m = s.markers; | |
s.curr_info_pane = document.querySelector('.info-pane'); | |
const map = s.map = new google.maps.Map( | |
document.querySelector('#map-canvas'), | |
{ | |
zoom: 3, | |
center: new google.maps.LatLng(61, 11), | |
mapTypeId: google.maps.MapTypeId.ROADMAP, | |
scaleControl: true, | |
//https://stackoverflow.com/questions/45729047/disable-the-ctrl-scroll-to-zoom-google-maps | |
gestureHandling: 'greedy', | |
} | |
); | |
google.maps.event.addListener(map, 'zoom_changed', function () { | |
if(s.curr_info) { s.curr_info.close(); } | |
}); | |
//https://developers.google.com/maps/articles/toomanymarkers#viewportmarkermanagement | |
//https://googlemaps.github.io/js-marker-clusterer/docs/examples.html | |
m.collection = new MarkerClusterer(map, [], { gridSize: 30, zoomOnClick: false }); | |
//http://stackoverflow.com/questions/13213849/force-an-information-window-instead-of-zoom-on-click-and-change-the-icon | |
//http://stackoverflow.com/questions/5710568/markerclusterer-on-click-zoom | |
google.maps.event.addListener(m.collection, 'clusterclick', function(cluster) { | |
var markers = cluster.getMarkers(); | |
//Convert lat/long from cluster object to a usable MVCObject | |
//http://stackoverflow.com/questions/10520940/create-infowindow-for-clustered-markers-using-google-maps-v3 | |
//http://jsfiddle.net/ErYub/ | |
var target = new google.maps.MVCObject(); | |
target.set('position', cluster.getCenter()); | |
showInfo(markers, target); | |
}); | |
m.bounds = new google.maps.LatLngBounds(); | |
document.body.addEventListener('click', e => { | |
const jump = e.target.closest('a.jump'); | |
if(jump) { | |
pan_to(jump.dataset.lat, jump.dataset.lon); | |
} | |
}) | |
} | |
function load() { | |
function addMarkers(organizers) { | |
organizers.results.forEach(o => { | |
o.areas.forEach(a => { | |
const place = [ | |
o.fylke.name, | |
o.kommuner.map(k => k.name).join('/') || o.alias, | |
a.name, | |
].join(' > '); | |
addMarker(a.location[1], a.location[0], place) | |
}); | |
}); | |
const s = _state; | |
s.map.fitBounds(s.markers.bounds); | |
} | |
const organizers = localStorage.sj2018_org; | |
if(organizers) { | |
console.log('Found cached organizers'); | |
addMarkers(JSON.parse(organizers)); | |
} | |
else { | |
fetch('https://api.stolpejakten.no/v6/organizers') | |
.then(r => { | |
console.log('fetched', r.status, r.statusText) | |
return r.text(); | |
}) | |
.then(t => { | |
localStorage.sj2018_org = t; | |
addMarkers(JSON.parse(t)); | |
}); | |
} | |
} | |
google.maps.event.addDomListener(window, 'load', () => { | |
initialize(); | |
load(); | |
}); | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://maps.googleapis.com/maps/api/js?v=3&key=AIzaSyDFakIzRcdWcvBjFvdBnREF--j-7AC3YF8"></script> | |
<script src="https://unpkg.com/gmaps-marker-clusterer@1"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,400italic,700); | |
/* Page layout */ | |
body { | |
display: flex; | |
flex-flow: column nowrap; | |
height: 100vh; | |
margin: 0; | |
header { | |
} | |
main { | |
flex: 1 1 auto; | |
display: flex; | |
#map-canvas { | |
flex: 1 1 auto; | |
position: relative; | |
} | |
#summary { | |
} | |
} | |
} | |
/* Details */ | |
body { | |
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; | |
color: #444; | |
h2 { | |
margin: .5em; | |
} | |
} | |
#summary { | |
background: black; | |
color: white; | |
box-sizing: border-box; | |
padding: .5em 1em; | |
overflow: auto; | |
max-width: 50vw; | |
//transition: width .3s; | |
a { | |
color: orange; | |
} | |
} | |
.info-window { | |
+ .info-window { | |
margin-top: 1em; | |
} | |
.image { | |
display: inline-block; | |
position: relative; | |
vertical-align: top; | |
margin-right: 10px; | |
} | |
.img-thumb { | |
max-width: 120px; | |
max-height: 120px; | |
} | |
.coords { | |
display: inline-block; | |
margin-left: 1em; | |
} | |
.jump { | |
display: block; | |
cursor: pointer; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment