test(leaflet-js-intg): add test components

This commit is contained in:
dancingCycle 2023-09-20 13:34:51 +02:00
parent b269097efd
commit bf5c23cb46
13 changed files with 667 additions and 0 deletions

View File

@ -8,6 +8,8 @@
# Links
* [Leaflet.js Integration](https://betterprogramming.pub/a-quick-guide-to-integrating-leaflet-js-and-react-ed89ff92790e)
* [Making Sense of React Hocks](https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889)
* [React setup with webpack for beginners](https://dev.to/deepanjangh/react-setup-with-webpack-for-beginners-2a8k)
* [Production](https://webpack.js.org/guides/production/)
* [Setup Development and Production Environment for React App](https://medium.com/freestoneinfotech/setup-development-and-production-environment-for-react-app-397c4cc9e382)

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,64 @@
import React, { useEffect } 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 MapNxt() {
useEffect(() => {
var container = L.DomUtil.get("map");
//https://stackoverflow.com/a/50034912/15078958
//Before initializing map check if the map is already initiated or not
if (container != null) {
container._leaflet_id = null;
}
//TODO Is this an alternative?
//https://stackoverflow.com/a/53836894/15078958
/**map.invalidateSize();*/
var map = L.map("map").setView([51.505, -0.09], 13);
L.tileLayer(
"https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}",
{
attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: "mapbox/streets-v11",
tileSize: 512,
zoomOffset: -1,
accessToken: "pk.eyJ1IjoidGFyLWhlbCIsImEiOiJjbDJnYWRieGMwMTlrM2luenIzMzZwbGJ2In0.RQRMAJqClc4qoNwROT8Umg",
scrollWheelZoom: false,
}).addTo(map);
//TODO: Why is 'scrollWheelZoom: false,' above not working?
//TODO: Why the following line instead?
map.scrollWheelZoom.disable()
L.Marker.prototype.options.icon = DefaultIcon;
var marker = L.marker([51.5, -0.09]).addTo(map);
marker.bindPopup("<b>Hello world!</b><br>I am a popup.").openPopup();
}, []);
return (
<div
id="map"
style={{ height: "42vh" }}>
</div>
);
};
//https://stackoverflow.com/a/72016670/15078958
/**
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css" integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ==" crossorigin=""/>
*/
/**
<script src="https://unpkg.com/leaflet@1.8.0/dist/leaflet.js" integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ==" crossorigin=""></script>
*/

View File

@ -0,0 +1,58 @@
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 Map() {
const mapContainer = useRef();
const [map, setMap] = useState({});
useEffect(()=>{
const map = L.map(
mapContainer.current,
{attributionControl: false}
).setView([51.505, -0.09], 13);
map.zoomControl.setPosition("bottomright");
L.tileLayer(
"https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}",
{
attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1,
accessToken: "pk.eyJ1IjoidGFyLWhlbCIsImEiOiJjbDJnYWRieGMwMTlrM2luenIzMzZwbGJ2In0.RQRMAJqClc4qoNwROT8Umg",
scrollWheelZoom: false,
}).addTo(map);
//TODO: Why is 'scrollWheelZoom: false,' above not working?
//TODO: Why the following line instead?
map.scrollWheelZoom.disable()
L.Marker.prototype.options.icon = DefaultIcon;
var marker = L.marker([51.5, -0.09]).addTo(map);
marker.bindPopup("<b>Hello world!</b><br>I am a popup.").openPopup();
// unmount map function
//You should unmount the function in react.js to remove the existing map.
return () => map.remove();
}, []);
return (
<div
style={{padding: 0, margin: 0, width: "50%", height: "23vh",}}
ref={el => mapContainer.current = el}>
</div>
);
};
//https://stackoverflow.com/a/66920207/15078958

View File

@ -0,0 +1,111 @@
import React, { useEffect, useRef } from 'react';
import L from "leaflet";
import "leaflet/dist/leaflet.css";
export default function Map() {
const mapContainerRef = useRef(null);
useEffect( async () => {
//const res =await Axios.get(BASE_PATH + 'fetchProperty')
//TODO Is this the map unload part?
const container = L.DomUtil.get(mapContainerRef.current);
if(container != null) {
container._leaflet_id = null;
}
if(container) {
const mapView = L.map( mapContainerRef.current, {
zoom: 13,
center: [19.059984, 72.889999]
// maxZoom: 13
// minZoom: 15
});
// const canvas = mapView.getCanvasContainer();
mapView.zoomControl.setPosition("bottomright");
mapView.attributionControl.addAttribution(
"<a href='https://mascots.pro'>Mascots. pro</a>"
);
L.tileLayer(
"https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}",
{
attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1,
accessToken: "pk.eyJ1IjoidGFyLWhlbCIsImEiOiJjbDJnYWRieGMwMTlrM2luenIzMzZwbGJ2In0.RQRMAJqClc4qoNwROT8Umg",
scrollWheelZoom: false,
}).addTo(map);
const mask = L.tileLayer.mask(
"https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}",
{
attribution: '<a href="https://mascots.pro">Mascots pro</a>',
maskSize: 300
// maxZoom: 18,
// maxNativeZoom: 16
// tms: true
}
).addTo(mapView);
mapView.on("mousemove", function (e) {
mask.setCenter(e.containerPoint);
});
/**
res.data.map((marker) => {
const innerHtmlContent = `<div id='popup-container' class='popup-container'> <h3> Property Details</h3>
<div class='popup-label'>Building Name :<p>${marker.Building}</p></div>
<div class='popup-address-label'> Address : <p>${marker.Landmark}, ${marker.Location}</p></div>
<div class='popup-rent-label'>Monthly Rent : <p> ${marker.Price}</p></div>
</div>`;
const divElement = document.createElement("div");
const assignBtn = document.createElement("div");
assignBtn.className = "map-link";
assignBtn.innerHTML = `<button class="view-btn">View Property</button>`;
divElement.innerHTML = innerHtmlContent;
divElement.appendChild(assignBtn);
assignBtn.addEventListener("click", (e) => {
console.log("dsvsdvb");
});
var iconOptions = {
iconUrl: "/images/location_pin2.svg",
iconSize: [25, 25]
};
var customIcon = L.icon(iconOptions);
// create popup contents
var customPopup = divElement;
// specify popup options
var customOptions = {
maxWidth: "500",
className: "custom"
};
const markerOptions = {
// title: "MyLocation",
// draggable: true
clickable: true,
icon: customIcon
};
const mark = L.marker([marker.Latitude,marker.Longitude], markerOptions);
mark.bindPopup(customPopup, customOptions);
mark.addTo(mapView);
// return mapView.off();
});
*/
return () => mapView.remove();
}
}, [])
return (
<div className="map-box">
<div className="map-container" ref={mapContainerRef}></div>
</div>
);
};
//https://stackoverflow.com/a/67486824/15078958

View File

@ -0,0 +1,39 @@
import React, { useEffect, useRef, useState } from 'react'
import L from 'leaflet'
import "leaflet/dist/leaflet.css";
export default function MapSimple() {
const mapRef = useRef();
useEffect(() => {
const map = L.map(
mapRef.current,
{attributionControl: true}
).setView(
[42.69751, 23.32415],
16
);
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,
}).addTo(map);
// unmount map function
//You should unmount the function in react.js to remove the existing map.
return () => map.remove();
}, []);
return (
<div
style={{padding: 0, margin: 0, width: "75%", height: "23vh",}}
ref={el => mapRef.current = el}>
</div>
);
};
//https://github.com/azaharyan/react-leaflet-example

View File

@ -0,0 +1,41 @@
import React, { useEffect, useRef, useState } from 'react'
import L, { geoJson } from 'leaflet'
function MapWithMarker() {
const [markerPosition, setMarkerPosition] = useState({ lat:42.6944, lng:23.3328 })
const mapRef = useRef(null)
useEffect(() => {
mapRef.current = L.map('map', {
center: markerPosition,
zoom: 18,
layers: [
L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", {
attribution:
'&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
})
]
})
}, [markerPosition])
const markerRef = useRef(null)
const customIcon = L.icon({
iconUrl: 'https://unpkg.com/leaflet@1.5.1/dist/images/marker-icon.png',
iconSize: [35,46],
iconAnchor: [17,46]
});
useEffect(() => {
if(markerRef.current)
markerRef.current.setLatLng(markerPosition)
else
markerRef.current = L.marker(markerPosition, {icon:customIcon }).addTo(mapRef.current).bindPopup('Bulgarian National Assembly')
}, [markerPosition, customIcon])
return <div id='map' style={{ width: '80%' }}></div>
}
export default MapWithMarker

File diff suppressed because one or more lines are too long

View File

@ -1,12 +1,27 @@
import React from 'react';
import Hello from '../components/hello';
//TODO Why is this component not working?
//import Map from '../components/map';
import MapSimple from '../components/map-simple';
import MapNext from '../components/map-next';
import MapNxt from '../components/map-nxt';
//TODO Why is this component not working?
//import MapNxt2 from '../components/map-nxt2';
import '../style.css';
const Home = () => {
return (
<>
<h2>Home</h2>
<h3>(React.js Lambda Function Component)</h3>
<Hello msg="Hello World!" />
{/**<Map />*/}
<MapNext />
<br />
<MapNxt />
<br />
<MapSimple />
</>
);
}

View File

@ -26,6 +26,14 @@ module.exports = {
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
],
},
]
},
resolve: {

View File

@ -9,6 +9,7 @@
"version": "0.1.0",
"license": "GPL-3.0-or-later",
"dependencies": {
"leaflet": "1.9.4",
"prop-types": "15.8.1",
"react": "18.2.0",
"react-dom": "18.2.0"
@ -19,6 +20,7 @@
"@babel/preset-react": "7.18.6",
"babel-loader": "9.1.2",
"css-loader": "6.7.3",
"file-loader": "^6.2.0",
"html-webpack-plugin": "5.5.1",
"style-loader": "3.3.2",
"webpack": "5.80.0",
@ -2433,6 +2435,15 @@
"integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
"dev": true
},
"node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@ -3134,6 +3145,15 @@
"integrity": "sha512-e2aeCAixCj9M7nJxdB/wDjO6mbYX+lJJxSJCXDzlr5YPGYVofuJwGN9nKg2o6wWInjX6XmxRinn3AeJMK81ltw==",
"dev": true
},
"node_modules/emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@ -3422,6 +3442,44 @@
"node": ">=0.8.0"
}
},
"node_modules/file-loader": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz",
"integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==",
"dev": true,
"dependencies": {
"loader-utils": "^2.0.0",
"schema-utils": "^3.0.0"
},
"engines": {
"node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"webpack": "^4.0.0 || ^5.0.0"
}
},
"node_modules/file-loader/node_modules/schema-utils": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.8",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
},
"engines": {
"node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
}
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@ -4196,6 +4254,11 @@
"shell-quote": "^1.7.3"
}
},
"node_modules/leaflet": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="
},
"node_modules/loader-runner": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
@ -4205,6 +4268,20 @@
"node": ">=6.11.5"
}
},
"node_modules/loader-utils": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true,
"dependencies": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
},
"engines": {
"node": ">=8.9.0"
}
},
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@ -8050,6 +8127,12 @@
"integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
"dev": true
},
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true
},
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@ -8572,6 +8655,12 @@
"integrity": "sha512-e2aeCAixCj9M7nJxdB/wDjO6mbYX+lJJxSJCXDzlr5YPGYVofuJwGN9nKg2o6wWInjX6XmxRinn3AeJMK81ltw==",
"dev": true
},
"emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@ -8793,6 +8882,29 @@
"websocket-driver": ">=0.5.1"
}
},
"file-loader": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz",
"integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==",
"dev": true,
"requires": {
"loader-utils": "^2.0.0",
"schema-utils": "^3.0.0"
},
"dependencies": {
"schema-utils": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.8",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
}
}
}
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@ -9354,12 +9466,28 @@
"shell-quote": "^1.7.3"
}
},
"leaflet": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="
},
"loader-runner": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
"integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
"dev": true
},
"loader-utils": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",

View File

@ -23,6 +23,7 @@
"@babel/preset-react": "7.18.6",
"babel-loader": "9.1.2",
"css-loader": "6.7.3",
"file-loader": "^6.2.0",
"html-webpack-plugin": "5.5.1",
"style-loader": "3.3.2",
"webpack": "5.80.0",
@ -31,6 +32,7 @@
"webpack-merge": "5.8.0"
},
"dependencies": {
"leaflet": "1.9.4",
"prop-types": "15.8.1",
"react": "18.2.0",
"react-dom": "18.2.0"

View File

@ -3,6 +3,9 @@
<head>
<meta charset="UTF-8">
<title>React Example</title>
<link rel="stylesheet" href="https://npmcdn.com/leaflet@1.0.0-rc.2/dist/leaflet.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css" integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ==" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.8.0/dist/leaflet.js" integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ==" crossorigin=""></script>
</head>
<body>
<div id="root"></div>