perliedman / leaflet-routing-machine

Control for routing in Leaflet
https://www.liedman.net/leaflet-routing-machine/
Other
1.06k stars 347 forks source link

How to make all markers appear in the bounding rectangle #666

Closed Ynsinan closed 1 year ago

Ynsinan commented 1 year ago

I don't want to manually enter a center coordinate and zoom ratio.What I want is for the screen to adjust the zoom ratio according to the markers. Automatically fit them all on the screen.

Thank you very much in advance

TrackingMap.tsx

import { useEffect, useRef, 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 { eachPointforRouting } from 'types/Map';
import { getCenterMapCoordinates } from 'utils/getCenterMapCoordinates';
import { getBounds } from 'geolib';
import { useMap } from 'react-leaflet';

type centerMapProps = {
  latitude: number;
  longitude: number;
};
type DefaultMapWithPopupProps = {
  // dataSource: RootMapWithPopupData;
  height?: string;
  width?: string;
};

const TrackingMap = ({ height }: DefaultMapWithPopupProps) => {
  const bounds: any = [];
  const mapRef = useRef();
  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: centerMapProps[][] = MapWithPopupdatav2.data.map(
    eachPoint =>
      eachPoint.gridData.data.map(point => ({
        latitude: point.latitude,
        longitude: point.longitude,
      }))
  );

  //We convert the structure that contains an array and an object in an array to an object in a single array
  //Currently only used here. Function needs to be moved to utils if it needs to be used elsewhere
  // - Yunus İNAN
  function centerMapDataCalculate(data: centerMapProps[][]) {
    let newArray: any = [];
    data.forEach(item => {
      item.map(point => {
        newArray.push(point);
      });
    });
    return newArray;
  }
  const markersCoordinatesForMapCentering =
    centerMapDataCalculate(markersLatLon);

  const centerValues: centerMapProps | any = getCenterMapCoordinates(
    markersCoordinatesForMapCentering
  );

  return (
    <MapContainer
      center={[centerValues.latitude, centerValues.longitude]}
      zoom={9}
      scrollWheelZoom={true}
      style={{ height: `${height}` }}
      ref={mapRef}
    >
      <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={bounds}
          />
        );
      })}
    </MapContainer>
  );
};

export default TrackingMap;

Routing.tsx

import { useEffect } from 'react';
//Third Party İmports
import L 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';

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();

  useEffect(() => {
    if (!map) return;

    const routingControl = L.Routing.control({
      waypoints: eachPoint,
      createMarker: function (
        waypointIndex: any,
        waypoint: any,
        numberOfWaypoints: any
      ) {
        return L.marker(waypoint.latLng).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>
          `
        );
      },
      lineOptions: {
        styles: [
          {
            color: color,
            opacity: 1,
            weight: 7,
          },
        ],
      },
      addWaypoints: false,
      draggableWaypoints: false,
      fitSelectedRoutes: false,
      showAlternatives: true,
    }).addTo(map);
    map.fitBounds(bounds.getBounds());
    return () => map.removeControl(routingControl);
  }, [map]);

  return null;
};
export default Routing;

FakeData.ts

export const MapWithPopupdatav2 = {
  data: [
    {
      id: 1,
      vehicleCode: 'Vehicle39',
      vehicleId: 39,
      color: '#00ff00',
      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: 13.74355389,
            locationCode: 'S1R1037',
            locationName: '',
            locationType: 'RCM',
            longitude: 100.5035463,
            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: 13.74364101,
            locationCode: 'S1A2275',
            locationName: '',
            locationType: 'RCM',
            longitude: 100.5014584,
            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: 13.74557352,
            locationCode: 'S1R2054',
            locationName: '',
            locationType: 'RCM',
            longitude: 100.5000613,
            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: '#ff0000',
      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: 14.11781576,
            locationCode: '0405',
            locationName: 'Branch48',
            locationType: 'Branch',
            longitude: 100.6180874,
            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: 13.89500694,
            locationCode: '0022',
            locationName: 'Branch10',
            locationType: 'Branch',
            longitude: 100.6078357,
            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: 13.98929965,
            locationCode: '0610',
            locationName: 'Branch70',
            locationType: 'Branch',
            longitude: 100.6185016,
            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: '#b200ff',
      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: 13.74467119,
            locationCode: 'S1A4960',
            locationName: '',
            locationType: 'ATM',
            longitude: 100.5839852,
            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: 13.74646852,
            locationCode: 'S1A7396',
            locationName: '',
            locationType: 'ATM',
            longitude: 100.5736933,
            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: 13.7470292,
            locationCode: 'S1A9243',
            locationName: '',
            locationType: 'RCM',
            longitude: 100.5794979,
            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: '#209ff3',
      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: 14.0661598,
            locationCode: 'S1R2206',
            locationName: '',
            locationType: 'RCM',
            longitude: 100.6293817,
            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: 14.10503655,
            locationCode: 'S1C2293',
            locationName: '',
            locationType: 'ATM',
            longitude: 100.6886859,
            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: 14.0756659,
            locationCode: 'S1C1902',
            locationName: '',
            locationType: 'ATM',
            longitude: 100.6875185,
            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: 14.06629306,
            locationCode: 'S1R2650',
            locationName: '',
            locationType: 'RCM',
            longitude: 100.684938,
            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[];
// }
Ynsinan commented 1 year ago

I solved the problem TrackingMap.tsx Changes

 {dataForRouting.map((eachPoint, index) => {
        return (
          <Routing
            key={index}
            eachPoint={eachPoint}
            dataSource={markersDataSource[index]}
            color={routeWayColor[index]}
            bounds={markersCoordinatesForMapCentering}
          />
        );
      })}

Routing.tsx Changes adding the addTo(map) under

 if (bounds.length && bounds.length > 0) {
      bounds.forEach(marker => {
        markerBounds.extend([marker.latitude, marker.longitude]);
      });
      map.fitBounds(markerBounds);
    }
curtisy1 commented 1 year ago

Glad to hear you solved it! I'll go ahead and close this issue for now