gabriel-russo / Leaflet.BetterFileLayer

The definitive plugin to load your spatialized files into leaflet.
https://gabriel-russo.github.io/Leaflet.BetterFileLayer/example/
Other
18 stars 0 forks source link

@question use on React? #3

Closed Delky91 closed 4 months ago

Delky91 commented 4 months ago

I'm attempting to integrate a plugin, specifically L.Control.betterFileLayer(options), into a React application using React-Leaflet, but encountering difficulties. Despite installing the plugin via npm and following the documentation, I'm unable to get it to work.

this is a try really bad code and im using nextJS i just delete the react-leaflet try

"use client";
import { useEffect, useState } from "react";
import Script from "next/script";
import Head from "next/head";
import L from "leaflet";
import "leaflet-better-filelayer";

export default function Map2() {
    const [leafletLoaded, setLeafletLoaded] = useState(false);
    const [map, setMap] = useState<L.Map | null>(null);

    useEffect(() => {
        if (leafletLoaded) {
            const L = window.L;
            const mapInstance = L.map("map").setView([-41.4718, -72.9396], 13);
            L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
                attribution:
                    '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
            }).addTo(mapInstance);
            setMap(mapInstance);
        }
    }, [leafletLoaded]);

    const handleFileUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
        const file = event.target.files?.[0];
        if (file && map) {
            const L = window.L;
            const options = {
                button: document.getElementById("upload"),
            };
            L.Control.betterFileLayer(options).addTo(map);
        }
    };

    return (
        <>
            <Head>
                <link
                    rel='stylesheet'
                    href='https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.css'
                    integrity='sha512-h9FcoyWjHcOcmEVkxOfTLnmZFWIH0iZhZT1H2TbOq55xssQGEJHEaIm+PgoUaZbRvQTNTluNOEfb1ZRy6D3BOw=='
                    crossOrigin='anonymous'
                    referrerPolicy='no-referrer'
                />
            </Head>
            <Script
                src='https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.js'
                integrity='sha512-puJW3E/qXDqYp9IfhAI54BJEaWIfloJ7JWs7OeD5i6ruC9JZL1gERT1wjtwXFlh7CjE7ZJ+/vcRZRkIYIb6p4g=='
                crossOrigin='anonymous'
                referrerPolicy='no-referrer'
                onLoad={() => setLeafletLoaded(true)}
            />
            <Script
                type='application/javascript'
                src='https://unpkg.com/leaflet-better-filelayer@0.1.1/dist/leaflet.betterfilelayer.min.js'
                crossOrigin='anonymous'
            />
            <link
                rel='stylesheet'
                href='https://unpkg.com/leaflet-better-filelayer@0.1.1/dist/leaflet.betterfilelayer.css'
                crossOrigin='anonymous'
                referrerPolicy='no-referrer'
            />
            <div
                id='map'
                className='w-[100vw] h-[100vh]'></div>
            <input
                type='file'
                name='cargar archivo'
                className='z-[500] absolute bottom-0'
                id='upload'
                accept='.gpx,.kml,.geojson,.json,.csv,.topojson,.wkt,.shp,.shx,.prj,.dbf,.zip'
                onChange={handleFileUpload}
            />
        </>
    );
}

im really trying to brute force at this moment, i think i will have to transform all the data to geoJSON and then show it at this time, i found u library but still cant make it work, any advice or someething will be appreciate

Delky91 commented 4 months ago

finally i found the way to do it in Next JS

"use client";

import React, { useEffect, useRef } from "react";
import "leaflet/dist/leaflet.css";
import "leaflet-better-filelayer/dist/leaflet.betterfilelayer.css";

const Map2 = () => {
    const mapRef = useRef();
    const mapInstance = useRef(null);

    useEffect(() => {
        if (!mapInstance.current) {
            const L = require("leaflet");
            require("leaflet-better-filelayer");

            const osm = L.tileLayer(
                "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
                {
                    attribution: "Map data &copy; 2013 OpenStreetMap contributors",
                }
            );

            mapInstance.current = L.map(mapRef.current)
                .setView([-23.70078702319699, -46.69719607766831], 16)
                .addLayer(osm);

            const options = {
                button: document.getElementById("input-btn"),
            };
            console.log(L.Control.betterFileLayer(options));

            L.Control.betterFileLayer(options).addTo(mapInstance.current);
        }
    }, []);

    return (
        <div>
            <div>
                <span>Leaflet.BetterFileLayer</span>
                <a href='https://github.com/gabriel-russo/Leaflet.BetterFileLayer'>
                    github.com/gabriel-russo/Leaflet.BetterFileLayer
                </a>
                <div>
                    <p>Control Panel</p>
                    <input
                        type='file'
                        id='input-btn'
                        multiple
                        accept='.gpx,.kml,.geojson,.json,.csv,.topojson,.wkt,.shp,.shx,.prj,.dbf,.zip'
                    />
                </div>
            </div>
            <div
                ref={mapRef}
                style={{ width: "60vw", height: "90vh" }}></div>
        </div>
    );
};

export default Map2;
gabriel-russo commented 4 months ago

That's correct, that's the way i use in my personal projects too.

Sorry for the lack of documentation, soon i will fix that.

If it helps, here's an example using MaterialUI:

import "leaflet-better-filelayer";
// Others imports.......

// useRef and others declarations....

useEffect(() => {
    // ..... code ......

    bfl.current = new L.Control.BetterFileLayer({
        button: btn.current,
        fileSizeLimit: 10240
    });

    map.on("bfl:layerloaderror", () => { console.log("Your Layer failed to load") });

    map.addControl(bfl.current);

    // ...... code ......
}, []);

return (
    <IconButton color="inherit" {...props}>
        <FileUploadIcon />
        <input
            hidden
            type="file"
            ref={btn}
            multiple
            accept=".gpx,.kml,.geojson,.json,.csv,.topojson,.wkt,.shp,.shx,.prj,.dbf,.zip"
        />
    </IconButton>
);
Delky91 commented 4 months ago

ooo i see i have acceses to bfl that could be a good add to the docs, ty it not 100% what i need cause i was in need of a parser but if i modify my map i can still get the data so from the files that i just load, tysm for the library and the example