简体   繁体   English

如何在 React Leaflet & Routing Machine 中添加层并按车辆代码过滤

[英]How to Add Layer in React Leaflet & Routing Machine and Filter by Vehicle Code

在此处输入图像描述

You can see the component I created in the picture.您可以在图片中看到我创建的组件。 Here are the different vehicles and their latitude and longitude values.以下是不同的车辆及其纬度和经度值。 I am routing according to these values.我正在根据这些值进行路由。 What I want to add at this stage is that there is a layer button on the top right of the map and I want my vehicle codes in the popup that opens when I click on this layer button.在这个阶段我想添加的是 map 的右上角有一个图层按钮,我希望我的车辆代码在我点击这个图层按钮时打开的弹出窗口中。 Vehicle24, Vehicle30... When I click on vehicle24 from the popup that opens, I want only vehicle24's routes to appear. Vehicle24, Vehicle30... 当我从打开的弹出窗口中单击 vehicle24 时,我只希望显示 vehicle24 的路线。 Is this possible, I can't make any progress.这可能吗,我无法取得任何进展。 Thanks in advance for your help.在此先感谢您的帮助。 I will add the codes I used below我将在下面添加我使用的代码

TrackingMap.tsx TrackingMap.tsx

import { useState } from 'react';
//Third Party imports
import 'leaflet/dist/leaflet.css';
import { MapContainer, TileLayer } from 'react-leaflet';
import L from 'leaflet';

//Components imports
import Routing from './Routing';

//Utils import
import { MapWithPopupdatav2 } from './fakeData2';
import { CoordinatInterface, EachPointforRouting } from 'types/Map';

interface DefaultMapWithPopupProps {
  // dataSource: RootMapWithPopupData;
  height?: string;
  width?: string;
}

const TrackingMap = ({ height }: DefaultMapWithPopupProps) => {
  const [markersDataSource, setMarkersDataSource] = useState(
    MapWithPopupdatav2.data.map(item => item.gridData.data.map(item => item))
  );

  const [routeWayColor, setRouteWayColor] = useState<string[]>(
    MapWithPopupdatav2.data.map(item => item.color)
  );

  const [dataForRouting, setDataForRouting] = useState<EachPointforRouting[][]>(
    MapWithPopupdatav2.data.map(eachPoint =>
      eachPoint.gridData.data.map(point =>
        L.latLng(point.latitude, point.longitude)
      )
    )
  );

  const markersLatLon: CoordinatInterface[][] = MapWithPopupdatav2.data.map(
    eachPoint =>
      eachPoint.gridData.data.map(point => ({
        latitude: point.latitude,
        longitude: point.longitude,
      }))
  );
  function centerMapDataCalculate(data: CoordinatInterface[][]) {
    let newArray: CoordinatInterface[] = [];
    data.forEach(item => {
      item.map(point => {
        newArray.push(point);
      });
    });
    return newArray;
  }

  const markersCoordinatesForMapCentering: CoordinatInterface[] =
    centerMapDataCalculate(markersLatLon);
  return (
    <MapContainer scrollWheelZoom={true} style={{ height: `${height}` }}>
      <TileLayer
        attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
      {dataForRouting.map((eachPoint, index) => {
        return (
          <Routing
            key={index}
            eachPoint={eachPoint}
            dataSource={markersDataSource[index]}
            color={routeWayColor[index]}
            bounds={markersCoordinatesForMapCentering}
          />
        );
      })}
    </MapContainer>
  );
};

export default TrackingMap;

Routing.tsx路由.tsx

import { useEffect } from 'react';
//Third Party İmports
import L, { latLngBounds } from 'leaflet';
import 'leaflet-routing-machine/dist/leaflet-routing-machine.css';
import 'leaflet-routing-machine';
import { useMap } from 'react-leaflet';
//Components

//Utils import
import { RoutingPropsforTrackingMap } from 'types/Map';
import { MarkerSVG } from 'utils/markerSVG';
import { closePopUpIconOptions } from 'utils/closePopUpIconOptions';
import { layerGroup } from 'leaflet';

L.Marker.prototype.options.icon = L.icon({
  iconUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png',
});

const Routing = ({
  eachPoint,
  dataSource,
  color,
  bounds,
}: RoutingPropsforTrackingMap) => {
  const map = useMap();
  let markerBounds = latLngBounds([]);
  const svgIcon = (visitOrder: number, color: string) =>
    L.divIcon({
      html: MarkerSVG(visitOrder, color),
      className: 'markerIcon',
      iconSize: [50, 50],
      iconAnchor: [32, 70],
      popupAnchor: [0, -70],
    });
  useEffect(() => {
    if (!map) return;
    console.log(eachPoint);

    const routingControl = L.Routing.control({
      waypoints: eachPoint,
      createMarker: function (
        waypointIndex: any,
        waypoint: any,
        numberOfWaypoints: any
      ) {
        return L.marker(waypoint.latLng, {
          icon: svgIcon(dataSource[waypointIndex].visitOrder, color),
        })
          .bindPopup(
            `<p><b>Location Code:</b>${dataSource[waypointIndex].locationCode}</p>
          <p><b>Location Type:</b>${dataSource[waypointIndex].locationType}</p>
          <p><b>Visit Order:</b>${dataSource[waypointIndex].visitOrder}</p>
          <p><b>Vehicle Code:</b>${dataSource[waypointIndex].vehicleCode}</p>
          `
          )
          .on('click', function (e: any) {
            closePopUpIconOptions();
          });
      },
      lineOptions: {
        styles: [
          {
            color: color,
            opacity: 1,
            weight: 7,
          },
        ],
      },

      addWaypoints: false,
      draggableWaypoints: false,
      fitSelectedRoutes: false,
      showAlternatives: true,
    }).addTo(map);
    if (bounds.length && bounds.length > 0) {
      bounds.forEach(marker => {
        markerBounds.extend([marker.latitude, marker.longitude]);
      });
      map.fitBounds(markerBounds);
    }

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

  return null;
};
export default Routing;

FakeData.ts假数据.ts

export const MapWithPopupdatav2 = {
  data: [
    {
      id: 1,
      vehicleCode: 'Vehicle39',
      vehicleId: 39,
      color: '#0ac282',
      gridData: {
        currentPage: 1,
        firstRowOnPage: 1,
        kind: 0,
        lastRowOnPage: 15,
        pageCount: 1,
        pageSize: 10000,
        totalRowCount: 15,
        data: [
          {
            distanceMatrixId: 245046421,
            duration: 618000,
            endDate: '2019-09-24T11:44:39',
            latitude: 41.021569,
            locationCode: 'S1R1037',
            locationName: '',
            locationType: 'RCM',
            longitude: 29.040992,
            planDayId: 183,
            planResultId: 116894,
            serviceType: 'RCM Replenish',
            startDate: '2019-09-24T11:34:21',
            status: 'To Do',
            vehicleCode: 'Vehicle39',
            vehicleId: 39,
            visitOrder: 1,
          },
          {
            distanceMatrixId: 189364956,
            duration: 1074000,
            endDate: '2019-09-24T12:05:35',
            latitude: 41.018218,
            locationCode: 'S1A2275',
            locationName: '',
            locationType: 'RCM',
            longitude: 29.044254,
            planDayId: 183,
            planResultId: 116906,
            serviceType: 'Fix',
            startDate: '2019-09-24T11:47:41',
            status: 'To Do',
            vehicleCode: 'Vehicle39',
            vehicleId: 39,
            visitOrder: 2,
          },
          {
            distanceMatrixId: 189452735,
            duration: 618000,
            endDate: '2019-09-24T12:47:52',
            latitude: 41.0075,
            locationCode: 'S1R2054',
            locationName: '',
            locationType: 'RCM',
            longitude: 29.035592,
            planDayId: 183,
            planResultId: 116891,
            serviceType: 'RCM Replenish',
            startDate: '2019-09-24T12:37:34',
            status: 'To Do',
            vehicleCode: 'Vehicle39',
            vehicleId: 39,
            visitOrder: 3,
          },
        ],
      },
    },
    {
      id: 2,
      vehicleCode: 'Vehicle24',
      vehicleId: 24,
      color: '#807ACD',
      gridData: {
        currentPage: 1,
        firstRowOnPage: 1,
        kind: 0,
        lastRowOnPage: 6,
        pageCount: 1,
        pageSize: 10000,
        totalRowCount: 6,
        data: [
          {
            distanceMatrixId: 245857071,
            duration: 696000,
            endDate: '2019-09-24T12:13:45',
            latitude: 40.999569,
            locationCode: '0405',
            locationName: 'Branch48',
            locationType: 'Branch',
            longitude: 29.095666,
            planDayId: 183,
            planResultId: 117530,
            serviceType: 'Cash pickup & Delivery',
            startDate: '2019-09-24T12:02:09',
            status: 'To Do',
            vehicleCode: 'Vehicle24',
            vehicleId: 24,
            visitOrder: 1,
          },
          {
            distanceMatrixId: 276074744,
            duration: 696000,
            endDate: '2019-09-24T14:11:36',
            latitude: 40.992341,
            locationCode: '0022',
            locationName: 'Branch10',
            locationType: 'Branch',
            longitude: 29.101693,
            planDayId: 183,
            planResultId: 117529,
            serviceType: 'Cash pickup & Delivery',
            startDate: '2019-09-24T14:00:00',
            status: 'To Do',
            vehicleCode: 'Vehicle24',
            vehicleId: 24,
            visitOrder: 2,
          },
          {
            distanceMatrixId: 242141750,
            duration: 696000,
            endDate: '2019-09-24T16:11:36',
            latitude: 40.98491,
            locationCode: '0610',
            locationName: 'Branch70',
            locationType: 'Branch',
            longitude: 29.092627,
            planDayId: 183,
            planResultId: 117528,
            serviceType: 'Cash pickup & Delivery',
            startDate: '2019-09-24T16:00:00',
            status: 'To Do',
            vehicleCode: 'Vehicle24',
            vehicleId: 24,
            visitOrder: 3,
          },
        ],
      },
    },
    {
      id: 3,
      vehicleCode: 'Vehicle36',
      vehicleId: 24,
      color: '#F38876',
      gridData: {
        currentPage: 1,
        firstRowOnPage: 1,
        kind: 0,
        lastRowOnPage: 28,
        pageCount: 1,
        pageSize: 10000,
        totalRowCount: 28,
        data: [
          {
            distanceMatrixId: 245046567,
            duration: 1074000,
            endDate: '2019-09-24T11:38:01',
            latitude: 40.980517,
            locationCode: 'S1A4960',
            locationName: '',
            locationType: 'ATM',
            longitude: 29.075156,
            planDayId: 183,
            planResultId: 117282,
            serviceType: 'Fix',
            startDate: '2019-09-24T11:20:07',
            status: 'To Do',
            vehicleCode: 'Vehicle36',
            vehicleId: 36,
            visitOrder: 1,
          },
          {
            distanceMatrixId: 189328693,
            duration: 444000,
            endDate: '2019-09-24T11:49:35',
            latitude: 40.979788,
            locationCode: 'S1A7396',
            locationName: '',
            locationType: 'ATM',
            longitude: 29.067378,
            planDayId: 183,
            planResultId: 117281,
            serviceType: 'ATM Replenish',
            startDate: '2019-09-24T11:42:11',
            status: 'To Do',
            vehicleCode: 'Vehicle36',
            vehicleId: 36,
            visitOrder: 2,
          },
          {
            distanceMatrixId: 191205228,
            duration: 1074000,
            endDate: '2019-09-24T12:14:55',
            latitude: 40.974639,
            locationCode: 'S1A9243',
            locationName: '',
            locationType: 'RCM',
            longitude: 29.05792,
            planDayId: 183,
            planResultId: 117280,
            serviceType: 'Fix',
            startDate: '2019-09-24T11:57:01',
            status: 'To Do',
            vehicleCode: 'Vehicle36',
            vehicleId: 36,
            visitOrder: 3,
          },
        ],
      },
    },
    {
      id: 4,
      vehicleCode: 'Vehicle30',
      vehicleId: 30,
      color: '#008EA9',
      gridData: {
        currentPage: 1,
        firstRowOnPage: 1,
        kind: 0,
        lastRowOnPage: 23,
        pageCount: 1,
        pageSize: 10000,
        totalRowCount: 23,
        data: [
          {
            distanceMatrixId: 271855562,
            duration: 618000,
            endDate: '2019-09-24T12:46:37',
            latitude: 41.025808,
            locationCode: 'S1R2206',
            locationName: '',
            locationType: 'RCM',
            longitude: 29.015655,
            planDayId: 183,
            planResultId: 117165,
            serviceType: 'RCM Replenish',
            startDate: '2019-09-24T12:36:19',
            status: 'To Do',
            vehicleCode: 'Vehicle30',
            vehicleId: 30,
            visitOrder: 1,
          },
          {
            distanceMatrixId: 245814193,
            duration: 1074000,
            endDate: '2019-09-24T11:18:01',
            latitude: 41.022554,
            locationCode: 'S1C2293',
            locationName: '',
            locationType: 'ATM',
            longitude: 29.015923,
            planDayId: 183,
            planResultId: 117170,
            serviceType: 'Fix',
            startDate: '2019-09-24T11:00:07',
            status: 'To Do',
            vehicleCode: 'Vehicle30',
            vehicleId: 30,
            visitOrder: 2,
          },
          {
            distanceMatrixId: 273658538,
            duration: 444000,
            endDate: '2019-09-24T11:32:59',
            latitude: 41.018628,
            locationCode: 'S1C1902',
            locationName: '',
            locationType: 'ATM',
            longitude: 29.011041,
            planDayId: 183,
            planResultId: 117169,
            serviceType: 'ATM Replenish',
            startDate: '2019-09-24T11:25:35',
            status: 'To Do',
            vehicleCode: 'Vehicle30',
            vehicleId: 30,
            visitOrder: 3,
          },
          {
            distanceMatrixId: 272746632,
            duration: 618000,
            endDate: '2019-09-24T11:47:01',
            latitude: 41.01522,
            locationCode: 'S1R2650',
            locationName: '',
            locationType: 'RCM',
            longitude: 29.011577,
            planDayId: 183,
            planResultId: 117168,
            serviceType: 'RCM Replenish',
            startDate: '2019-09-24T11:36:43',
            status: 'To Do',
            vehicleCode: 'Vehicle30',
            vehicleId: 30,
            visitOrder: 4,
          },
        ],
      },
    },
  ],
};

// export interface Datum2 {
//   distanceMatrixId: number;
//   duration: number;
//   endDate: Date;
//   latitude: number;
//   locationCode: string;
//   locationName: string;
//   locationType: string;
//   longitude: number;
//   planDayId: number;
//   planResultId: number;
//   serviceType: string;
//   startDate: string;
//   status: string;
//   vehicleCode: string;
//   vehicleId: number;
//   visitOrder: number;
// }

// export interface GridData {
//   currentPage: number;
//   firstRowOnPage: number;
//   kind: number;
//   lastRowOnPage: number;
//   pageCount: number;
//   pageSize: number;
//   totalRowCount: number;
//   data: Datum2[];
// }

// export interface Datum {
//   id: number;
//   vehicleCode: string;
//   vehicleId: number;
//   color: string;
//   gridData: GridData;
// }

// export interface RootObject {
//   data: Datum[];
// }

react-leaflet supports adding custom controls . react-leaflet 支持添加自定义控件 Using such custom control, you can add a basic list that handles selecting a vehicle, saving its index in state and changing the route accordingly.使用此类自定义控件,您可以添加处理选择车辆的基本列表,将其索引保存在 state 并相应地更改路线。

Here's a working fiddle that places a very basic custom control in the bottom-left corner. 这是一个工作小提琴,它在左下角放置了一个非常基本的自定义控件。 This is because once the routing control is appended to the DOM, your top-right corner would be occupied.这是因为一旦将路由控件附加到 DOM,您的右上角就会被占用。

Apart from the custom control and useState() hook, you'll also want to modify the useEffect hook in the Routing.tsx to be exhaustive.除了自定义控件和useState()钩子之外,您还需要修改 Routing.tsx 中的useEffect Routing.tsx以使其详尽无遗。 As for why this is, I recommend giving Dan Abramov's deep-dive a read.至于为什么会这样,我建议阅读Dan Abramov 的深入研究。 Basically, with just the map in your deps, your component will never update, even if the underlying coordinates change.基本上,在你的部门中只有 map,你的组件永远不会更新,即使底层坐标发生变化。 For clarity, I left the markerBounds out of the dependency list in the sample.为清楚起见,我将markerBounds排除在示例的依赖项列表之外。 You should see yellow squiggly lines saying the list is missing that (so in your code, you would add it in there)您应该看到黄色波浪线,说明列表缺少该列表(因此在您的代码中,您将在其中添加它)

Also as a side note, although I'm sure this is just for testing purposes, I would advise against re-instantiating the whole routing machine in the useEffect hook and rather update the coordinates there and then reroute.另外作为旁注,虽然我确信这只是为了测试目的,但我建议不要在useEffect挂钩中重新实例化整个路由机器,而是更新那里的坐标然后重新路由。 This would remove the need to call addTo() and removeControl() on every render这将消除在每次渲染时调用addTo()removeControl()的需要

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将 leaflet 路由机器控制添加到另一个 div 而不是 map:react-leaflet - how to add leaflet routing machine control to another div instead of map: react-leaflet 如何在 React-Leaflet 3 中使用 Leaflet 路由机? - How to use Leaflet Routing Machine with React-Leaflet 3? 如何在 react-leaflet 中添加弹出到 WMS 层 - How to add pop up to WMS Layer in react- leaflet 如何使用反应在传单的图层控件选择上添加标题? - How to add titles on leaflet's layer control selection using react? React Leaflet Routing Machine: onClick to add Marker after all waypoints are removes only after second clicks - React Leaflet Routing Machine: onClick to add Marker after all waypoints are removed fires only after second click React + leaflet + 路由机器:在 MapContainer 外部访问 map 时出现问题 - React + leaflet + routing machine : Problem accessing map outside MapContainer 如何引用反应小叶组件的小叶层? - How to reference the leaflet layer of a react-leaflet component? 如何引用 React Leaflet GeoJSON 组件层名称? - How to reference React Leaflet GeoJSON component layer name? 如何在React中现有的Leaflet贴图中编辑/修改图层源? - How to edit/modify layer source in existing Leaflet map in React? 如何以编程方式显示/隐藏 react-leaflet 中的图层? - How do I programatically show/hide a layer in react-leaflet?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM