Leaflet demo
For update marker position
by ken3desu
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css">
<h3>多角形の内側にのみマーカーを置けます</h3>
<div id="map"></div>
CSS
#map {
height: 500px;
width: 80%;
}
JavaScript
// 地図
const osmUrl = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png';
const osmAttrib = '© <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors';
const osm = L.tileLayer(osmUrl, {
maxZoom: 18,
attribution: osmAttrib,
});
// 初期化
const map = L.map('map').setView([34.6982856, 137.6999814], 12).addLayer(osm);
// 2点から四角になる様に4点の座標配列を生成
const makeBox = (x1, y1, x2, y2) => {
return [
[x1, y1],
[x1, y2],
[x2, y2],
[x2, y1],
];
};
// 領域セット
const polygonInnerLatLngList = [
[34.68, 137.73],
[34.7, 137.72],
[34.73, 137.71],
[34.73, 137.70],
[34.72, 137.69],
[34.7, 137.69],
[34.68, 137.64],
[34.65, 137.65],
[34.64, 137.65],
[34.69, 137.67],
[34.68, 137.68],
];
const polygonLatLngList = [makeBox(-90, -180, 90, 180), polygonInnerLatLngList];
L.polygon(polygonLatLngList, {
color: 'black',
opacity: 0,
fillOpacity: 0.6,
}).addTo(map);
// マーカーセット
let marker;
const onMapClick = (e) => {
if (!isInsideByCrossingNumberAlgorithm([e.latlng.lat, e.latlng.lng], polygonInnerLatLngList)) {
return;
}
if (marker) {
marker.remove(); // 既存のマーカーがあれば入れ替え
}
marker = L.marker(e.latlng).addTo(map).bindPopup(e.latlng.toString()).openPopup();
};
map.on('click', onMapClick);
/**
* 点が多角形の内にあるならば true
* @param {[Number, Number]} point
* @param {[Number, Number][]} polygon
* @return {boolean}
*/
function isInsideByCrossingNumberAlgorithm(point, polygon) {
const x = point[0];
const y = point[1];
let crossCount = 0;
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
// 多角形を成す辺を全て調査する
// 現在の index の多角形の点X, Y
const polCX = polygon[i][0];
const polCY = polygon[i][1];
// 次の index の多角形の点X, Y
const polNX = polygon[j][0];
const polNY = polygon[j][1];
if (polCY > y === polNY > y) {
// 点が辺の完全に上 or 完全に下ならば. ノーカウントでループ続行
continue;
}
// 辺が点pと同じ高さになる位置を特定し、その時のxの値と点pのxの値を比較する
// 同じ高さになる時の辺の割合 = (点Y - 始点Y座標)) / 辺のY軸長さ
const vt = (y -...