How to set marker icon in leaflet map? - javascript

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

Leaflet only loads the first row of tiles in my map

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);
});

FlyTo on existing Mapbox Object in Svelte

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(...)

Problem with adding image on map with leaflet-distortableimage to the correct coordinates using corners

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: '&copy 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.

leaflet usage in Preact JS

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>

Click on zoom button trigger go thought all div and trigger my map function Anuglar10 / OpenLayer6

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>

Categories