Add OSM service, map click handler
This commit is contained in:
@@ -1,20 +1,25 @@
|
|||||||
|
import Component from '@glimmer/component';
|
||||||
|
import { service } from '@ember/service';
|
||||||
import { modifier } from 'ember-modifier';
|
import { modifier } from 'ember-modifier';
|
||||||
import 'ol/ol.css';
|
import 'ol/ol.css';
|
||||||
import Map from 'ol/Map.js';
|
import Map from 'ol/Map.js';
|
||||||
import { defaults as defaultControls } from 'ol/control.js';
|
import { defaults as defaultControls } from 'ol/control.js';
|
||||||
import View from 'ol/View.js';
|
import View from 'ol/View.js';
|
||||||
import { fromLonLat } from 'ol/proj.js';
|
import { fromLonLat, toLonLat } from 'ol/proj.js';
|
||||||
import LayerGroup from 'ol/layer/Group.js';
|
import LayerGroup from 'ol/layer/Group.js';
|
||||||
import { apply } from 'ol-mapbox-style';
|
import { apply } from 'ol-mapbox-style';
|
||||||
|
|
||||||
let mapInstance;
|
export default class MapComponent extends Component {
|
||||||
|
@service osm;
|
||||||
|
|
||||||
const setupMap = modifier((element) => {
|
mapInstance;
|
||||||
if (mapInstance) return;
|
|
||||||
|
setupMap = modifier((element) => {
|
||||||
|
if (this.mapInstance) return;
|
||||||
|
|
||||||
const openfreemap = new LayerGroup();
|
const openfreemap = new LayerGroup();
|
||||||
|
|
||||||
mapInstance = new Map({
|
this.mapInstance = new Map({
|
||||||
target: element,
|
target: element,
|
||||||
layers: [openfreemap],
|
layers: [openfreemap],
|
||||||
controls: defaultControls({ zoom: false }),
|
controls: defaultControls({ zoom: false }),
|
||||||
@@ -26,11 +31,28 @@ const setupMap = modifier((element) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
apply(openfreemap, 'https://tiles.openfreemap.org/styles/positron');
|
apply(openfreemap, 'https://tiles.openfreemap.org/styles/positron');
|
||||||
});
|
|
||||||
|
|
||||||
<template>
|
this.mapInstance.on('singleclick', this.handleMapClick);
|
||||||
|
});
|
||||||
|
|
||||||
|
handleMapClick = async (event) => {
|
||||||
|
const coords = toLonLat(event.coordinate);
|
||||||
|
const [lon, lat] = coords;
|
||||||
|
|
||||||
|
console.log(`Clicked at: ${lat}, ${lon}`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const pois = await this.osm.getNearbyPois(lat, lon);
|
||||||
|
console.log('Nearby POIs:', pois);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch POIs:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
<template>
|
||||||
<div
|
<div
|
||||||
{{setupMap}}
|
{{this.setupMap}}
|
||||||
style="position: absolute; inset: 0;"
|
style="position: absolute; inset: 0;"
|
||||||
></div>
|
></div>
|
||||||
</template>
|
</template>
|
||||||
|
}
|
||||||
|
|||||||
25
app/services/osm.js
Normal file
25
app/services/osm.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import Service from '@ember/service';
|
||||||
|
|
||||||
|
export default class OsmService extends Service {
|
||||||
|
async getNearbyPois(lat, lon, radius = 200) {
|
||||||
|
const query = `
|
||||||
|
[out:json][timeout:25];
|
||||||
|
(
|
||||||
|
nwr["amenity"](around:${radius},${lat},${lon});
|
||||||
|
nwr["shop"](around:${radius},${lat},${lon});
|
||||||
|
nwr["tourism"](around:${radius},${lat},${lon});
|
||||||
|
nwr["leisure"](around:${radius},${lat},${lon});
|
||||||
|
nwr["historic"](around:${radius},${lat},${lon});
|
||||||
|
);
|
||||||
|
out center;
|
||||||
|
`.trim();
|
||||||
|
|
||||||
|
const url = `https://overpass-api.de/api/interpreter?data=${encodeURIComponent(
|
||||||
|
query
|
||||||
|
)}`;
|
||||||
|
const res = await fetch(url);
|
||||||
|
if (!res.ok) throw new Error('Overpass request failed');
|
||||||
|
const data = await res.json();
|
||||||
|
return data.elements;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user