init
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# Local Netlify folder
|
||||
.netlify
|
||||
|
||||
node_modules/
|
||||
dist/
|
||||
26
index.html
Normal file
26
index.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<div id="info">
|
||||
<div class="info-box">
|
||||
<p class="title">Layer ID</p>
|
||||
<div id="layer">0</div>
|
||||
</div>
|
||||
<div class="info-box">
|
||||
<p class="title">LatLng</p>
|
||||
<div id="lnglat">00.00 00.00</div>
|
||||
</div>
|
||||
<div class="info-box">
|
||||
<p class="title">Selected</p>
|
||||
<div id="selected">
|
||||
<div>None</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="map"></div>
|
||||
-->
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
10
package.json
Normal file
10
package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@fontsource-variable/jetbrains-mono": "^5.2.8",
|
||||
"@maptiler/leaflet-maptilersdk": "^4.1.1",
|
||||
"@types/jquery": "^3.5.33",
|
||||
"jquery": "^4.0.0",
|
||||
"netlify-cli": "^23.13.5",
|
||||
"vite": "^7.3.1"
|
||||
}
|
||||
}
|
||||
40
src/layers.ts
Normal file
40
src/layers.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { FillLayerSpecification, LineLayerSpecification } from "@maptiler/sdk";
|
||||
|
||||
export const LAYERS = {
|
||||
BUILDING_HIGHLIGHT: {
|
||||
id: "building-highlight",
|
||||
type: "fill",
|
||||
source: "buildings",
|
||||
"source-layer": "building",
|
||||
paint: {
|
||||
"fill-color": "#4fba45",
|
||||
"fill-opacity": 1,
|
||||
},
|
||||
filter: ["==", ["id"], ""],
|
||||
} as FillLayerSpecification,
|
||||
|
||||
BUILDING_SELECT: {
|
||||
id: "building-select",
|
||||
type: "fill",
|
||||
source: "buildings",
|
||||
"source-layer": "building",
|
||||
paint: {
|
||||
"fill-color": "#8e289c",
|
||||
"fill-opacity": 1,
|
||||
},
|
||||
filter: ["==", ["id"], ""],
|
||||
} as FillLayerSpecification,
|
||||
|
||||
ROAD_HIGHLIGHT: {
|
||||
id: "road-highlight",
|
||||
type: "line",
|
||||
paint: {
|
||||
"line-color": "#FF0000",
|
||||
"line-width": 4,
|
||||
"line-opacity": 1,
|
||||
},
|
||||
source: "maptiler_planet_v4",
|
||||
"source-layer": "road",
|
||||
filter: ["==", ["id"], ""],
|
||||
} as LineLayerSpecification,
|
||||
};
|
||||
47
src/main.css
Normal file
47
src/main.css
Normal file
@@ -0,0 +1,47 @@
|
||||
body,
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "monospaced";
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "JetBrains Mono Variable", monospace;
|
||||
}
|
||||
|
||||
#info {
|
||||
z-index: 500;
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
width: 400px;
|
||||
height: calc((100vh) - 30px);
|
||||
border-radius: 8px;
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
margin: 10px;
|
||||
padding: 10px;
|
||||
color: #fff;
|
||||
border: 1px solid green;
|
||||
}
|
||||
|
||||
.info-box .title {
|
||||
margin-top: 5px;
|
||||
font-weight: bold;
|
||||
background: rgba(0, 255, 0, 0.3);
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.info-box ul {
|
||||
margin-bottom: 0;
|
||||
padding-left: 25px;
|
||||
}
|
||||
.info-box li {
|
||||
}
|
||||
|
||||
#map {
|
||||
height: 100vh;
|
||||
}
|
||||
120
src/main.ts
Normal file
120
src/main.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import "@fontsource-variable/jetbrains-mono";
|
||||
import "./main.css";
|
||||
import "@maptiler/sdk/dist/maptiler-sdk.css";
|
||||
import $ from "jquery";
|
||||
import {
|
||||
ExpressionSpecificationDefinition,
|
||||
FilterSpecification,
|
||||
Map,
|
||||
config,
|
||||
} from "@maptiler/sdk";
|
||||
import { LAYERS } from "./layers";
|
||||
|
||||
const MAP_STYLE = "019be805-c88e-7c8b-9850-bc704d72e604";
|
||||
const API_KEY = "8nmgHEIZQiIgqQj3RZNa";
|
||||
const INITIAL_ZOOM = 17;
|
||||
|
||||
config.apiKey = API_KEY;
|
||||
|
||||
const $info = $("#layer");
|
||||
const $lnglat = $("#lnglat");
|
||||
const $selected = $("#selected");
|
||||
|
||||
let selected: Array<string | number | undefined> = [];
|
||||
|
||||
const map = new Map({
|
||||
container: "map",
|
||||
style: MAP_STYLE,
|
||||
});
|
||||
|
||||
// Funzione helper per settare i filtri dei layer.
|
||||
// Per non avere array hardcoded.]
|
||||
const layerFilterEq = (id?: string | number) => {
|
||||
return ["==", ["id"], id ? id : ""] as FilterSpecification;
|
||||
};
|
||||
const layerFilterIn = (ids: Array<string | number | undefined>) => {
|
||||
return ["in", ["id"], ["literal", ids]] as FilterSpecification;
|
||||
};
|
||||
|
||||
map.on("load", () => {
|
||||
// Aggiunge tutti i layer custom a codice per le interazioni
|
||||
map.addLayer(LAYERS.BUILDING_HIGHLIGHT);
|
||||
map.addLayer(LAYERS.BUILDING_SELECT);
|
||||
map.addLayer(LAYERS.ROAD_HIGHLIGHT);
|
||||
|
||||
// console.log(map.getLayer("road_network")?.source);
|
||||
// console.log(map.getLayer("road_network")?.sourceLayer);
|
||||
// console.log(map.getLayer("road_network")?.paint);
|
||||
|
||||
map.on("mousemove", (e) => {
|
||||
// Prende le features solo di questi livelli
|
||||
const features = map.queryRenderedFeatures(e.point, {
|
||||
layers: ["building_matteo", "road_network"],
|
||||
});
|
||||
|
||||
// Aggiorna latitudine e longitudine nel container al mouse over.
|
||||
$lnglat.html(`${e.lngLat.lng} ${e.lngLat.lat}`);
|
||||
|
||||
if (features && features.length > 0) {
|
||||
// Prendo l'ID della top level feature in hover
|
||||
const hovered = features[0];
|
||||
const hoveredId = hovered.id;
|
||||
|
||||
// Aggiorna l'ID della feature nel container delle informazioni.
|
||||
$info.html(hoveredId?.toString() || "");
|
||||
|
||||
if (hoveredId) {
|
||||
map.setFilter(LAYERS.BUILDING_HIGHLIGHT.id, layerFilterEq(hoveredId));
|
||||
map.setFilter(LAYERS.ROAD_HIGHLIGHT.id, layerFilterEq(hoveredId));
|
||||
map.getCanvas().style.cursor = "pointer";
|
||||
}
|
||||
} else {
|
||||
map.getCanvas().style.cursor = "default";
|
||||
map.setFilter(LAYERS.BUILDING_HIGHLIGHT.id, layerFilterEq());
|
||||
map.setFilter(LAYERS.ROAD_HIGHLIGHT.id, layerFilterEq());
|
||||
}
|
||||
});
|
||||
|
||||
map.on("click", (e) => {
|
||||
const features = map.queryRenderedFeatures(e.point, {
|
||||
layers: ["building_matteo"],
|
||||
});
|
||||
|
||||
if (features && features.length > 0) {
|
||||
const clicked = features[0];
|
||||
const clickedId = clicked.id;
|
||||
|
||||
if (!selected.includes(clickedId)) {
|
||||
selected.push(clickedId);
|
||||
} else {
|
||||
selected.splice(selected.indexOf(clickedId), 1);
|
||||
}
|
||||
|
||||
const selectedList = $("<ul>");
|
||||
selected.forEach((id) => {
|
||||
selectedList.append(`<li>${id}</li>`);
|
||||
});
|
||||
$selected.empty().append(selectedList);
|
||||
|
||||
if (selected.length === 0) {
|
||||
$selected.append("<div>None</div>");
|
||||
}
|
||||
|
||||
if (clickedId) {
|
||||
map.setFilter(LAYERS.BUILDING_HIGHLIGHT.id, layerFilterEq());
|
||||
map.setFilter(LAYERS.BUILDING_SELECT.id, layerFilterIn(selected));
|
||||
map.getCanvas().style.cursor = "pointer";
|
||||
}
|
||||
} else {
|
||||
map.getCanvas().style.cursor = "default";
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
navigator.geolocation.getCurrentPosition((position) => {
|
||||
map.setZoom(INITIAL_ZOOM);
|
||||
map.panTo({
|
||||
lat: position.coords.latitude,
|
||||
lng: position.coords.longitude,
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user