基于JSON的Leaflet-geosearch实现

5jdjgkvh  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(74)

我遇到了一个问题,我无法在搜索字段中连接我的JSON列表。我找不到如何正确更改提供程序(const provider = newOpenStreetMapProvider())的解决方案,以便它通过JSON进行搜索。

import React, { useEffect } from 'react';

import { MapContainer, TileLayer, useMap } from 'react-leaflet';
import L from 'leaflet';
import 'leaflet-geosearch/dist/geosearch.css';
import { GeoSearchControl, OpenStreetMapProvider } from 'leaflet-geosearch';
import customMarkerIcon from 'assets/img/maps/marker-icon.png';
import markerData3 from 'assets/data/json/airports.json';

const customIcon = L.icon({
  iconUrl: customMarkerIcon,
  iconSize: [25, 41],
  iconAnchor: [12, 41],
  popupAnchor: [1, -34],
});


const Search = () => {
  const map = useMap();

  useEffect(() => {
    const locations = markerData3.map(location => ({
      ...location,
      lat: parseFloat(location.coordinates.split(',')[1].trim()),
      lng: parseFloat(location.coordinates.split(',')[0].trim()),
    }));

    const provider = new OpenStreetMapProvider();
    const searchControl = new GeoSearchControl({
      provider: provider,
      style: 'bar',
      showMarker: true,
      showPopup: false,
      marker: {
        icon: new L.Icon.Default(),
        draggable: false,
      },
      autoClose: true, // Automatically close the search results container on selection
      searchLabel: 'Enter location...', // Change the placeholder text
      retainZoomLevel: false, // Maintain the zoom level after searching
      animateZoom: true, // Animate the zoom to the selected location
    }).addTo(map);

    // Prepare the data for the search
    provider.search({
      query: '', // Empty query to load all locations
      latlng: locations.map(location => [location.lat, location.lng]),
    });

    return () => {
      map.removeControl(searchControl);
    };
  }, [map]);

  return null;
};

const MapWithMarkers = ({ onMarkerClick }) => {
  const map = useMap();
  const markerClusterGroupRef = L.markerClusterGroup();

  useEffect(() => {
    // Clear the existing markers from the cluster group
    markerClusterGroupRef.clearLayers();

    // Add new markers to the cluster group
    markerData3.forEach(marker => {
      const [lng, lat] = marker.coordinates.split(',').map(coord => parseFloat(coord.trim()));
      const leafletMarker = L.marker([lat, lng], { icon: customIcon });

      // Attach a click event listener to the marker
      leafletMarker.on('click', () => {
        onMarkerClick(`${marker.iso_country} - ${marker.name} - ${marker.ident}`);
      });

      const popupContent = `<strong>${marker.ident}</strong><br>${marker.name}`;
      leafletMarker.bindPopup(popupContent);
      markerClusterGroupRef.addLayer(leafletMarker);
    });
    

    // Add the updated cluster group to the map
    map.addLayer(markerClusterGroupRef);

    // Clean up when the component unmounts
    return () => {
      map.removeLayer(markerClusterGroupRef);
    };
  }, [map, onMarkerClick]);

  return null;
};

const AirportsMapNewAircraftSection = ({ mapType, onMarkerClick }) => {

  // Callback function to handle marker clicks
  const handleMarkerClick = (basePoint) => {
    onMarkerClick(basePoint)
  };

  

  return (
    <div className="AirportsMap" style={{ width: '100%'}}>
      <MapContainer center={[56.9235, 23.9710]} zoom={4} maxZoom={18} style={{ height: '500px', width: '100%', borderRadius: "0px 0px 10px 10px"}}>
        <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
        <MapWithMarkers onMarkerClick={handleMarkerClick}/>
        <Search />
      </MapContainer>
    </div>
  );
};

export default AirportsMapNewAircraftSection;

个字符
Package.json版本的插件

"react-leaflet": "^4.2.1",
    "react-leaflet-cluster": "^2.1.0",
    "react-leaflet-markercluster": "^3.0.0-rc1",
    "react-leaflet-search": "^2.0.1",
    "leaflet": "^1.9.4",
    "leaflet-easybutton": "^2.4.0",
    "leaflet-geosearch": "^3.11.0",
    "leaflet-search": "^4.0.0",
    "leaflet-search-control": "^2.1.2",
    "leaflet.markercluster": "^1.5.3",

jmp7cifd

jmp7cifd1#

最后!仍然工作没有输入滞后和没有错误。

已创建CustomJSON Provider

const CustomJSONProvider = {
  search: async ({ query }) => {
    if (!query) {
      return [];
    }

    const searchResults = markerData3.filter(location =>
      location.ident.toLowerCase().includes(query.toLowerCase())
    );

    return searchResults.map(location => ({
      y: parseFloat(location.coordinates.split(',')[1].trim()),
      x: parseFloat(location.coordinates.split(',')[0].trim()),
      label: location.ident,
    }));
  },
};

字符串

完整代码

import React, { useEffect } from 'react';

import { MapContainer, TileLayer, useMap } from 'react-leaflet';
import L from 'leaflet';
import 'leaflet-geosearch/dist/geosearch.css';
import { GeoSearchControl } from 'leaflet-geosearch';
import customMarkerIcon from 'assets/img/maps/marker-icon.png';
import markerData3 from 'assets/data/json/airports.json';
import 'leaflet/dist/leaflet.css';

const customIcon = L.icon({
  iconUrl: customMarkerIcon,
  iconSize: [25, 41],
  iconAnchor: [12, 41],
  popupAnchor: [1, -34],
});


const CustomJSONProvider = {
  search: async ({ query }) => {
    if (!query) {
      return [];
    }

    const searchResults = markerData3.filter(location =>
      location.ident.toLowerCase().includes(query.toLowerCase())
    );

    return searchResults.map(location => ({
      y: parseFloat(location.coordinates.split(',')[1].trim()),
      x: parseFloat(location.coordinates.split(',')[0].trim()),
      label: location.ident,
    }));
  },
};

const Search = () => {
  const map = useMap();

  useEffect(() => {
    const searchControl = new GeoSearchControl({
      provider: CustomJSONProvider,
      style: 'bar',
      showMarker: true,
      showPopup: false,
      marker: {
        icon: new L.Icon.Default(),
        draggable: false,
      },
      autoClose: true,
      searchLabel: 'Enter location...',
      retainZoomLevel: false,
      animateZoom: true,
    }).addTo(map);

    return () => {
      map.removeControl(searchControl);
    };
  }, [map]);

  return null;
};

const MapWithMarkers = ({ onMarkerClick }) => {
  const map = useMap();
  const markerClusterGroupRef = L.markerClusterGroup();

  useEffect(() => {
    // Clear the existing markers from the cluster group
    markerClusterGroupRef.clearLayers();

    // Add new markers to the cluster group
    markerData3.forEach(marker => {
      const [lng, lat] = marker.coordinates.split(',').map(coord => parseFloat(coord.trim()));
      const leafletMarker = L.marker([lat, lng], { icon: customIcon });

      // Attach a click event listener to the marker
      leafletMarker.on('click', () => {
        onMarkerClick(`${marker.iso_country} - ${marker.name} - ${marker.ident}`);
      });

      const popupContent = `<strong>${marker.ident}</strong><br>${marker.name}`;
      leafletMarker.bindPopup(popupContent);
      markerClusterGroupRef.addLayer(leafletMarker);
    });

    // Add the updated cluster group to the map
    map.addLayer(markerClusterGroupRef);

    // Clean up when the component unmounts
    return () => {
      map.removeLayer(markerClusterGroupRef);
    };
  }, [map, onMarkerClick]);

  return null;
};

const AirportsMapNewAircraftSection = ({ mapType, onMarkerClick }) => {

  // Callback function to handle marker clicks
  const handleMarkerClick = (basePoint) => {
    onMarkerClick(basePoint)
  };

  return (
    <div className="AirportsMap" style={{ width: '100%'}}>
      <MapContainer center={[56.9235, 23.9710]} zoom={4} maxZoom={18} style={{ height: '500px', width: '100%', borderRadius: "0px 0px 10px 10px"}}>
        <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
        <MapWithMarkers onMarkerClick={handleMarkerClick}/>
        <Search />
      </MapContainer>
    </div>
  );
};

export default AirportsMapNewAircraftSection;

帮助我的URL

https://smeijer.github.io/leaflet-geosearch/providers/custom-providers

相关问题