Files
fiscad-dgi-front/src/app/office/cartographie/cartographie-fiscale-tfu/cartographie-fiscale-tfu.component.ts
2026-04-01 17:15:17 +01:00

1089 lines
35 KiB
TypeScript

import { Component, OnInit, ViewContainerRef, ViewEncapsulation } from '@angular/core';
import Map from 'ol/Map';
import View from 'ol/View';
import LayerGroup from 'ol/layer/Group';
import LayerTile from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import LayerSwitcher, {
BaseLayerOptions,
GroupLayerOptions,
} from 'ol-layerswitcher';
import MousePosition from 'ol/control/MousePosition';
import FullScreen from 'ol/control/FullScreen';
import ZoomToExtent from 'ol/control/ZoomToExtent';
import ImageLayer from 'ol/layer/Image';
import GeoJSON from 'ol/format/GeoJSON';
import Zoom from 'ol/control/Zoom';
import ZoomSlider from 'ol/control/ZoomSlider';
import { FormBuilder, FormGroup } from '@angular/forms';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import Feature from 'ol/Feature';
import Icon from 'ol/style/Icon';
import Point from 'ol/geom/Point';
import {
Circle as CircleStyle,
Fill,
RegularShape,
Stroke,
Style,
Text,
} from 'ol/style';
import { Draw, Modify, MouseWheelZoom, defaults as defaultInteractions, DoubleClickZoom } from 'ol/interaction';
import LineString from 'ol/geom/LineString';
import { getArea, getLength } from 'ol/sphere';
import { fromLonLat, transform } from 'ol/proj';
import { Router } from '@angular/router';
import { circular } from 'ol/geom/Polygon';
import { take } from 'rxjs';
import { CrudService } from 'src/app/crud.service';
import { NzModalService } from 'ng-zorro-antd/modal';
import { NzMessageService } from 'ng-zorro-antd/message';
import { GlobalService } from 'src/app/global.service';
import { HttpErrorResponse } from '@angular/common/http';
import { NzTreeNodeOptions } from 'ng-zorro-antd/tree';
import { TokenStorage } from 'src/app/utilitaire/token-storage';
import { JwtHelperService } from '@auth0/angular-jwt';
declare var $: any;
declare var NioApp: any;
/* déclaration pour outils de mesure */
const style = new Style({
fill: new Fill({
color: 'rgba(255, 255, 255, 0.2)',
}),
stroke: new Stroke({
color: 'rgba(0, 0, 0, 0.5)',
lineDash: [10, 10],
width: 2,
}),
image: new CircleStyle({
radius: 5,
stroke: new Stroke({
color: 'rgba(0, 0, 0, 0.7)',
}),
fill: new Fill({
color: 'rgba(255, 255, 255, 0.2)',
}),
}),
});
const labelStyle = new Style({
text: new Text({
font: '14px Calibri,sans-serif',
fill: new Fill({
color: 'rgba(255, 255, 255, 1)',
}),
backgroundFill: new Fill({
color: 'rgba(26, 88, 144, 1)',
}),
padding: [3, 3, 3, 3],
textBaseline: 'bottom',
offsetY: -15,
}),
image: new RegularShape({
radius: 8,
points: 3,
angle: Math.PI,
displacement: [0, 10],
fill: new Fill({
//color: 'rgba(0, 0, 0, 0.7)',
color: 'rgba(26, 88, 144, 1)',
}),
}),
});
const tipStyle = new Style({
text: new Text({
font: '12px Calibri,sans-serif',
fill: new Fill({
color: 'rgba(255, 255, 255, 1)',
}),
backgroundFill: new Fill({
color: 'rgba(0, 0, 0, 0.4)',
}),
padding: [2, 2, 2, 2],
textAlign: 'left',
offsetX: 15,
}),
});
const modifyStyle = new Style({
image: new CircleStyle({
radius: 5,
stroke: new Stroke({
color: 'rgba(0, 0, 0, 0.7)',
}),
fill: new Fill({
color: 'rgba(0, 0, 0, 0.4)',
}),
}),
text: new Text({
text: 'Drag to modify',
font: '12px Calibri,sans-serif',
fill: new Fill({
color: 'rgba(255, 255, 255, 1)',
}),
backgroundFill: new Fill({
color: 'rgba(0, 0, 0, 0.7)',
}),
padding: [2, 2, 2, 2],
textAlign: 'left',
offsetX: 15,
}),
});
const segmentStyle = new Style({
text: new Text({
font: '12px Calibri,sans-serif',
fill: new Fill({
color: 'rgba(255, 255, 255, 1)',
}),
backgroundFill: new Fill({
color: 'rgba(0, 0, 0, 0.4)',
}),
padding: [2, 2, 2, 2],
textBaseline: 'bottom',
offsetY: -12,
}),
image: new RegularShape({
radius: 6,
points: 3,
angle: Math.PI,
displacement: [0, 8],
fill: new Fill({
color: 'rgba(0, 0, 0, 0.4)',
}),
}),
});
const segmentStyles = [segmentStyle];
const formatLength = function (line: any) {
const length = getLength(line, { projection: 'EPSG:4326' });
let output;
if (length > 100) {
output = Math.round((length / 1000) * 100) / 100 + ' km';
} else {
output = Math.round(length * 100) / 100 + ' m';
}
return output;
};
const formatArea = function (polygon: any) {
const area = getArea(polygon, { projection: 'EPSG:4326' });
let output;
if (area > 10000) {
output = Math.round((area / 1000000) * 100) / 100 + ' km\xB2';
} else {
output = Math.round(area * 100) / 100 + ' m\xB2';
}
return output;
};
const sourceDrawOutil = new VectorSource();
const modify = new Modify({ source: sourceDrawOutil, style: modifyStyle });
let tipPoint: any;
function styleFunction(feature: any, segments: any, drawType: any, tip: any) {
const styles = [style];
const geometry = feature.getGeometry();
const type = geometry.getType();
let point, label, line;
if (!drawType || drawType === type) {
if (type === 'Polygon') {
point = geometry.getInteriorPoint();
label = formatArea(geometry);
line = new LineString(geometry.getCoordinates()[0]);
} else if (type === 'LineString') {
point = new Point(geometry.getLastCoordinate());
label = formatLength(geometry);
line = geometry;
}
}
if (segments && line) {
let count = 0;
line.forEachSegment(function (a: any, b: any) {
const segment = new LineString([a, b]);
//transform('EPSG:4326', 'EPSG:3413')
/*const aLbalel = transform(a, 'EPSG:4326', 'EPSG:3857');
const bLbalel = transform(b, 'EPSG:4326', 'EPSG:3857');
const segmentLabel = new LineString([aLbalel, bLbalel]);*/
const label = formatLength(segment);
if (segmentStyles.length - 1 < count) {
segmentStyles.push(segmentStyle.clone());
}
const segmentPoint = new Point(segment.getCoordinateAt(0.5));
segmentStyles[count].setGeometry(segmentPoint);
segmentStyles[count]?.getText()?.setText(label);
styles.push(segmentStyles[count]);
count++;
});
}
if (label) {
labelStyle.setGeometry(point);
labelStyle.getText()?.setText(label);
styles.push(labelStyle);
}
if (
tip &&
type === 'Point' &&
!modify.getOverlay()?.getSource()?.getFeatures().length
) {
tipPoint = geometry;
tipStyle.getText()?.setText(tip);
styles.push(tipStyle);
}
return styles;
}
@Component({
selector: 'app-cartographie-fiscale-tfu',
templateUrl: './cartographie-fiscale-tfu.component.html',
styleUrls: ['./cartographie-fiscale-tfu.component.css'],
encapsulation: ViewEncapsulation.None // ← ajouter cette ligne
})
export class CartographieFiscaleTfuComponent implements OnInit {
iconImagePosition = new Style({
image: new Icon({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: 'assets/static/images/marker-icon.png',
size: [25, 45], // [25, 45],
}),
});
styleDelimiterLayer = new Style({
stroke: new Stroke({
color: 'black',
width: 3,
}),
fill: new Fill({
color: 'transparent',
}),
});
baseOSM = new LayerTile({
title: 'OSM',
type: 'base',
visible: true,
source: new OSM(),
} as BaseLayerOptions);
baseMaps = new LayerGroup({
title: 'Base maps',
layers: [this.baseOSM],
} as GroupLayerOptions);
view = new View({
projection: 'EPSG:4326',
center: [2.315834, 9.307690],//[2.237783, 8.993058],
zoom: 7.2,
minZoom: 7.2,
/*extent: [
-1.3114703249183064, 5.3826768040185105, 8.825820324918308,
12.48591919598149,
],*/
});
map!: Map;
mouse_position = new MousePosition();
full_sc = new FullScreen({ label: 'F' });
zoom = new Zoom({ zoomInLabel: '+', zoomOutLabel: '-' });
slider = new ZoomSlider();
zoom_ex = new ZoomToExtent({
extent: [
-1.3114703249183064, 5.3826768040185105, 8.825820324918308,
12.48591919598149,
],
});
departementList: any[] = [];
communeList: any[] = [];
arrondissementList: any[] = [];
villageQuartierList: any[] = [];
parcelleList: any[] = [];
parcelleFilteredList: any[] = [];
parcelleSearchFilteredList: any[] = [];
filterForm!: FormGroup;
sourceDecoupage: VectorSource = new VectorSource();
vectorDecoupage: any;
sourceParcelle: VectorSource = new VectorSource();
vectorParcelle: any;
circleMarkerVector: any;
iconVectorLayer: any;
globalSearch = '';
coordinate1 = { longitude: null, latitude: null };
rayon = 0;
/* outils de dessins */
isDrawing = false;
sketch: any;
typeSelect: string = 'LineString';
showSegments: boolean = true;
clearPrevious: boolean = true;
vectorDrawOutil = new VectorLayer({
source: sourceDrawOutil,
style: (feature: any) => {
return styleFunction(
feature,
this.showSegments,
this.typeSelect,
'Click to start measuring'
);
},
zIndex: 7,
});
draw: any;
/* fin outils de dessins */
mapDataInfo: any = null;
batimentList: any[] = [];
uniteLogementList: any[] = [];
visibleMapData = false;
keyFilter: any = null;
activeTab: string = 'legende'; // ← ajouter ici
// ── Cartes pliables ───────────────────────────────────────────────────
collapsedCards: { [key: string]: boolean } = {
localisation: false, // false = déplié par défaut
propriete: false,
representant: false,
fiscal: false
};
activeInfoTab: string = 'batiment';
keyFliterList: any[] = [
{ couleur: '#333', code: 'ALL', libelle: 'Toutes les parcelles' },
{ couleur: '#94a3b8', code: 'NON_ENQUETE_NON_BATIE', libelle: 'Parcelles non enquêtées — Non bâties', batie: false, status: 'NON_ENQUETE' },
{ couleur: '#8b5cf6', code: 'NON_ENQUETE_BATIE', libelle: 'Parcelles non enquêtées — Bâties', batie: true, status: 'NON_ENQUETE' },
{ couleur: '#06b6d4', code: 'ENQUETE_NON_BATIE_AJOUR', libelle: 'Non bâties — À jour', batie: false, status: 'AJOUR' },
{ couleur: '#22c55e', code: 'ENQUETE_BATIE_AJOUR', libelle: 'Bâties — À jour', batie: true, status: 'AJOUR' },
{ couleur: '#f59e0b', code: 'ENQUETE_NON_BATIE_NON_AJOUR', libelle: 'Non bâties — Non à jour', batie: false, status: 'NON_AJOUR' },
{ couleur: '#f97316', code: 'ENQUETE_BATIE_NON_AJOUR', libelle: 'Bâties — Non à jour', batie: true, status: 'NON_AJOUR' },
{ couleur: '#ef4444', code: 'PARCELLE_NON_ENQUETER', libelle: 'Parcelles non enquêtées', status: 'NON_ENQUETE' },
{ couleur: '#ef4444', code: 'PARCELLE_ENDETTE', libelle: 'Parcelles endettées', status: 'NON_AJOUR' },
{ couleur: '#393542', code: 'PARCELLE_A_JOUR_DU_FISC', libelle: 'Parcelles à jour du fisc', status: 'AJOUR' },
];
commune: any;
nodes: NzTreeNodeOptions[] = [];
quartierSelected: any = null;
arbreUtilisateurCourant: any[] = [];
user: any = null;
// ── Filtre boîte flottante ────────────────────────────
filterBoxVisible = false;
filterApplied = false;
filterCritere = '';
filterValue = '';
filterQlotissement = '';
filterIlotLotissement = '';
filterPlotissement = '';
filterPersonneNom: string = '';
filterPersonnePrenom: string = '';
constructor(
private router: Router,
private fb: FormBuilder,
private crudService: CrudService,
private modal: NzModalService,
private message: NzMessageService,
private globalService: GlobalService,
private tokenStorage: TokenStorage,
) { }
ngOnInit(): void {
this.globalService.setLodingSuccess(false);
const token = this.tokenStorage.getToken() != null ? this.tokenStorage.getToken() : '';
const helper = new JwtHelperService();
const decodeToken = helper.decodeToken(token ? token : '');
this.user = decodeToken?.user;
if (this.user) {
this.crudService.getAll('secteur-decoupage/arbre/user-id/' + this.user?.id).subscribe(
(data: any) => {
this.arbreUtilisateurCourant = data.object ? data.object : [];
if (this.arbreUtilisateurCourant && this.arbreUtilisateurCourant.length > 0) {
this.constructionArbreUtilisateurs();
}
this.message.success(`Chargement des découpages de l'utilisateur ${this.user?.nom} réussi`);
},
(error: any) => {
this.message.error(`Chargement des découpages de l'utilisateur ${this.user?.nom} échoué`);
});
}
this.map = new Map({
target: 'map',
view: this.view,
interactions: defaultInteractions().getArray().filter(
(interaction: any) => !(interaction instanceof DoubleClickZoom) &&
!(interaction instanceof MouseWheelZoom) // ← ajouter cette ligne
),
});
this.map.addLayer(this.baseMaps);
this.map.addControl(this.mouse_position);
//this.map.addControl(this.overview);
this.map.addControl(this.full_sc);
this.map.addControl(this.zoom);
this.map.addControl(this.slider);
this.map.addControl(this.zoom_ex);
this.globalService.setLodingSuccess(false);
}
chargerParcelleListByQuartier(quartier: any): void {
if (quartier) {
console.log("data quartier ===> ", quartier);
this.message.loading('Chargement des parcelles en cours ...');
this.globalService.setLodingSuccess(true);
//this.crudService.getAll('parcelle-geom/by-quartier/' + quartier.code).subscribe(
this.crudService.getAll('parcelle-geom/by-quartier-id/' + quartier.quartierId).subscribe(
(data: any) => {
console.log('data parcelle ==>', data);
if (data.object) {
//dessiner les parcelles
this.parcelleList = data.object.filter((el: any) => el.ilot != null);
this.parcelleFilteredList = data.object.filter((el: any) => el.ilot != null);
this.parcelleSearchFilteredList = data.object.filter((el: any) => el.ilot != null);;
if (this.parcelleList && this.parcelleList.length > 0) {
if (this.parcelleList[0].longitude && this.parcelleList[0].latitude) {
this.map.getView().setCenter([this.parcelleList[0].longitude, this.parcelleList[0].latitude]);
this.map.getView().setZoom(17);
}
}
this.doMapCPS();
//}
}
this.message.remove();
this.globalService.setLodingSuccess(false);
},
(error: HttpErrorResponse) => {
this.message.create('error', `Erreur de connexion internet ou du système`);
this.globalService.setLodingSuccess(false);
this.message.remove();
}
);
}
}
doMapCPS(): void {
this.map.removeLayer(this.vectorParcelle);
if (this.parcelleFilteredList.length > 0 && this.map) {
this.globalService.setLodingSuccess(true);
this.sourceParcelle = new VectorSource({
features: new GeoJSON().readFeatures(
{
type: 'FeatureCollection',
name: 'Parcelle',
features: this.buildFeatureFormatData(this.parcelleFilteredList),
},
{ dataProjection: 'EPSG:32631', featureProjection: 'EPSG:4326' }
),
});
console.log(this.sourceParcelle);
this.vectorParcelle = new VectorLayer({
source: this.sourceParcelle,
zIndex: 6,
});
this.sourceParcelle
.getFeatures()
.forEach((feature: any, index: number) => {
feature.setStyle(this.getDynamiqueStyleParcelle(this.parcelleFilteredList[index]));
feature.setProperties({
parcelle: this.parcelleFilteredList[index],
});
});
this.map.addLayer(this.vectorParcelle);
this.message.remove();
this.globalService.setLodingSuccess(false);
//console.log('map must draw layer ===> ', this.sourceParcelle);
}
}
initMap(): void {
this.map.removeLayer(this.vectorDecoupage);
this.map.removeLayer(this.vectorParcelle);
this.map.removeLayer(this.iconVectorLayer);
this.map.removeLayer(this.circleMarkerVector);
this.map.getView().setCenter([2.237783, 8.993058]);
this.map.getView().setZoom(7.3);
}
onMouseEnter(): void {
console.log(this.globalSearch);
this.globalService.setLodingSuccess(true);
if (this.globalSearch != '' && this.globalSearch != undefined && this.parcelleList.length > 0) {
this.parcelleFilteredList = this.parcelleList.filter(
(element: any) => (element.ilot && element.ilot.toLowerCase().indexOf(this.globalSearch.toLowerCase()) > -1) ||
(element.p && element.p.toLowerCase().indexOf(this.globalSearch.toLowerCase()) > -1) ||
(element.nomEtPrenoms && element.nomEtPrenoms.toLowerCase().indexOf(this.globalSearch.toLowerCase()) > -1) ||
(element.q && element.q.toLowerCase().indexOf(this.globalSearch.toLowerCase()) > -1)
);
this.map.getView().setCenter([this.parcelleFilteredList[0].longitude, this.parcelleFilteredList[0].latitude]);
this.map.getView().setZoom(19);
this.doMapCPS();
} else {
this.parcelleFilteredList = this.parcelleList;
this.map.getView().setZoom(17);
this.doMapCPS();
}
this.globalService.setLodingSuccess(false);
}
compareFn = (o1: any, o2: any) => (o1 && o2 ? o1.code === o2.code : o1 === o2);
keyFilterAction(value: any): void {
console.log('keyFilterAction', value);
this.filterCritere = '';
this.filterValue = '';
this.filterQlotissement = '';
this.filterIlotLotissement = '';
this.filterPlotissement = '';
this.filterPersonneNom = ''; // ← ajouter
this.filterPersonnePrenom = ''; // ← ajouter
this.filterApplied = false;
this.globalService.setLodingSuccess(true);
this.parcelleFilteredList = [];
if (value && value?.code == 'ALL') {
this.parcelleFilteredList = this.parcelleList;
this.doMapCPS();
this.globalService.setLodingSuccess(false);
return;
}
if (value && (value?.code == 'PARCELLE_ENDETTE' || value?.code == 'PARCELLE_NON_ENQUETER' || value?.code == 'PARCELLE_A_JOUR_DU_FISC')) {
this.parcelleFilteredList = this.parcelleList.filter((element: any) => (element.statutParcelle == value.status));
this.doMapCPS();
this.globalService.setLodingSuccess(false);
return;
}
if (value && value?.code != 'ALL' && value?.code != 'PARCELLE_A_JOUR_DU_FISC' && value?.code != 'PARCELLE_ENDETTE' && value?.code != 'PARCELLE_NON_ENQUETER') {
this.parcelleFilteredList = this.parcelleList.filter((element: any) => (element.batie == value.batie && element.statutParcelle == value.status));
this.doMapCPS();
this.globalService.setLodingSuccess(false);
return;
}
console.log(' this.parcelleFilteredList ==>', this.parcelleFilteredList);
}
buildFeatureFormatData(dataList: any[]): any[] {
dataList.forEach((element) => {
Object.defineProperty(element, 'type', {
value: 'Feature',
writable: false,
});
//element.geometry.coordinates = element.geometry.coordinates = transform(element.geometry.coordinates, 'EPSG:3857', 'EPSG:4326');
});
console.log('dataList ==>', dataList);
return dataList;
}
positionActuelle(): void {
this.crudService.getPosition().then(
(res: any) => {
console.log('res', res);
this.coordinate1.longitude = res.lng;
this.coordinate1.latitude = res.lat;
},
(failure: any) => {
console.error(failure); //expected output: Oopsy...
}
);
}
resetSimulation(): void {
this.coordinate1.longitude = null;
this.coordinate1.latitude = null;
this.map.removeLayer(this.circleMarkerVector);
this.map.removeLayer(this.iconVectorLayer);
}
lancerSimulation(): void {
if (
this.coordinate1.longitude != null &&
this.coordinate1.latitude != null &&
this.rayon > 0
) {
this.map.removeLayer(this.circleMarkerVector);
this.map.removeLayer(this.iconVectorLayer);
const circleFeature = new Feature({
geometry: circular(
[this.coordinate1.longitude, this.coordinate1.latitude],
this.rayon
),
});
this.circleMarkerVector = new VectorLayer({
source: new VectorSource({
features: [circleFeature],
}),
});
circleFeature.setStyle(this.styleDelimiterLayer);
this.map.addLayer(this.circleMarkerVector);
this.circleMarkerVector.setZIndex(8);
this.makeIconeToLongLat(this.coordinate1.longitude, this.coordinate1.latitude);
const circleGeometry: any = circleFeature.getGeometry();
//const size = this.map.getSize();
this.view.fit(circleGeometry, { padding: [170, 50, 30, 150] });
} else {
this.message.create('error', 'Formulaire invalid !');
}
}
makeIconeToLongLat(long: any, lat: any): void {
const iconFeature = new Feature({
geometry: new Point([long, lat]),
});
iconFeature.setStyle(this.iconImagePosition);
const iconVectorSource = new VectorSource({
features: [iconFeature],
});
this.iconVectorLayer = new VectorLayer({
source: iconVectorSource,
});
this.map.addLayer(this.iconVectorLayer);
this.iconVectorLayer.setZIndex(1000);
}
getDynamiqueStyleParcelle(parcelle: any): Style {
const element = this.keyFliterList.find((e: any) => e.status == parcelle.statutParcelle && e.batie == parcelle.batie);
//console.log('element ===>', element);
return new Style({
stroke: new Stroke({ color: 'black', width: 1 }),
fill: new Fill({
color: element ? element.couleur : '#94a3b8',
//color: '#94a3b8',
}),
});
}
/* dessin de distance */
onChangeTypeSelectDrawing(): void {
this.map.removeInteraction(this.draw);
this.addInteraction();
}
onChangeShowSegmentDrawing(valueEvent: any): void {
this.showSegments = valueEvent;
console.log('this.showSegments', this.showSegments);
this.vectorDrawOutil.changed();
this.draw.getOverlay().changed();
}
showOutilsMeasure(): void {
this.isDrawing = true;
//this.vectorDrawOutil.setZIndex(7);
this.map.addLayer(this.vectorDrawOutil);
this.map.addInteraction(modify);
this.addInteraction();
}
hideOutilsMeasure(): void {
this.isDrawing = false;
//this.vectorDrawOutil.setZIndex(0);
sourceDrawOutil.clear();
this.draw.dispose();
//this.map.removeLayer(this.vectorDrawOutil);
this.map.removeInteraction(this.draw);
}
addInteraction(): void {
const drawType: any = this.typeSelect;
const activeTip =
'Click to continue drawing the ' +
(drawType === 'Polygon' ? 'polygon' : 'line');
const idleTip = 'Click to start measuring';
let tip = idleTip;
this.draw = new Draw({
source: sourceDrawOutil,
type: drawType,
style: (feature: any) => {
//console.log("this.showSegments", this.showSegments);
return styleFunction(feature, this.showSegments, drawType, tip);
},
});
this.draw.on('drawstart', () => {
console.log('this.clearPrevious ==>', this.clearPrevious);
if (this.clearPrevious == true) {
sourceDrawOutil.clear();
}
modify.setActive(false);
tip = activeTip;
});
this.draw.on('drawend', () => {
modifyStyle.setGeometry(tipPoint);
modify.setActive(true);
if (this.map != undefined) {
this.map.once('pointermove', () => {
modifyStyle.setGeometry('');
});
}
tip = idleTip;
});
modify.setActive(true);
this.map.addInteraction(this.draw);
}
/* fin dessin de distance */
getInformationFromCoord(event: any) {
if (this.isDrawing == false) {
//this.parcelle = null;
this.batimentList = [];
this.uniteLogementList = [];
const coordinate: any = this.map.getEventCoordinate(event);
const pixels = this.map.getEventPixel(event);
var features = this.map.getFeaturesAtPixel(pixels);
if (features && features.length > 0) {
features.forEach((element: any) => {
console.log("element['values_']", element['values_']);
const result: any = element ? element?.values_ : null;
console.log('result.values_', result.values_);
if (result != null) {
this.mapDataInfo = result?.parcelle;
if (this.mapDataInfo != null) {
this.visibleMapData = true;
this.crudService.getAll('batiment/all/by-parcelle-id/' + this.mapDataInfo?.parcelleId).subscribe(
(data: any) => {
this.batimentList = data.object ? data.object : [];
console.log(' this.batimentList ==> ', this.batimentList);
}
);
this.crudService.getAll('unite-logement/by-parcelle-id/' + this.mapDataInfo?.parcelleId).subscribe(
(data: any) => {
this.uniteLogementList = data.object ? data.object : [];
console.log(' this.uniteLogementList ==> ', this.uniteLogementList);
}
);
}
/*console.log('this.parcelle', this.parcelle);
if(this.parcelle != null) {
this.parcelleService
.getListProprietaire(this.parcelle?.id)
.pipe(take(1))
.subscribe((dataAppartenir: any) => {
console.log('dataAppartenir ==> ', dataAppartenir);
this.appartenirList = dataAppartenir.object
? dataAppartenir.object
: [];
});
this.parcelleService
.getBatiementListOfParcelle(this.parcelle.id)
.subscribe((data: any) => {
this.batimentList = data.object;
});
this.parcelleService
.getUniteLogementListOfParcelle(this.parcelle.id)
.subscribe((data: any) => {
this.uniteLogementList = data.object;
});
}*/
}
});
}
}
}
formatMontant(val: number): string {
if (!val && val !== 0) return '—';
return new Intl.NumberFormat('fr-FR').format(val) + ' FCFA';
}
close(): void {
this.visibleMapData = false;
}
detailByNup(): void {
if (this.mapDataInfo && this.mapDataInfo.parcelleId) {
//const urlBase = this.router.url
const baseUrl = window.location.origin;
console.log('baseUrl ==>', baseUrl);
window.open(baseUrl+'/core/cartographie/data/detail-parcelle/' + this.mapDataInfo.parcelleId)
//this.router.navigate(['/core/cartographie/data/detail-information-parcelle/' + this.mapDataInfo.parcelleId]);
} else {
this.modal.error({
nzTitle: 'Erreur',
nzContent: "Cette parcelle ne comporte pas de données fiscale d'enquête"
});
}
}
openGoogleMap(mode: 'driving' | 'walking' | 'bicycling' | 'transit'): void {
if (this.mapDataInfo && this.mapDataInfo.longitude && this.mapDataInfo.latitude) {
const destinationLat = this.mapDataInfo.latitude;
const destinationLng = this.mapDataInfo.longitude;
navigator.geolocation.getCurrentPosition(
(position) => {
const originLat = position.coords.latitude;
const originLng = position.coords.longitude;
const url = `https://www.google.com/maps/dir/?api=1&origin=${originLat},${originLng}&destination=${destinationLat},${destinationLng}&travelmode=${mode}`;
window.open(url, '_blank');
},
(error) => {
console.error("Erreur de géolocalisation", error);
alert("Impossible d'obtenir votre position.");
}
);
} else {
this.modal.error({
nzTitle: 'Erreur',
nzContent: 'Les coordonnées géographique de la parcelle ne sont pas disponibles.'
});
}
}
constructionArbreUtilisateurs() {
const data: any[] = this.arbreUtilisateurCourant;
// Grouper par département — objet indexé par id
const deptObj: { [id: number]: any } = {};
data.forEach(item => {
// Niveau département
if (!deptObj[item.departementId]) {
deptObj[item.departementId] = {
...item,
communes: {} as { [id: number]: any }
};
}
const dept = deptObj[item.departementId];
// Niveau commune
if (!dept.communes[item.communeId]) {
dept.communes[item.communeId] = {
...item,
arrondissements: {} as { [id: number]: any }
};
}
const commune = dept.communes[item.communeId];
// Niveau arrondissement
if (!commune.arrondissements[item.arrondissementId]) {
commune.arrondissements[item.arrondissementId] = {
...item,
quartiers: [] as any[]
};
}
const arr = commune.arrondissements[item.arrondissementId];
// Niveau quartier
arr.quartiers.push(item);
});
// Construire les nœuds nz-tree
this.nodes = Object.values(deptObj).map((dept: any) => ({
title: `${dept.departementCode}${dept.departementNom}`,
key: `dept-${dept.departementId}`,
icon: 'bank',
isLeaf: false,
expanded: false,
nbParcelles: dept.nbParcellesDepartement,
children: Object.values(dept.communes).map((comm: any) => ({
title: `${comm.communeCode}${comm.communeNom}`,
key: `comm-${comm.communeId}`,
icon: 'home',
isLeaf: false,
expanded: false,
nbParcelles: comm.nbParcellesCommune,
children: Object.values(comm.arrondissements).map((arr: any) => ({
title: arr.arrondissementNom,
key: `arr-${arr.arrondissementId}`,
icon: 'apartment',
isLeaf: false,
expanded: false,
nbParcelles: arr.nbParcellesArrondissement,
children: arr.quartiers.map((quart: any) => ({
title: quart.quartierNom,
key: `quart-${quart.quartierId}`,
icon: 'environment',
isLeaf: true,
nbParcelles: quart.nbParcellesQuartier,
quartier: quart
}))
}))
}))
}));
}
onNodeClick(event: any) {
const node = event.node;
if (node.isLeaf && node.key.startsWith('quart-')) {
this.quartierSelected = node.origin.quartier;
console.log(' this.quartierSelected ==>', this.quartierSelected);
this.message.create('success', `Quartier ${this.quartierSelected.quartierNom} sélectionné.`);
// votre logique de sélection...
if (this.quartierSelected) {
this.chargerParcelleListByQuartier(this.quartierSelected);
}
}
}
getBadgeColor(niveau: string): string {
const colors: any = {
'dept': '#204e10',
'comm': '#10b981',
'arr': '#f59e0b',
'quart': '#ef6972'
};
return colors[niveau] ?? '#6b7280';
}
getNiveau(key: string): string {
if (key.startsWith('dept')) return 'dept';
if (key.startsWith('comm')) return 'comm';
if (key.startsWith('arr')) return 'arr';
if (key.startsWith('quart')) return 'quart';
return '';
}
toggleCard(key: string): void {
this.collapsedCards[key] = !this.collapsedCards[key];
}
toggleFilterBox(): void {
this.filterBoxVisible = !this.filterBoxVisible;
}
getFilterPlaceholder(critere: string): string {
const map: { [key: string]: string } = {
nup: 'ex: NUP-COT-001',
numeroTitreFoncier: 'ex: TF-2023-412',
telephone: 'ex: +229 97...',
ifu: 'ex: IFU-000...',
npi: 'ex: NPI-...',
raisonSociale: 'ex: SARL BÉNIN...',
};
return map[critere] ?? 'Entrer une valeur…';
}
appliquerFiltre(): void {
if (!this.filterCritere) return;
this.globalService.setLodingSuccess(true);
if (this.filterCritere === 'qip_lotissement') {
this.parcelleFilteredList = this.parcelleList.filter(item => {
const ilotItem = (item.ilotLotissement || item.ilot || '').trim().toLowerCase();
const plotItem = (item.plotissement || item.p || '').trim().toLowerCase();
const filterIlot = this.filterIlotLotissement?.trim().toLowerCase() || '';
const filterPlot = this.filterPlotissement?.trim().toLowerCase() || '';
// Si filtre îlot → champ doit exister et matcher
if (filterIlot && (!ilotItem || ilotItem !== filterIlot)) {
return false;
}
// Si filtre plot → champ doit exister et matcher
if (filterPlot && (!plotItem || plotItem !== filterPlot)) {
return false;
}
// Si on arrive ici → ok
return true;
});
} else if (this.filterCritere === 'personne_nom_prenom') {
// ── Nom & Prénom : correspondance exacte sur chaque champ renseigné ──────
const nom = this.filterPersonneNom.trim().toLowerCase();
const prenom = this.filterPersonnePrenom.trim().toLowerCase();
this.parcelleFilteredList = this.parcelleList.filter(item => {
const itemNom = (item.nomEtPrenoms || item.nom || '').toLowerCase();
const itemPrenom = (item.nomEtPrenoms || item.prenom || '').toLowerCase();
const nomOk = !nom || itemNom === nom || itemNom.startsWith(nom);
const prenomOk = !prenom || itemPrenom === prenom || itemPrenom.indexOf(prenom) > -1;
return nomOk && prenomOk;
});
} else {
// ── Champ unique : correspondance exacte ──────────────────────────────────
const val = this.filterValue.trim().toLowerCase();
if (!val) {
this.globalService.setLodingSuccess(false);
return;
}
this.parcelleFilteredList = this.parcelleList.filter(item => {
const champ = (item[this.filterCritere] || '').toString().toLowerCase();
return champ === val || champ.startsWith(val);
});
}
if (this.parcelleFilteredList && this.parcelleFilteredList.length != this.parcelleList.length) {
if (this.parcelleFilteredList[0].longitude && this.parcelleFilteredList[0].latitude) {
this.map.getView().setCenter([this.parcelleFilteredList[0].longitude, this.parcelleFilteredList[0].latitude]);
this.map.getView().setZoom(18);
}
}
this.doMapCPS();
this.globalService.setLodingSuccess(false);
this.filterApplied = true;
}
reinitialiserFiltre(): void {
this.filterCritere = '';
this.filterValue = '';
this.filterQlotissement = '';
this.filterIlotLotissement = '';
this.filterPlotissement = '';
this.filterPersonneNom = ''; // ← ajouter
this.filterPersonnePrenom = ''; // ← ajouter
this.keyFilter = '';
this.filterApplied = false;
this.globalService.setLodingSuccess(true);
this.parcelleFilteredList = [...this.parcelleList];
this.doMapCPS();
this.globalService.setLodingSuccess(false);
}
}