reactjs leaflet kml wrong behaviour - reactjs

I'm using https://github.com/shramov/leaflet-plugins display kml in my map, it work's great, but when I'm using reactjs kml not displaying as should be and map.fitBounds(e.target.getBounds()); not working, there is no problem if not using reactjs, here is my code
componentDidMount() {
mymap = new L.Map('map', {center: new L.LatLng(-2.6025, 140.6927), zoom: 11});
var baselayer = new L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'OSM ',
maxZoom: 18,
});
mymap.addLayer(baselayer);
baselayer.on('load', function (event) {
var track = new L.KML("/files/1/Layer/Administrasi/Administrasi Kota Jayapura.kml", {async: true});
mymap.addLayer(track);
});
}
here is the result when using reactJS
Do I Miss something ?

I don't know that KML was threaded as svg or not, but but global style for SVG seems affected KML as well, so remove/modify css for svg solve this problems.

Related

Avoid re-rendering of open layers map when context changes

I am using an Open Layers map inside React. I am attaching it to the DOM using setTarget like so:
const mapObject = useMap(maplayers);
useEffect(() => {
mapObject.setTarget(mapRef.current);
return () => mapObject && mapObject.setTarget(undefined);
},[mapObject]);
Inside the useMap.js hook I am writing changes to the center and zoom of the map back to the context:
const {
zoom,
setZoom,
center,
setCenter,
} = useContext(MapContext);
let mapObject = null;
var projection = new olProj.Projection({
code: 'EPSG:25832',
units: 'm',
});
let options = {
target: 'map',
controls: olControl.defaults({
rotate: false,
zoom: false,
attributionOptions: {
collapsible: false,
},
}),
layers: maplayers,
view: new ol.View({
projection: projection,
center: center,
zoom: zoom
}),
};
mapObject = new ol.Map(options);
mapObject.on('moveend', (e) => {
console.log('moveend');
setCenter(() => e.target.getView().getCenter());
setZoom(() => e.target.getView().getZoom());
});
The problem now is that the whole map gets rerendered every time the center and zoom change. How can I avoid this? The only idea I have is to use useEffect with a dependency array that misses center and zoom but I know this is bad practise and should not be done.
You just discovered why one should not use useEffect to create Openlayers components in React. I answer this question once per week here - I will probably end up writing a very long and detailed answer and then start marking those questions as duplicates. Or maybe write a tutorial for Openlayers + React.
What you are trying to achieve is not easy and no one got it right the first time. I am the author of rlayers - https://github.com/mmomtchev/rlayers - a set of components for using Openlayers in React. The only reliable way to do everything that React expects is to use class-based components and to completely rewrite the React component life-cycle. You are free to use my components - either directly, either as an inspiration for writing your own.
In your particular case, the problem is that you create a new mapObject every time the hook is called. React detects this change and decides that the component must be rerendered. Built-in React hooks work around this by memoizing the value. Your hook should declare the dependencies of the mapObject and then use React.useMemo to always return the same object:
const mapObject = React.useMemo(() => {
// code to generate the mapObject
return mapObject;
}, [ projection, url, /* and all other items that require rerender */ ]
);
This way your hook will always return the same mapObject and you will continue to use a useEffect with only the mapObject as a dependency - according to the React guidelines.

Problem with initializing existing canvas with PixiJs

As titled,
Is it possible to initialize canvas with image on it using Pixi so that i can add filter on top of it? Im using gsap 3.2.6 and Pixi 5.2.4.
I have the canvas created like this (using React btw)
useEffect(() => {
let ctx = imgDisplayer.current.getContext('2d');
let img = new Image();
img.onload = function(){
imgDisplayer.current.width = img.width; // To set canvas width to image width
imgDisplayer.current.height = img.height; // To set canvas height to image height
ctx.drawImage(img, 0, 0);
setCanvas(imgDisplayer.current);
}
img.src = source;
}, []);
That setCanvas is to store the loaded canvas into state, so that i can use it to initialize Pixi.
if (canvas){
const app = new Pixi.Application({
width: 1300,
height: 866,
backgroundColor: 0x000000,
autoResize: true,
view: canvas
});
}
Problem is, this throws me the following error
Error: This browser does not support WebGL. Try using the canvas renderer
If only i could fetch an https image (direct image link) then this wouldn't be a problem, and i can load the image using Pixi.Sprite insteaad.. but because of cross origin, i cannot think of way on how to render the image. I can render it just fine on canvas, but not with Pixi.
The error you pasted is saying that your browser does not support WebGL.
Please check WebGL support on those pages: https://get.webgl.org/ , https://webglreport.com/
Can you try to initialize Pixi on some simpler page just to check if it works for you? I mean, just create simple html page (without React etc), try to setup Pixi there and try to draw anything (some red circle etc).

Custom MapBox Icons in React without geojson

I am trying to create custom icons for my map markers in my mapbox in React, however essentially all of the existing documentation describes how to accomplish this when you are using a geojson wrapper to define a set amount of markers. This solution doesn't work for me, since the amount of markers for this application needs to be dynamic.
var el = document.createElement("div");
el.className = 'marker';
el.style.backgroundImage = 'url(droneIconSVG.svg)';
el.style.width = "50000px";
el.style.height = "50000px";
console.log(el.style.backgroundImage);
console.log(image01);
var drones = {};
firebase
.database()
.ref("drones")
.on("child_added", function(snapshot) {
var drone = new mapboxgl.Marker(el).setLngLat([snapshot.val().lat, snapshot.val().lng]).addTo(map);
drones[snapshot.val().id] = drone;
});
This code shows the creation of a marker, and assignment of that marker to every "drone" icon that has been added to my real time database in firebase. Any ideas as to why it might not be representing my "droneIconSVG.svg" file properly? It is a normal SVG file that I exported from illustrator.
Thank you

Google maps api with React

I am currently working on a project and have tried multiple times to include clickable markers into my map. I have use google-maps-react library, however I have not managed to get a marker showing information and being able to click on a button on this information window. I have read that Marker by default isn't clickable but is there an other way to do so ? or are there any tutorials or code that explain so
thank you in advance...
You need to use .addListener() on a marker and tell it to open an infowindow (or whichever action you want to take on marker click).
You can find an example in the Google API documentation here
// Add a marker to the map
const marker = new google.maps.Marker({
// position of the marker on map
position: { lat: 53.3, lng: -6.3 },
// the map object you want the marker on
map: map,
});
// add a listener to the marker which listens for a 'click'
// and runs the callback when it 'hears' one
marker.addListener('click', () => {
// set the content of the info window. This can be formatted using HTML
infowindow.setContent('I have been clicked!');
// tells the infowindow on which map to open and which marker to anchor to
infowindow.open(map, marker);
});

Using Leaflet plugins on react-leaflet

I am building a ReactJs application with react-leaflet.
Problem is that there are a lot of Leaflet plugins that has no support for react-leaflet.
I try to use this plugin
http://kartena.github.io/Leaflet.zoomslider/
Can somebody suggest a solution in this case?
Most Leaflet plugins don't have a React component. You can create custom components for React-Leaflet from the Leaflet plugin.
I was going to say you do it by getting a reference to the map object, but I don't think that's needed. But I have left that in at the base of this response as it a very helpful thing to know.
try the following:
var map = L.map('map', {
zoomsliderControl: true,
zoomControl: false,
layers: [layer]
}).setView([57.7, 11.9], 8);
Where 'map' is the id of the Map element.
===========================================
On your Map element get a reference to the map object.
<Map ref={(m) => this.leaf = m} etc...>
then in your react component.
where you have componentDidMount= () =>{
use the map object to add in the slider
var map = this.leaf.leafletElement;

Resources