@navigoo/map-components 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@navigoo/map-components",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Reusable React components for mapping and routing in Yaoundé",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useRef, useState } from 'react';
1
+ import React, { useEffect, useRef } from 'react';
2
2
  import L from 'leaflet';
3
3
  import 'leaflet/dist/leaflet.css';
4
4
  import { parse } from 'wellknown';
@@ -28,77 +28,6 @@ const MapView: React.FC<MapViewProps> = ({
28
28
  const routeLayerRef = useRef<L.LayerGroup | null>(null);
29
29
  const clickMarkerRef = useRef<L.Marker | null>(null);
30
30
  const routePolylinesRef = useRef<L.Polyline[]>([]);
31
- const [ipLocation, setIpLocation] = useState<{ lat: number; lng: number } | null>(null);
32
-
33
- // Fonction pour obtenir la localisation par IP
34
- const getLocationByIP = async (): Promise<{ lat: number; lng: number } | null> => {
35
- try {
36
- const response = await fetch('https://ipapi.co/json/');
37
- const data = await response.json();
38
-
39
- if (data.latitude && data.longitude) {
40
- return {
41
- lat: data.latitude,
42
- lng: data.longitude
43
- };
44
- }
45
- return null;
46
- } catch (error) {
47
- console.error('Erreur de géolocalisation par IP:', error);
48
- return null;
49
- }
50
- };
51
-
52
- // Fonction pour obtenir la localisation par le navigateur
53
- const getBrowserLocation = (): Promise<{ lat: number; lng: number }> => {
54
- return new Promise((resolve, reject) => {
55
- if (!navigator.geolocation) {
56
- reject(new Error('Géolocalisation non supportée'));
57
- return;
58
- }
59
-
60
- navigator.geolocation.getCurrentPosition(
61
- (position) => {
62
- resolve({
63
- lat: position.coords.latitude,
64
- lng: position.coords.longitude
65
- });
66
- },
67
- (error) => {
68
- reject(error);
69
- },
70
- {
71
- enableHighAccuracy: true,
72
- timeout: 10000,
73
- maximumAge: 60000
74
- }
75
- );
76
- });
77
- };
78
-
79
- // Effet pour la géolocalisation au démarrage
80
- useEffect(() => {
81
- const initializeLocation = async () => {
82
- try {
83
- // Essayer d'abord la géolocalisation du navigateur
84
- const browserLocation = await getBrowserLocation();
85
- setIpLocation(browserLocation);
86
- } catch (browserError) {
87
- console.log('Géolocalisation navigateur échouée, tentative par IP...', browserError);
88
-
89
- // Fallback sur la géolocalisation par IP
90
- const ipLocation = await getLocationByIP();
91
- if (ipLocation) {
92
- setIpLocation(ipLocation);
93
- } else {
94
- // Fallback final sur une position par défaut (centre du monde)
95
- setIpLocation({ lat: 20, lng: 0 });
96
- }
97
- }
98
- };
99
-
100
- initializeLocation();
101
- }, []);
102
31
 
103
32
  const parseWKTLineString = (wkt: string): [number, number][] => {
104
33
  try {
@@ -123,20 +52,18 @@ const MapView: React.FC<MapViewProps> = ({
123
52
 
124
53
  useEffect(() => {
125
54
  if (mapContainerRef.current && !mapRef.current) {
126
- // Position par défaut centrée sur le monde, sera mise à jour par la géolocalisation
127
- const defaultCenter = ipLocation || { lat: 20, lng: 0 };
128
-
129
55
  mapRef.current = L.map(mapContainerRef.current, {
130
- center: [defaultCenter.lat, defaultCenter.lng],
131
- zoom: 12,
132
- minZoom: 2, // Zoom minimal réduit pour voir le monde entier
133
- maxZoom: 18, // Zoom maximal augmenté pour plus de détails
134
- // Suppression des limites de la carte
56
+ center: [7.365, 12.3], // Centre approximatif du Cameroun
57
+ zoom: 7, // Zoom ajusté pour voir l'ensemble du Cameroun
58
+ minZoom: 6,
59
+ maxZoom: 16,
60
+ maxBounds: [[1.65, 8.4], [13.08, 16.2]], // Limites pour le Cameroun
61
+ maxBoundsViscosity: 1.0,
135
62
  });
136
63
 
137
64
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
138
65
  attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
139
- maxZoom: 18,
66
+ maxZoom: 16,
140
67
  }).addTo(mapRef.current);
141
68
 
142
69
  L.Icon.Default.mergeOptions({
@@ -164,41 +91,46 @@ const MapView: React.FC<MapViewProps> = ({
164
91
  });
165
92
  }
166
93
 
167
- // Mettre à jour le centre de la carte quand la localisation par IP est disponible
168
- if (mapRef.current && ipLocation && !userLocation && !searchedPlace && !routes) {
169
- mapRef.current.setView([ipLocation.lat, ipLocation.lng], 12, { animate: true });
170
-
171
- // Ajouter un marqueur pour la position détectée
172
- if (!markerRef.current) {
173
- markerRef.current = L.marker([ipLocation.lat, ipLocation.lng])
174
- .addTo(mapRef.current)
175
- .bindPopup(`<b>Votre position approximative</b><br>Détectée par IP<br>Lat: ${ipLocation.lat.toFixed(6)}<br>Lng: ${ipLocation.lng.toFixed(6)}`)
176
- .openPopup();
177
- }
178
- }
179
-
180
94
  return () => {
181
95
  if (mapRef.current) {
182
96
  mapRef.current.remove();
183
97
  mapRef.current = null;
184
98
  }
185
99
  };
186
- }, [apiClient, ipLocation]);
100
+ }, [apiClient]);
187
101
 
188
102
  useEffect(() => {
189
103
  if (!mapRef.current) return;
190
104
 
191
- if (routeLayerRef.current) routeLayerRef.current.clearLayers();
192
- if (markerRef.current) markerRef.current.remove();
193
- if (clickMarkerRef.current) clickMarkerRef.current.remove();
105
+ // Nettoyer les couches précédentes
106
+ if (routeLayerRef.current) {
107
+ routeLayerRef.current.clearLayers();
108
+ }
109
+ if (markerRef.current) {
110
+ markerRef.current.remove();
111
+ markerRef.current = null;
112
+ }
113
+ if (clickMarkerRef.current) {
114
+ clickMarkerRef.current.remove();
115
+ clickMarkerRef.current = null;
116
+ }
117
+
194
118
  routePolylinesRef.current = [];
195
119
 
120
+ // Fonction pour centrer la carte sur un point avec un marqueur
196
121
  const centerOnPoint = async (lat: number, lng: number, placeName: string, zoom: number = 16) => {
197
122
  let displayName = placeName;
198
123
  if (placeName === 'Votre position') {
199
124
  const closestPlace = await apiClient.findClosestPlace(lat, lng);
200
125
  displayName = closestPlace?.name || placeName;
201
126
  }
127
+
128
+ // Supprimer l'ancien marqueur s'il existe
129
+ if (markerRef.current) {
130
+ markerRef.current.remove();
131
+ markerRef.current = null;
132
+ }
133
+
202
134
  mapRef.current!.setView([lat, lng], zoom, { animate: true });
203
135
  markerRef.current = L.marker([lat, lng])
204
136
  .addTo(mapRef.current!)
@@ -207,6 +139,7 @@ const MapView: React.FC<MapViewProps> = ({
207
139
  };
208
140
 
209
141
  if (routes && routes.length > 0) {
142
+ // Gérer les itinéraires
210
143
  let allCoordinates: [number, number][] = [];
211
144
  routes.forEach((route, index) => {
212
145
  const coordinates: [number, number][] = [];
@@ -276,14 +209,10 @@ const MapView: React.FC<MapViewProps> = ({
276
209
  centerOnPoint(searchedPlace.coordinates.lat, searchedPlace.coordinates.lng, searchedPlace.name);
277
210
  } else if (userLocation) {
278
211
  centerOnPoint(userLocation.latitude, userLocation.longitude, 'Votre position');
279
- } else if (ipLocation) {
280
- // Centrer sur la position IP si aucune autre position n'est disponible
281
- centerOnPoint(ipLocation.lat, ipLocation.lng, 'Votre position approximative', 12);
282
212
  } else {
283
- // Position de fallback centrée sur le monde
284
- mapRef.current!.setView([20, 0], 2, { animate: true });
213
+ mapRef.current!.setView([7.365, 12.3], 7, { animate: true });
285
214
  }
286
- }, [apiClient, userLocation, searchedPlace, routes, selectedRouteIndex, setSelectedRouteIndex, ipLocation]);
215
+ }, [apiClient, userLocation, searchedPlace, routes, selectedRouteIndex, setSelectedRouteIndex]);
287
216
 
288
217
  return <div className="w-full h-screen" ref={mapContainerRef} />;
289
218
  };