Skip to content

Commit

Permalink
feat: add meshes option on map
Browse files Browse the repository at this point in the history
  • Loading branch information
Jules Jean-Louis authored and edelclaux committed Oct 17, 2024
1 parent 5c3e6bc commit 2ba1aea
Show file tree
Hide file tree
Showing 3 changed files with 243 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
<pnx-geojson
[geojson]="observations"
[zoomOnFirstTime]="true"
[style]="styleTabGeoJson"
></pnx-geojson>
</pnx-map>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
::ng-deep .leaflet-tooltip-pane .number-obs {
color: rgb(0, 0, 0);
/* font-weight: bold; */
background: transparent;
border: 0;
box-shadow: none;
/* font-size:2; */
}
::ng-deep .tab-geographic-overview {
background-color: rgba(255, 255, 255, 0.8);
}
::ng-deep .tab-geographic-overview .custom-control-label {
margin: 0.2rem;
}
::ng-deep .tab-geographic-overview .custom-control-label::before {
top: 0.05rem;
}
::ng-deep .tab-geographic-overview .custom-control-label::after {
top: calc(0.05rem + 2px);
}
::ng-deep .legend {
line-height: 10px;
font-size: 14px;
color: #555;
background-color: white;
opacity: 0.7;
padding: 5px;
border-radius: 4px;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
}
::ng-deep .legend i {
width: 18px;
height: 18px;
float: left;
margin-right: 8px;
}
::ng-deep .legend:hover {
opacity: 1;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ import { Taxon } from '@geonature_common/form/taxonomy/taxonomy.component';
import { SyntheseDataService } from '@geonature_common/form/synthese-form/synthese-data.service';
import { FeatureCollection } from 'geojson';
import { TaxonSheetService } from '../taxon-sheet.service';
import { ConfigService } from '@geonature/services/config.service';
import * as L from 'leaflet';
import { SyntheseFormService } from '@geonature_common/form/synthese-form/synthese-form.service';
import { TranslateService } from '@ngx-translate/core';
import { MapService } from '@geonature_common/map/map.service';

interface MapAreasStyle {
color: string;
weight: number;
fillOpacity: number;
fillColor?: string;
}

@Component({
standalone: true,
Expand All @@ -16,29 +28,208 @@ import { TaxonSheetService } from '../taxon-sheet.service';
})
export class TabGeographicOverviewComponent implements OnInit {
observations: FeatureCollection | null = null;
areasEnable: boolean;
areasLegend: any;
private areasLabelSwitchBtn;
public featureGroup: any;
styleTabGeoJson: {};

mapAreasStyle: MapAreasStyle = {
color: '#FFFFFF',
weight: 0.4,
fillOpacity: 0.8,
};

mapAreasStyleActive: MapAreasStyle = {
color: '#FFFFFF',
weight: 0.4,
fillOpacity: 0,
};

constructor(
private _syntheseDataService: SyntheseDataService,
private _tss: TaxonSheetService,
public mapListService: MapListService
) {}
public mapListService: MapListService,
public config: ConfigService,
public formService: SyntheseFormService,
public translateService: TranslateService,
private _ms: MapService
) {
this.areasEnable =
this.config.SYNTHESE.AREA_AGGREGATION_ENABLED &&
this.config.SYNTHESE.AREA_AGGREGATION_BY_DEFAULT;
this.featureGroup = new L.FeatureGroup();
}

ngOnInit() {
this._tss.taxon.subscribe((taxon: Taxon | null) => {
if (!taxon) {
this.observations = null;
return;
}
this._syntheseDataService
.getSyntheseData(
{
cd_ref: [taxon.cd_ref],
},
{}
)
.subscribe((data) => {
// Store geojson
this.observations = data;
const format = this.areasEnable ? 'grouped_geom_by_areas' : 'grouped_geom';
this.updateTabGeographic(taxon, format);
});
this.initializeFormWithMapParams();
}

updateTabGeographic(taxon: Taxon, format: string) {
this._syntheseDataService
.getSyntheseData(
{
cd_ref: [taxon.cd_ref],
},
{ format }
)
.subscribe((data) => {
this.observations = data;

this.styleTabGeoJson = undefined;

const map = this._ms.getMap();

map.eachLayer((layer) => {
if (!(layer instanceof L.TileLayer)) {
map.removeLayer(layer);
}
});

if (this.observations && this.areasEnable) {
L.geoJSON(this.observations, {
onEachFeature: (feature, layer) => {
const observations = feature.properties.observations;
if (observations && observations.length > 0) {
const obsCount = observations.length;
this.setAreasStyle(layer as L.Path, obsCount);
}
},
}).addTo(map);
}
});
}

private initializeFormWithMapParams() {
this.formService.searchForm.patchValue({
format: this.areasEnable ? 'grouped_geom_by_areas' : 'grouped_geom',
});
}

ngAfterViewInit() {
this.addAreasButton();
if (this.areasEnable) {
this.addAreasLegend();
}
}

addAreasButton() {
const LayerControl = L.Control.extend({
options: {
position: 'topright',
},
onAdd: (map) => {
let switchBtnContainer = L.DomUtil.create(
'div',
'leaflet-bar custom-control custom-switch leaflet-control-custom tab-geographic-overview'
);

let switchBtn = L.DomUtil.create('input', 'custom-control-input', switchBtnContainer);
switchBtn.id = 'toggle-areas-btn';
switchBtn.type = 'checkbox';
switchBtn.checked = this.config.SYNTHESE.AREA_AGGREGATION_BY_DEFAULT;

switchBtn.onclick = () => {
this.areasEnable = switchBtn.checked;
const format = switchBtn.checked ? 'grouped_geom_by_areas' : 'grouped_geom';

this._tss.taxon.subscribe((taxon: Taxon | null) => {
if (taxon) {
this.updateTabGeographic(taxon, format);
}
});

if (this.areasEnable) {
this.addAreasLegend();
} else {
this.removeAreasLegend();
}
};

this.areasLabelSwitchBtn = L.DomUtil.create(
'label',
'custom-control-label',
switchBtnContainer
);
this.areasLabelSwitchBtn.setAttribute('for', 'toggle-areas-btn');
this.areasLabelSwitchBtn.innerText = this.translateService.instant(
'Synthese.Map.AreasToggleBtn'
);

return switchBtnContainer;
},
});

const map = this._ms.getMap();
map.addControl(new LayerControl());
}

private addAreasLegend() {
if (this.areasLegend) return;
this.areasLegend = new (L.Control.extend({
options: { position: 'bottomright' },
}))();

this.areasLegend.onAdd = (map: L.Map): HTMLElement => {
let div: HTMLElement = L.DomUtil.create('div', 'info legend');
let grades: number[] = this.config['SYNTHESE']['AREA_AGGREGATION_LEGEND_CLASSES']
.map((legendClass: { min: number; color: string }) => legendClass.min)
.reverse();
let labels: string[] = ["<strong> Nombre <br> d'observations </strong> <br>"];

for (let i = 0; i < grades.length; i++) {
labels.push(
'<i style="background:' +
this.getColor(grades[i] + 1) +
'"></i> ' +
grades[i] +
(grades[i + 1] ? '&ndash;' + grades[i + 1] + '<br>' : '+')
);
}
div.innerHTML = labels.join('<br>');

return div;
};

const map = this._ms.getMap();
this.areasLegend.addTo(map);
}

private removeAreasLegend() {
if (this.areasLegend) {
const map = this._ms.getMap();
map.removeControl(this.areasLegend);
this.areasLegend = null;
}
}

private setAreasStyle(layer: L.Path, obsNbr: number) {
this.mapAreasStyle['fillColor'] = this.getColor(obsNbr);
layer.setStyle(this.mapAreasStyle);
delete this.mapAreasStyle['fillColor'];
this.styleTabGeoJson = this.mapAreasStyleActive;
}

private getColor(obsNbr: number) {
let classesNbr = this.config['SYNTHESE']['AREA_AGGREGATION_LEGEND_CLASSES'].length;
let lastIndex = classesNbr - 1;
for (let i = 0; i < classesNbr; i++) {
let legendClass = this.config['SYNTHESE']['AREA_AGGREGATION_LEGEND_CLASSES'][i];
if (i != lastIndex) {
if (obsNbr > legendClass.min) {
return legendClass.color;
}
} else {
return legendClass.color;
}
}
}
}

0 comments on commit 2ba1aea

Please sign in to comment.