Карта работает правильно, но синие линии сетки (границы плиток/швы проекций) появляются только при увеличении или уменьшении масштаба после рисования фигуры.
Линии мигают во время масштабирования и выглядят следующим образом: Границы плиток отладки Google Maps.
Важные наблюдения:
- Линии сетки не появляются при начальной загрузке
- Они начинают появляться только после рисования многоугольников/прямоугольников/кругов
- Удаление фигур нет всегда удаляйте сетку
- Проблема возникает только при увеличении/уменьшении масштаба
Я попробовал следующее, ничего не решило проблему:
- Удаление MapId
- Отключение пользовательского интерфейса и элементов управления по умолчанию
- Изменение обработки жестов
- Принудительный растровый режим
- Удаление DrawingManager
- Изменения CSS/zIndex
Код: Выделить всё
{/* Drawing polygons / rectangles / circles triggers the issue */}Код: Выделить всё
useEffect(() => { if (!map || !drawingLib) return; const manager = new drawingLib.DrawingManager({ map, // drawingMode: null, // drawingControl: true, drawingControlOptions: { position: ControlPosition.TOP_RIGHT, drawingModes: [ drawingLib.OverlayType.POLYGON, drawingLib.OverlayType.RECTANGLE, drawingLib.OverlayType.CIRCLE, ], }, polygonOptions: { fillColor: '#3388ff', fillOpacity: 0.2, strokeColor: '#3388ff', strokeWeight: 3, editable: false, draggable: false, clickable: true, }, rectangleOptions: { fillColor: '#3388ff', fillOpacity: 0.2, strokeColor: '#3388ff', strokeWeight: 3, editable: false, draggable: false, clickable: true, }, circleOptions: { fillColor: '#3388ff', fillOpacity: 0.2, strokeColor: '#3388ff', strokeWeight: 3, editable: false, draggable: false, clickable: true, }, }); setDrawingManager(manager); return () => { manager.setMap(null); }; }, [map, drawingLib]); // 2. Handle Shape Creation useEffect(() => { if (!drawingManager) return; const listener = window.google.maps.event.addListener( drawingManager, 'overlaycomplete', (event) => { const overlay = event.overlay; const type = event.type; const id = Date.now() + Math.random(); let coords; if (type === 'circle') { coords = { center: { lat: overlay.getCenter().lat(), lng: overlay.getCenter().lng() }, radius: overlay.getRadius(), }; } else if (type === 'rectangle') { const bounds = overlay.getBounds(); const ne = bounds.getNorthEast(); const sw = bounds.getSouthWest(); coords = [ { lat: ne.lat(), lng: sw.lng() }, { lat: ne.lat(), lng: ne.lng() }, { lat: sw.lat(), lng: ne.lng() }, { lat: sw.lat(), lng: sw.lng() }, ]; } else { // Polygon const path = overlay.getPath().getArray(); coords = path.map((p) => ({ lat: p.lat(), lng: p.lng() })); } const newShape = { id, type: type.toLowerCase(), coords, [labelField.key]: '', }; // Clear the drawing overlay immediately (we replace it with a managed one via state) overlay.setMap(null); drawingManager.setDrawingMode(null); onShapeCreated(newShape); onShapeSelectedForEdit(newShape); }, ); return () => { window.google.maps.event.removeListener(listener); }; }, [drawingManager, onShapeCreated, onShapeSelectedForEdit, labelField.key]); // 3. Sync State -> Google Maps Overlays useEffect(() => { if (!map || !drawingLib) return; // Remove overlays not in state overlaysRef.current.forEach((data, id) => { const exists = shapes.find((s) => s.id === id); if (!exists) { data.overlay.setMap(null); if (data.labelMarker) data.labelMarker.setMap(null); window.google.maps.event.clearInstanceListeners(data.overlay); overlaysRef.current.delete(id); } }); // Add or Update overlays shapes.forEach((shape) => { let data = overlaysRef.current.get(shape.id); if (!data) { let overlay; const opts = { map, fillColor: '#3388ff', fillOpacity: 0.2, strokeColor: '#3388ff', strokeWeight: 3, editable: false, draggable: false, clickable: true, zIndex: 1, geodesic: false, }; if (shape.type === 'circle') { overlay = new window.google.maps.Circle({ ...opts, center: shape.coords.center, radius: shape.coords.radius, }); } else if (shape.type === 'rectangle') { const bounds = new window.google.maps.LatLngBounds(); shape.coords.forEach((c) => bounds.extend(c)); overlay = new window.google.maps.Rectangle({ ...opts, bounds }); } else { overlay = new window.google.maps.Polygon({ ...opts, paths: shape.coords, }); } // Click Listener overlay.addListener('click', (e) => { if (e.stop) e.stop(); onShapeClick({ id: shape.id }); }); // Edit Listeners const triggerEdit = () => { let newCoords; if (shape.type === 'circle') { newCoords = { center: { lat: overlay.getCenter().lat(), lng: overlay.getCenter().lng() }, radius: overlay.getRadius(), }; } else if (shape.type === 'rectangle') { const b = overlay.getBounds(); const ne = b.getNorthEast(); const sw = b.getSouthWest(); newCoords = [ { lat: ne.lat(), lng: sw.lng() }, { lat: ne.lat(), lng: ne.lng() }, { lat: sw.lat(), lng: ne.lng() }, { lat: sw.lat(), lng: sw.lng() }, ]; } else { const path = overlay.getPath().getArray(); newCoords = path.map((p) => ({ lat: p.lat(), lng: p.lng() })); } onShapeEdited([{ id: shape.id, coords: newCoords }]); }; if (shape.type === 'circle') { overlay.addListener('radius_changed', triggerEdit); overlay.addListener('center_changed', triggerEdit); } else if (shape.type === 'rectangle') { overlay.addListener('bounds_changed', triggerEdit); } else { const path = overlay.getPath(); ['set_at', 'insert_at', 'remove_at'].forEach((evt) => { window.google.maps.event.addListener(path, evt, triggerEdit); }); } // Label Marker const labelMarker = new window.google.maps.Marker({ map, position: getCenter(shape, overlay), label: { text: '', color: 'white', fontWeight: 'bold', className: 'map-label-text', }, icon: { path: window.google.maps.SymbolPath.CIRCLE, scale: 0, }, zIndex: 1000, }); data = { overlay, labelMarker }; overlaysRef.current.set(shape.id, data); } // Sync Label Content const labelText = shape[labelField.key]; if (labelText) { data.labelMarker.setLabel({ text: labelText, color: '#FFFFFF', fontWeight: 'bold', fontSize: '14px', }); data.labelMarker.setPosition(getCenter(shape, data.overlay)); data.labelMarker.setMap(map); } else { data.labelMarker.setMap(null); } }); }, [map, shapes, labelField.key, drawingLib, onShapeClick, onShapeEdited]); // 4. Handle Selection Visuals useEffect(() => { overlaysRef.current.forEach((data, id) => { const isSelected = selectedShape && id === selectedShape.id; const { overlay } = data; if (isSelected) { overlay.setOptions({ fillColor: '#ff0000', strokeColor: '#ff0000', strokeWeight: 4, fillOpacity: 0.3, editable: true, draggable: false, }); } else { overlay.setOptions({ fillColor: '#3388ff', strokeColor: '#3388ff', strokeWeight: 3, fillOpacity: 0.2, editable: false, draggable: false, }); } }); }, [selectedShape]);
Подробнее здесь: https://stackoverflow.com/questions/798 ... pes-in-vis