feat: add Map with Layer Group as src/components/map-lgroup.js

This commit is contained in:
dancingCycle 2024-01-04 08:53:00 +01:00
parent c0a9a5b363
commit feb536cf8c
4 changed files with 290 additions and 93 deletions

103
src/components/list.js Normal file
View File

@ -0,0 +1,103 @@
import React from 'react'
import { Link} from 'react-router-dom';
export default function List(){
return (
<>
<ul>
<li>
<Link to={'/bike-ride'} >
<button>
Bike and ride (B+R) stations
</button>
</Link>
</li>
<li>
<Link to={'/organic-bakery'} >
<button>
Organic bakeries
</button>
</Link>
</li>
<li>
<Link to={'/organic-only-shop'} >
<button>
Organic only shops
</button>
</Link>
</li>
<li>
<Link to={'/organic-shop'} >
<button>
Organic shops
</button>
</Link>
</li>
<li>
<Link to={'/park-ride'} >
<button>
Park and ride (P+R) stations
</button>
</Link>
</li>
<li>
<Link to={'/public-bookcase'} >
<button>
Public bookcases
</button>
</Link>
</li>
<li>
<Link to={'/second-hand'} >
<button>
Second hand shops
</button>
</Link>
</li>
<li>
<Link to={'/taxi'} >
<button>
Taxi stations
</button>
</Link>
</li>
<li>
<Link to={'/ticket-machine'} >
<button>
Ticket machines
</button>
</Link>
</li>
<li>
<Link to={'/ticket-office'} >
<button>
Ticket offices
</button>
</Link>
</li>
<li>
<Link to={'/vegan'} >
<button>
Vegan only restaurants
</button>
</Link>
</li>
<li>
<Link to={'/vegetarian'} >
<button>
Vegetarian only restaurants
</button>
</Link>
</li>
<li>
<Link to={'/zero-waste'} >
<button>
Zero waste shops
</button>
</Link>
</li>
</ul>
</>
);
};

128
src/components/map-array.js Normal file
View File

@ -0,0 +1,128 @@
import React, { useEffect, useRef, useState } from 'react'
import L from 'leaflet'
import "leaflet/dist/leaflet.css";
import icon from "leaflet/dist/images/marker-icon.png";
import iconShadow from "leaflet/dist/images/marker-shadow.png";
let DefaultIcon = L.icon({
iconUrl: icon,
shadowUrl: iconShadow,
});
export default function MapArray( { array } ) {
console.log('map-array:MapArray: array.lngth: ' + array.length);
/*center map in the middle of RVB*/
const mapCenter = [52.16594, 10.52673];
const mapRef = useRef();
useEffect(() => {
//base layer
const baseLayerOsm = L.tileLayer(
"http://{s}.tile.osm.org/{z}/{x}/{y}.png",
{
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
maxZoom: 18,
scrollWheelZoom: false,
}
);
//marker array
const rryMrkr = array.map( function( value, key ) {
//console.log('map-array:MapArray:map() value: ' +JSON.stringify(value));
//get entity properties
const id = value.id;
const type = value.type;
const name = value.tags.name;
let lat, lon = null;
if ( type === "node"){
lat = value.lat;
lon = value.lon;
} else if ( type === "way" || type === "relation" ) {
lat = value.center.lat;
lon = value.center.lon;
} else {
console.error("map-entities: OSM type (" + type + ") NOT known");
}
//verify entity properties
if(lat !== undefined && lat !== null && lon !== undefined && lon !== null ){
//TODO
/*
var marker = L.marker([lat, lon]).addTo(map);
const popupText ='name: <b>' + name + '</b><br />id: ' + id + '<br />type: ' + type;
marker.bindPopup(popupText);
*/
L.Marker.prototype.options.icon = DefaultIcon;
const marker = L.marker(
[lat, lon],
{alt: 'marker name: ' + name}
);
const popupText ='name: <b>' + name + '</b><br />lat: ' + lat + '<br />lon: ' + lon;
//console.log('popupText: ' + popupText);
marker.bindPopup(popupText);
return marker
} else {
console.error('map-entities: lat or lon undefined or null');
}
});
console.log('rryMrkr: ' + rryMrkr.length);
//layer group
const overlayMrkr = L.layerGroup(rryMrkr);
//map
const map = L.map(
mapRef.current,
{attributionControl: true,
layers : [baseLayerOsm, overlayMrkr]}
).setView(
mapCenter,
3
);
//layout control
var baseMaps = {
"OpenStreetMap": baseLayerOsm
};
var overlayMaps = {
'Markers' : overlayMrkr
};
const layerControl = L.control.layers(baseMaps, overlayMaps).addTo(map);
// unmount map function
//You should unmount the function in react.js to remove the existing map.
return () => map.remove();
}, []);
if ( array !== undefined && array !== null && array.length > 0 ) {
return (
<>
<p>MapArray</p>
<div
style={{padding: 0, margin: 0, width: "75%", height: "23vh",}}
ref={el => mapRef.current = el}>
</div>
</>
);
}else{
//TODO Why does mapRef have to be present?
return (
<>
<p>MapArray loading...</p>
<div
ref={el => mapRef.current = el}>
</div>
</>
);
}
};
//https://github.com/azaharyan/react-leaflet-example

View File

@ -0,0 +1,54 @@
import React, { useEffect, useState } from 'react';
import { get } from '../utils/request';
//TODO adjust config usage
import config from '../utils/config';
import Map from '../components/map-array';
export default function MapLGroup(){
const [array, setArray] = useState([]);
/*fetch array in a JavaScript function*/
const fetch = async () => {
try {
/*TODO handle errors: https://www.valentinog.com/blog/await-react/*/
const address = config.ADDRESS + 'nwr[shop=second_hand](area)->.shops;nwr[second_hand=yes](area)->.secondHands;(.shops;.secondHands;);' + config.OUT;
console.log("Fetch:fetch(): address: " + address);
const res = await get(address);
console.log("Fetch:fetch(): res.length: "+res.elements.length);
setArray((array) => res.elements);
} catch (err) {
console.error('err.message: ' + err.message);
setArray((array) => []);
}
};
useEffect(() => {
/*effect goes here*/
fetch();
/*use an empty dependency array to ensure the hook is running only once*/
/*TODO study dependency array: https://reactjs.org/docs/hooks-effect.html*/
}, []);
if ( array !== undefined && array !== null && array.length > 0 ) {
/*return a React element*/
return (
<>
<p>MapLGroup</p>
<Map
array={array}
/>
</>
);
}else{
return (
<>
<p>MapLGroup</p>
<p>Loading...</p>
</>
);
}
}

View File

@ -1,103 +1,15 @@
import React from 'react'
import { Link} from 'react-router-dom';
import List from '../components/list';
import MapLGroup from '../components/map-lgroup';
export default function Home(){
return (
<>
<ul>
<li>
<Link to={'/bike-ride'} >
<button>
Bike and ride (B+R) stations
</button>
</Link>
</li>
<li>
<Link to={'/organic-bakery'} >
<button>
Organic bakeries
</button>
</Link>
</li>
<li>
<Link to={'/organic-only-shop'} >
<button>
Organic only shops
</button>
</Link>
</li>
<li>
<Link to={'/organic-shop'} >
<button>
Organic shops
</button>
</Link>
</li>
<li>
<Link to={'/park-ride'} >
<button>
Park and ride (P+R) stations
</button>
</Link>
</li>
<li>
<Link to={'/public-bookcase'} >
<button>
Public bookcases
</button>
</Link>
</li>
<li>
<Link to={'/second-hand'} >
<button>
Second hand shops
</button>
</Link>
</li>
<li>
<Link to={'/taxi'} >
<button>
Taxi stations
</button>
</Link>
</li>
<li>
<Link to={'/ticket-machine'} >
<button>
Ticket machines
</button>
</Link>
</li>
<li>
<Link to={'/ticket-office'} >
<button>
Ticket offices
</button>
</Link>
</li>
<li>
<Link to={'/vegan'} >
<button>
Vegan only restaurants
</button>
</Link>
</li>
<li>
<Link to={'/vegetarian'} >
<button>
Vegetarian only restaurants
</button>
</Link>
</li>
<li>
<Link to={'/zero-waste'} >
<button>
Zero waste shops
</button>
</Link>
</li>
</ul>
<List />
<MapLGroup />
</>
);
}