I’m working on a Laravel project where I need to draw polygons on a Mapbox GL JS map, save the coordinates to the database, and then load and display those polygons correctly when editing the records. However, I’m encountering issues where the polygons do not display correctly on the map when the page loads.
Here’s a summary of what I’m trying to achieve and the issues I’m facing:
Polygon Display Issue: Even though the polygon coordinates are stored in the database correctly, they are not being displayed on the map when the page loads.
My Setup
Laravel Version: 10.x
Mapbox GL JS Version: 3.5.1
Leaflet Draw Plugin Version: 1.0.4
My db coordinates ""\"[[[28.945355184937,41.017461342255416],[28.94629932251067,40.996087049591665],[28.985953100586244,41.01661945584914],[28.959774740601034,41.02056975269869],[28.945355184937,41.017461342255416]]]\"""
Model
protected $casts = [
'product_groups' => 'array',
'status' => 'boolean',
'polygon_coordinates' => 'array', // polygon_coordinates alanının json olduğunu belirtiyoruz
];
.
Controller edit
public function edit($id)
{
$zoneCoverage = ZoneCoverage::findOrFail($id);
$salesRegions = SalesRegion::all();
$polygonCoordinates = $zoneCoverage->polygon_coordinates ? json_encode($zoneCoverage->polygon_coordinates) : null;
return view('plugins/demo::zone_coverage.form', compact('zoneCoverage', 'salesRegions', 'polygonCoordinates'));
}
.
@extends(BaseHelper::getAdminMasterLayoutTemplate())
@section('content')
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.draw.css" />
<div class="container">
<div class="row">
<div class="col-md-12">
<h1>{{ isset($zoneCoverage) ? __('Edit Zone Coverage') : __('New Zone Coverage') }}</h1>
<form action="{{ isset($zoneCoverage) ? route('sales.zone_coverage.editzone_coverage.update', $zoneCoverage->id) : route('sales.zone_coverage.createzone_coverage.store') }}" method="POST">
@csrf
@if(isset($zoneCoverage))
@method('PUT')
@endif
<div class="form-group">
<label for="sales_regions_id">Sales Region</label>
<select name="sale_area_id" id="sale_area_id" class="form-control">
<option value="">{{ __('Select') }}</option>
@foreach($salesRegions as $region)
<option value="{{ $region->id }}" {{ isset($zoneCoverage) && $zoneCoverage->sale_area_id == $region->id ? 'selected' : '' }} data-scope="{{ $region->region_scope }}">{{ $region->name }}</option>
@endforeach
</select>
</div>
<div id="geographical_data_fields" style="display: none;">
<div class="form-group">
<label for="il">City</label>
<input type="text" name="city" id="city" class="form-control" value="{{ old('il', $zoneCoverage->city ?? '') }}">
</div>
<div class="form-group">
<label for="ilce">District</label>
<input type="text" name="district" id="district" class="form-control" value="{{ old('ilce', $zoneCoverage->district ?? '') }}">
</div>
<div class="form-group">
<label for="mahalle">Street</label>
<input type="text" name="street" id="street" class="form-control" value="{{ old('mahalle', $zoneCoverage->street ?? '') }}">
</div>
</div>
<div id="google_maps_polygon_fields" style="display: none;">
<div id="map" style="height: 400px;"></div>
</div>
<button type="submit" class="btn btn-success">{{ isset($zoneCoverage) ? __('Update') : __('Save') }}</button>
<a href="{{ route('sales.zone_coverage.index') }}" class="btn btn-danger">{{ __('Cancel') }}</a>
</form>
</div>
</div>
</div>
<script src="https://unpkg.com/@turf/turf@6/turf.min.js"></script>
<script src="https://api.mapbox.com/mapbox-gl-js/v3.5.1/mapbox-gl.js"></script>
<script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.4.3/mapbox-gl-draw.js"></script>
<link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/v3.5.1/mapbox-gl.css" />
<link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.4.3/mapbox-gl-draw.css" />
<script>
document.addEventListener('DOMContentLoaded', function () {
const saleAreaField = document.getElementById('sale_area_id');
const geographicalDataFields = document.getElementById('geographical_data_fields');
const googleMapsPolygonFields = document.getElementById('google_maps_polygon_fields');
function handleRegionScopeChange(regionScope) {
if (regionScope === 'geographical_data') {
geographicalDataFields.style.display = 'block';
googleMapsPolygonFields.style.display = 'none';
} else if (regionScope === 'google_maps_polygon') {
geographicalDataFields.style.display = 'none';
googleMapsPolygonFields.style.display = 'block';
initMap();
} else {
geographicalDataFields.style.display = 'none';
googleMapsPolygonFields.style.display = 'none';
}
}
saleAreaField.addEventListener('change', function () {
const selectedOption = this.options[this.selectedIndex];
const regionScope = selectedOption.getAttribute('data-scope');
handleRegionScopeChange(regionScope);
});
// Initial load
if (saleAreaField.value) {
const selectedOption = saleAreaField.options[saleAreaField.selectedIndex];
const regionScope = selectedOption.getAttribute('data-scope');
handleRegionScopeChange(regionScope);
}
function initMap() {
mapboxgl.accessToken = 'pk.eyJ1Ijoia290aTQyIiwiYSI6ImNsdnVudDFyOTE2N3Myam53eTZpcGxkOG8ifQ.IuuMRUS4czPqGuYWnpJ6Ww';
const map = new mapboxgl.Map({
container: 'map', // container ID
style: 'mapbox://styles/mapbox/satellite-v9', // style URL
center: [28.9784, 41.0082], // starting position [lng, lat]
zoom: 13 // starting zoom
});
const draw = new MapboxDraw({
displayControlsDefault: false,
controls: {
polygon: true,
trash: true
},
defaultMode: 'draw_polygon'
});
map.addControl(draw);
map.on('draw.create', updateArea);
map.on('draw.delete', updateArea);
map.on('draw.update', updateArea);
function updateArea(e) {
const data = draw.getAll();
const answer = document.getElementById('calculated-area');
if (data.features.length > 0) {
const area = turf.area(data);
const rounded_area = Math.round(area * 100) / 100;
answer.innerHTML = `<p><strong>${rounded_area}</strong></p><p>square meters</p>`;
document.getElementById('polygon_coordinates').value = JSON.stringify(data.features[0].geometry.coordinates);
} else {
answer.innerHTML = '';
if (e.type !== 'draw.delete')
alert('Click the map to draw a polygon.');
}
}
@if(isset($polygonCoordinates))
const polygonCoordinates = {!! $polygonCoordinates !!};
const polygon = {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": polygonCoordinates
}
};
draw.add(polygon);
map.fitBounds(turf.bbox(polygon), { padding: 20 });
@endif
setTimeout(function() {
map.resize();
}, 500);
}
});
</script>
@endsection
My Issues:
Polygon Display Issue: The polygon coordinates are stored in the database correctly, but they do not display on the map when the page loads.
Questions:
How can I correctly load and display the saved polygon coordinates on the map when the page loads?
Any help or guidance would be greatly appreciated. Thank you!
My code was actually working correctly. It was exploding because I saved it as json_encode when saving to DB. When I fixed it, the problem disappeared.