I have my component MAP and I use leaflet (not react-leaflet).
I want to set a marker.
This is the code of my component.
import React from 'react';
import L from 'leaflet';
import '../../../../node_modules/leaflet/dist/leaflet.css';
import './map.scss';
export default class Map extends React.Component {
componentDidMount() {
this.map = L.map('map', {
center: [48.8762, 2.357909999999947],
zoom: 14,
zoomControl: true,
layers: [
L.tileLayer('https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png',{
detectRetina: true,
maxZoom: 20,
maxNativeZoom: 17,
}),
]
});
L.marker([48.8762, 2.357909999999947],
{
draggable: true, // Make the icon dragable
title: 'Hover Text', // Add a title
opacity: 0.5} // Adjust the opacity
)
.addTo(this.map)
.bindPopup("<b>Paris</b><br>Gare de l'Est")
.openPopup();
L.circle([48.8762, 2.357909999999947], {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5,
radius: 500
}).addTo(this.map);
};
render() {
return <div className="map" id="map" />
}
}
I add the marker us described in the documentation, but the result in the map is not the default icon, it is only a square with a thin border.
I checked the css-File from leaflet. The icon is in the images folder, but it is not in the map available.
This icon (marker) I am looking for
This is what I get
Can anybody help or see what is wrong with my code?
This is a well known css bundle issue with webpack. Define markerIcon as
const markerIcon = L.icon({
iconSize: [25, 41],
iconAnchor: [10, 41],
popupAnchor: [2, -40],
// specify the path here
iconUrl: "https://unpkg.com/leaflet#1.5.1/dist/images/marker-icon.png",
shadowUrl: "https://unpkg.com/leaflet#1.5.1/dist/images/marker-shadow.png"
});
and assign it to the icon property of L.marker like this:
L.marker(
[48.8762, 2.357909999999947],
{
draggable: true, // Make the icon dragable
title: "Hover Text", // Add a title
opacity: 0.5,
icon: markerIcon // here assign the markerIcon var
} // Adjust the opacity
)
.addTo(this.map)
.bindPopup("<b>Paris</b><br>Gare de l'Est")
.openPopup();
Demo
As per your question, I can interpret that you are not able to import the CSS properly.
You can import the css for the leaflet module by writing
import 'leaflet/dist/leaflet.css';
For detailed explanation you can read
Do I have to import leaflet's CSS file?
Example of how to load static CSS files from node_modules using webpack?
Related
I'm not able to get Leaflet to load the tiles of my map past the first row in this Vue 3 component. I've tried declaring the vertical size of its div several ways, as well as calling map.invalidateSize() when the component is mounted, but without any success.
<script setup lang="ts">
import { onMounted } from "vue";
import * as L from "leaflet";
import "leaflet/dist/leaflet.css";
onMounted(() => {
var map = L.map("map", { attributionControl: false }).setView([0, 0], 0);
L.tileLayer("http://127.0.0.1:7800/{z}/{x}/{y}.jpeg", {
maxZoom: 0,
noWrap: true,
}).addTo(map);
});
</script>
<template>
<h1>Map Detail</h1>
<div id="map"></div>
</template>
<style>
#map {
width: 100%;
height: 512px;
}
</style>
Not sure if either or both will work but you can try
Setting the dimensions of #map like this
#map {
width: 100%;
height: calc(512px / 100%); // Set the height relative to the width of the parent element
}
Setting the maxZoom to a higher value like 18 in tile layer, and set the zoom in map to 1
import { onMounted } from "vue";
import * as L from "leaflet";
import "leaflet/dist/leaflet.css";
onMounted(() => {
var map = L.map("map", {
attributionControl: false,
zoom: 1, // Set the initial zoom level to 1
}).setView([0, 0], 0);
L.tileLayer("http://127.0.0.1:7800/{z}/{x}/{y}.jpeg", {
maxZoom: 18,
noWrap: true,
}).addTo(map);
});
I have a Svelte application with a Map component as below. I'd like to pass in props for centreCoords and Zoom and then fly to them when they change outside the component.
However, I can't work out how to get the map object outside the onMount function.
<script>
import { onMount, onDestroy } from 'svelte';
import mapboxgl from 'mapbox-gl';
const token = 'xxx';
let mapElement;
let map;
export let zoom;
export let centreCoords = [];
// This but doesn't work
map.flyTo({
center: centreCoords,
zoom: zoom,
essential: true // this animation is considered essential with respect to prefers-reduced-motion
});
onMount(() => {
mapboxgl.accessToken = token;
map = new mapboxgl.Map({
container: mapElement,
zoom: zoom,
center: centreCoords,
// Choose from Mapbox's core styles, or make your own style with Mapbox Studio
style: 'mapbox://styles/mapbox/light-v10',
antialias: true // create the gl context with MSAA antialiasing, so custom layers are antialiased
});
});
onDestroy(async () => {
if (map) {
map.remove();
}
});
</script>
<main>
<div bind:this={mapElement} />
</main>
<style>
#import 'mapbox-gl/dist/mapbox-gl.css';
main div {
height: 800px;
}
</style>
Should be possible to just use a reactive statement with an if:
$: if (map) map.flyTo(...)
Maybe someone faced a similar problem. When such a code is executed, the image added to the map is displayed not in the coordinates specified in the corners, but on the entire screen.
import "leaflet-toolbar";
import "leaflet-distortableimage";
import "leaflet-distortableimage/dist/vendor.js";
import "./styles.css";
import "leaflet/dist/leaflet.css";
import "leaflet-toolbar/dist/leaflet.toolbar.css";
import "leaflet-distortableimage/dist/leaflet.distortableimage.css";
import PlanImage from "../../../../Downloads/Stage_Plans_155_8bd04203-148f-4332-b82a-297afd3be66f.jpeg";
const map = L.map("app", {
center: [50.0, 10.0],
zoom: 3,
});
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: '© OpenStreetMap contributors',
}).addTo(map);
map.whenReady(() => {
let img = new L.distortableImageOverlay(PlanImage, {
corners: [L.latLng(51.52, -0.14), L.latLng(51.52, -0.1), L.latLng(51.5, -0.14), L.latLng(51.5, -0.1)],
mode: "lock",
}).addTo(map);
// () => map.removeLayer(imageLayer);
});
An error appears
DistortableImageOverlay.js:317 Uncaught TypeError: Cannot read properties of undefined (reading 'slice')
at NewClass.getAngle (DistortableImageOverlay.js:317:18)
at NewClass._reset (DistortableImageOverlay.js:453:30)
at NewClass.setBounds (ImageOverlay.js:144:9)
at NewClass.setCorners (DistortableImageOverlay.js:247:10)
at NewClass.<anonymous> (index.js:40:7)
at NewClass.whenReady (Map.js:1465:13)
at Object.parcelRequire.src/index.js.leaflet (index.js:20:5)
at newRequire (src.a2b27638.js:47:24)
at src.a2b27638.js:81:7
at src.a2b27638.js:120:3
And after moving the mouse wheel, the image is displayed at the desired coordinates.
How can we embeded leaflet Map into Preact component. I am creating a Map widget using webpack. In the below I show you the code I implemented.
import registerCustomElement from 'preact-custom-element';
import { h , Component } from 'preact';
import {map as createMap, tileLayer} from '../../node_modules/leaflet/dist/leaflet-src.esm.js';
class mapView extends Component {
componentDidMount() {
let map2 = L.map('mapid').setView([51.505, -0.09], 13);
map.addLayer(L.tileLayer(urlTemplate, {minZoom: 4}));
const mapEl = this.shadowRoot.querySelector('#mapid');
let map = createMap(mapEl).setView([51.505, -0.09], 13);
}
render (){
return (
<div>
<div id="mapid" style="height: 100%"></div>
</div>
)
}
}
registerCustomElement(mapView, "map-view");
Can we use React Leaflet in Preact? Is it possible to use? or is there any library or package to create Map in Preact?
This is easy. I found a Stack Overflow question related to Leaflet usage in LitElement.
My answer is similar as this, but need to do some changes, because I am creating a web component (widget).
import registerCustomElement from 'preact-custom-element';
import { Component } from 'preact';
import {map as createMap, tileLayer , icon, marker} from '../../node_modules/leaflet/dist/leaflet-src.esm.js';
import markerIcon from '../../node_modules/leaflet/dist/images/marker-icon.png';
import '../../node_modules/leaflet/dist/leaflet.css';
import "../Assets/CSS/file.css";
import 'bootstrap/dist/css/bootstrap.css';
class mapView extends Component {
componentDidMount() {
var locations = [
["LOCATION_1", 11.8166, 122.0942],
["LOCATION_2", 11.9804, 121.9189],
["LOCATION_3", 10.7202, 122.5621],
["LOCATION_4", 11.3889, 122.6277],
["LOCATION_5", 10.5929, 122.6325]
];
map = createMap('mapid').setView([51.505, -0.09], 13);
let urlll = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?';
map.addLayer(tileLayer(
urlll,
{attribution: 'Map data © OpenStreetMap contributors, Imagery © Mapbox',
maxZoom: 18,
tileSize: 512,
zoomOffset: -1,
})
);
let marketIcon = icon({
iconUrl: markerIcon,
iconRetinaUrl: markerIcon,
iconAnchor: [5, 25],
popupAnchor: [10, -44],
iconSize: [25, 35],
});
for (var i = 0; i < locations.length; i++) {
marker([locations[i][1], locations[i][2]], {
icon: marketIcon,
draggable: true,
}).addTo(map);
}
}
render (){
return (
<div>
<div id="mapid"></div>
</div>
)
}
}
registerCustomElement(mapView, "map-view");
You need to update your webpack.config with the file loader. https://v4.webpack.js.org/loaders/file-loader/
Here is my script file code
<script defer="" src="http://HOST_URL/MapCom.js" type="text/javascript"></script>
<map-view name="map"></map-view>
I have an issue using event with OpenLayers and Angular, I have an function on click on my map which catch me the lonlat from where I have clicked on the map but, when I click on the zoom in and out control the function is also triggered same thing when I drag my view which I don't what to happen. It's the first time i'm using this API, can someone help me ?
my TS file
import { Component, OnInit } from '#angular/core';
import Map from 'ol/Map';
import Tile from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import View from 'ol/View';
import { fromLonLat, transform } from 'ol/proj';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import { Feature } from 'ol';
import Point from 'ol/geom/Point';
import Style from 'ol/style/Style';
import Icon from 'ol/style/Icon'
#Component({
selector: 'app-indicator-acceuil',
templateUrl: './indicator-acceuil.component.html',
styleUrls: ['./indicator-acceuil.component.scss']
})
export class IndicatorAcceuilComponent implements OnInit {
map: any;
markerSource: VectorSource = new VectorSource({});
constructor() { }
ngOnInit(): void {
this.initilizeMap();
}
initilizeMap() {
this.map = new Map({
target: 'map',
layers: [
new Tile({
source: new OSM()
}),
new VectorLayer({
source: this.markerSource,
style: new Style({
image: new Icon({
anchor : [0.5,1],
src: 'assets/pin24x24.png',
scale : 1.5,
imgSize: [24,24],
})
})
})
],
view: new View({
center: fromLonLat([2.213749,46.227638]),
zoom: 6
}),
});
}
getCoord(event: any) {
const coordinate = this.map.getEventCoordinate(event);
let lonlat = transform(coordinate, 'EPSG:3857', 'EPSG:4326');
const lon = lonlat[0];
const lat = lonlat[1];
console.log(lonlat)
this.addMarker(lon, lat);
}
addMarker(lon: number, lat: number) {
this.markerSource.clear();
let marker = new Feature({
geometry: new Point(fromLonLat([lon,lat])) // dont worry about coordinate type 0,0 will be in west coast of africa
});
this.markerSource.addFeature(marker)
}
}
My html file
<div id="map" (click)="getCoord($event)"></div>