feat: add Map with Layer Group as src/components/map-lgroup.js
This commit is contained in:
parent
c0a9a5b363
commit
feb536cf8c
|
@ -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>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -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: '© <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
|
|
@ -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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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 />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue