|
| 1 | +<!DOCTYPE html><html lang="ja"><head><meta charset="utf-8"/> |
| 2 | + |
| 3 | +<title>バス停さがしマップ</title> |
| 4 | + |
| 5 | +<link rel="apple-touch-icon" href="icon-busstop-big.png"/> |
| 6 | +<meta property="og:image" content="busstopmap.jpg"/> |
| 7 | +<link rel=" stylesheet" href=" https://unpkg.com/[email protected]/dist/leaflet.css" /> |
| 8 | +<script src=" https://unpkg.com/[email protected]/dist/leaflet.js" ></script> |
| 9 | +<script src="https://code4fukui.github.io/egmapjs/egmap.js"></script> |
| 10 | +<link rel="stylesheet" href="https://code4fukui.github.io/egmapjs/egmap.css"/> |
| 11 | +<script src="https://fukuno.jig.jp/fukuno.js"></script> |
| 12 | +<script src="https://code4fukui.github.io/egmapjs/sparql.js"></script> |
| 13 | +<script>"use strict" |
| 14 | + |
| 15 | +window.onload = function() { |
| 16 | + var map = initMap('mapid') |
| 17 | + map.setZoom(18) |
| 18 | + map.panTo([ 35.943560,136.188917 ]) // 鯖江駅 |
| 19 | + |
| 20 | + let icons = [] |
| 21 | + const showIcons = function() { |
| 22 | + for (let icon of icons) |
| 23 | + map.removeLayer(icon) |
| 24 | + icons = [] |
| 25 | + |
| 26 | + // SPARQLクエリー (参考データ https://fukuno.jig.jp/app/odp/finddata.html ) |
| 27 | + var query = ` |
| 28 | + prefix ic: <http://imi.go.jp/ns/core/rdf#> |
| 29 | + prefix xsd: <http://www.w3.org/2001/XMLSchema#> |
| 30 | + prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> |
| 31 | + prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> |
| 32 | + prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> |
| 33 | + prefix jrrk: <http://purl.org/jrrk#> |
| 34 | +
|
| 35 | + select ?uri ?name ?lat ?lng ?wifi ?plugs ?charge { |
| 36 | + ?uri rdf:type <http://purl.org/jrrk#BusStop>. |
| 37 | + ?uri rdfs:label ?name. |
| 38 | + ?uri geo:lat ?lat. |
| 39 | + ?uri geo:long ?lng. |
| 40 | + filter( |
| 41 | + xsd:float(?lat) < $LAT_MAX && xsd:float(?lng) > $LNG_MIN && |
| 42 | + xsd:float(?lat) > $LAT_MIN && xsd:float(?lng) < $LNG_MAX |
| 43 | + ) |
| 44 | + } limit 1000 |
| 45 | + ` |
| 46 | + var p = map.getCenter() |
| 47 | + const dl = .02 // 取得する広さ 大きいほど広く取得 |
| 48 | + query = query.replace("$LAT_MAX", p.lat + dl) |
| 49 | + query = query.replace("$LAT_MIN", p.lat - dl) |
| 50 | + query = query.replace("$LNG_MAX", p.lng + dl) |
| 51 | + query = query.replace("$LNG_MIN", p.lng - dl) |
| 52 | + |
| 53 | + querySPARQL(query, function(data) { |
| 54 | + var items = data.results.bindings |
| 55 | + for (var i = 0; i < items.length; i++) { |
| 56 | + var item = items[i] |
| 57 | + var uri = item.uri.value |
| 58 | + var lat = item.lat.value |
| 59 | + var lng = item.lng.value |
| 60 | + var name = item.name.value |
| 61 | + var s = "<a href=" + uri + ">" + name + "</a>" |
| 62 | + icons.push(map.addIcon(lat, lng, s, "icon-busstop.png", 64 )) |
| 63 | + } |
| 64 | + }) |
| 65 | + } |
| 66 | + showIcons() |
| 67 | + |
| 68 | + showhere.onclick = function() { |
| 69 | + showIcons() |
| 70 | + } |
| 71 | + let watchid = null |
| 72 | + gohere.onclick = function() { |
| 73 | + if (watchid) |
| 74 | + navigator.geolocation.clearWatch(watchid) |
| 75 | + watchid = navigator.geolocation.watchPosition(function(gpos) { |
| 76 | + const pos = [ gpos.coords.latitude, gpos.coords.longitude ] |
| 77 | + console.log(pos) |
| 78 | + map.panTo(pos) |
| 79 | + showIcons() |
| 80 | + navigator.geolocation.clearWatch(watchid) |
| 81 | + watchid = null |
| 82 | + }, function() { |
| 83 | + alert("現在位置に取得に失敗!") |
| 84 | + }) |
| 85 | + } |
| 86 | + |
| 87 | + setShowLL(map) |
| 88 | +} |
| 89 | + |
| 90 | +const setShowLL = function(map) { |
| 91 | + // センタークロス追加 |
| 92 | + const iconcenter = L.icon({ |
| 93 | + iconUrl: 'crosshairs.png', |
| 94 | + iconRetinaUrl: 'crosshairs.png', |
| 95 | + iconSize: [ 35, 35 ], |
| 96 | + iconAnchor: [ 17, 17 ], |
| 97 | + }); |
| 98 | + const crosshair = new L.marker(map.getCenter(), { icon: iconcenter, clickable:false }) |
| 99 | + crosshair.addTo(map); |
| 100 | + map.on('move', function() { |
| 101 | + crosshair.setLatLng(map.getCenter()); |
| 102 | + }); |
| 103 | + |
| 104 | + var showLL = function() { |
| 105 | + var ll = map.getCenter() |
| 106 | + if (window.tfll) |
| 107 | + tfll.value = fixfloat(ll.lat, 6) + "," + fixfloat(ll.lng, 6) |
| 108 | + } |
| 109 | + showLL() |
| 110 | + map.on("move", showLL) |
| 111 | +} |
| 112 | + |
| 113 | +</script> |
| 114 | +<style> |
| 115 | + |
| 116 | +body { margin: 0; font-family: sans-serif; text-align: center; } |
| 117 | +h1 { font-size: 3vw; margin: 0; } |
| 118 | +#mapid { height: 60vh; } |
| 119 | +button { |
| 120 | + background: #fa7; |
| 121 | + color: white; |
| 122 | + font-weight: bold; |
| 123 | + padding: 1em; |
| 124 | + margin: 0.5em; |
| 125 | +} |
| 126 | +#showhere { |
| 127 | + background: #7a7; |
| 128 | +} |
| 129 | + |
| 130 | +</style></head><body> |
| 131 | + |
| 132 | +<h1>バス停さがしマップ</h1> |
| 133 | +<div id="mapid"></div> |
| 134 | +<button id=showhere>表示位置で再取得</button> <button id=gohere>現在位置へ移動</button><br> |
| 135 | + |
| 136 | +<img id=qrcode><script>addEventListener("load", () => qrcode.src = "https://chart.apis.google.com/chart?chs=140x140&cht=qr&chl=" + encodeURIComponent(document.location))</script><br> |
| 137 | + |
| 138 | +APP: CC BY <a href=https://fukuno.jig.jp/>バス停さがしマップ - 一日一創</a><br> |
| 139 | +LIB: CC BY <a href=https://fukuno.jig.jp/2393>簡単地図アプリ egmapjs</a><br> |
| 140 | +ICON: <a href=https://www.irasutoya.com/2013/10/blog-post_5408.html>バス停のイラスト | かわいいフリー素材集 いらすとや</a><br> |
| 141 | +DATA: CC BY <a href=https://sparql.odp.jig.jp/>odp - SPARQL</a><br> |
| 142 | + |
| 143 | +</body></html> |
0 commit comments