smeijer / leaflet-geosearch

A geocoding/address-lookup library supporting various api providers.
https://smeijer.github.io/leaflet-geosearch/
MIT License
1.02k stars 270 forks source link

CustomMarker ignored and default icon not visible #336

Open Memo99 opened 1 year ago

Memo99 commented 1 year ago

HI,

i'm trying to show the search result on the map, but either my custom marker will be shown, or the default one, because the image is not contained in the npm package. ("dist/assets/img*)

How could i solve this?


import React, { Fragment, useEffect, useState } from 'react';
import L from 'leaflet';
import { MapContainer, TileLayer, Popup, Marker, useMap } from "react-leaflet";
import { GeoSearchControl, OpenStreetMapProvider } from 'leaflet-geosearch';

import {useGeoLocation} from 'services/LocationService';
import axios from 'axios';
import "leaflet-geosearch/assets/css/leaflet.css"

var called = false; // only dev mode

const customMarker = L.icon({
    iconRetinaUrl:  process.env.PUBLIC_URL + "/assets/img/misc/marker.png",
    iconUrl: process.env.PUBLIC_URL + "/assets/img/misc/marker.png",
    iconSize: [50, 50],
    iconAnchor: [25, 5],
});

export function LocationMap(props) {
    const location = useGeoLocation();
    const ZOOM_LEVEL = 13;
    const [searchTerm, setSearchTerm] = useState('');
    const [searchResults, setSearchResults] = useState(["Istanbul", "Ankara"]);
    const provider = new OpenStreetMapProvider();
    const searchControl = new GeoSearchControl({
        provider: provider,
        style: 'bar',
        showMarker: false, // optional: true|false  - default true
        showPopup: false, // optional: true|false  - default false
        popupFormat: ({ query, result }) => result.label, // optional: function    - default returns result label,
        resultFormat: ({ result }) => result.label, // optional: function    - default returns result label
        maxMarkers: 5, // optional: number      - default 1
        retainZoomLevel: true, // optional: true|false  - default false
        animateZoom: true, // optional: true|false  - default true
        autoClose: false, // optional: true|false  - default false
        searchLabel: 'search', // optional: string      - default 'Enter address'
        keepResult: false, // optional: true|false  - default false
        updateMap: true, // optional: true|false  - default true
        marker: {
            // optional: L.Marker    - default L.Icon.Default
            icon: new L.Icon.Default(),
            draggable: false,
          },
      });

    useEffect(() => {
        const delayDebounceFn = setTimeout(() => {

            if(searchTerm && searchTerm.length > 0)
            {
                const result = axios.get(`https://nominatim.openstreetmap.org/search/${searchTerm}?format=json`);
                result.then((result)=> {
                    console.log(result.data);
                    setSearchResults(result.data)
                })
            }
        }, 200)

        return () => clearTimeout(delayDebounceFn);
    }, [searchTerm])

    const CurrentPos = ({loc}) => {
        const mapRef = useMap();
        if(loc.loaded && !loc.error)
            mapRef.flyTo(
                {lat:loc.coordinates.lat, lng: loc.coordinates.lng}, 
                ZOOM_LEVEL, 
                {animate: false}
            )
        if(loc.error)
        {
            alert("No location");
        }
        return null;
    }

    const SearchComp = () => {
        const map = useMap();  
        useEffect(() => {
            if(!called)
            {
                map.addControl(searchControl); 
                called = true;
            }
        }, [])
        return null;
    }

    return (
        <Fragment>
            <div className="form-group submit-listing-map">
                <MapContainer id="map" zoom={8} center={{lat: 39.924396, lng: 32.836010 }} 
                // onClick={(e) => setLocation(e.latlng)}
                >
                    <TileLayer
                        url='https://{s}.tile.osm.org/{z}/{x}/{y}.png'
                    />
                    <SearchComp />
                    <CurrentPos loc={location} />
                    {location.loaded && !location.error && (
                        <Marker icon={customMarker} position={[location.coordinates.lat, location.coordinates.lng]}></Marker>
                    )}
                </MapContainer>
            </div>
        </Fragment>
    );

}```