1<!doctype html><html lang="fr"><head><meta charset="utf-8"><title>Outil Négociateur Télécom : Ãtude de Zone de Recherche (ZR)</title><meta name="author" content="immonetic"><meta name="rating" content="General"><meta name="description" content="Accélérez vos déploiements avec notre outil dédié aux négociateurs télécoms. Commandez votre étude de Zone de Recherche (ZR) issue de bases officielles."><link rel="preload" href="_frame/style.css" as="style"><link rel="preload" href="_scripts/bootstrap/css/bootstrap.min.css" as="style"><link rel="preload" href="_scripts/bootstrap/fonts/fontawesome-webfont.woff2?v=4.3.0" as="font" type="font/woff2" crossorigin><link rel="preload" href="_scripts/bootstrap/css/font-awesome.min.css" as="style"><!--PRELOAD--><meta property="og:url" content="https://antennes-relais.fr/outils-negociateurs.html"><meta property="og:type" content="website"><meta property="og:site_name" content="antennes relais d"><meta property="og:title" content="Outil Négociateur Télécom : Ãtude de Zone de Recherche (ZR)"><meta property="og:description" content="Accélérez vos déploiements avec notre outil dédié aux négociateurs télécoms. Commandez votre étude de Zone de Recherche (ZR) issue de bases officielles."><meta property="og:image" content="https://antennes-relais.fr/_media/img/xlarge/gemini-generated-image-jxp9ltjxp9ltjxp9-2.jpg"><meta property="og:image:width" content="1600"><meta property="og:image:height" content="903"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="Outil Négociateur Télécom : Ãtude de Zone de Recherche (ZR)"><meta name="twitter:description" content="Accélérez vos déploiements avec notre outil dédié aux négociateurs télécoms. Commandez votre étude de Zone de Recherche (ZR) issue de bases officielles."><meta name="twitter:image" content="https://antennes-relais.fr/_media/img/xlarge/gemini-generated-image-jxp9ltjxp9ltjxp9-2.jpg"><meta name="ai-keywords" content="outil négociateur télécom, étude zone de recherche, audit ZR, antennes-relais, données officielles, déploiement réseau, IMMONETIC, cartographie télécom, télécommunications, PLU"><meta name="ai-description" content="Outil d'audit cartographique et d'analyse de Zones de Recherche (ZR) conçu par IMMONETIC pour les professionnels et négociateurs télécoms. Ce service permet de générer des études basées sur des données officielles pour faciliter et accélérer le déploiement de nouvelles antennes-relais.">google.com, pub-5479908916438170, DIRECT, f08c47fec0942fa0<meta name="generator" content="Lauyan TOWeb 14.1.0.112"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link href="rss.xml" rel="alternate" type="application/rss+xml"><link href="_media/img/medium/logo-formulaire.png" rel="shortcut icon" type="image/png"><link href="_media/img/medium/logo-formulaire.png" rel="apple-touch-icon"><meta name="msapplication-TileColor" content="#5835b8"><meta name="msapplication-TileImage" content="_media/img/medium/logo-formulaire.png"><meta name="theme-color" content="#FF8C18"><meta name="msapplication-navbutton-color" content="#FF8C18"><link href="_scripts/bootstrap/css/bootstrap.min.css" rel="stylesheet"><link href="https://fonts.googleapis.com/css?family=Varela+Round&display=swap" rel="stylesheet"><link href="_frame/style.css" rel="stylesheet"><link rel="canonical" href="https://antennes-relais.fr/outils-negociateurs.html"><link rel="stylesheet" href="_scripts/jquery/ui/tw-dialog.css"><link rel="stylesheet" href="_scripts/bootstrap/css/font-awesome.min.css"><style>.raty-comp{padding:8px 0;font-size:10px;color:#FD9317}.tw-blogbar{display:flex;align-items:center}@media (max-width:767px){.tw-blogbar{flex-direction:column;}}.ta-left{text-align:left}.ta-center{text-align:center}.ta-justify{text-align:justify}.ta-right{text-align:right}.float-l{float:left}.float-r{float:right}.flexobj{flex-grow:0;flex-shrink:0;margin-right:1em;margin-left:1em}.flexrow{display:flex !important;align-items:center}.flexrow-align-start{align-items:start}@media (max-width:767px){.flexrow{flex-direction:column}.flexrow-align-start{align-items:center}}.cookie-consent{width:100%;padding:16px 0;position:relative;z-index:9800;text-align:center;}.ckc-bottom{position:fixed;bottom:0;left:0;right:0;height:auto;}.cookie-consent,.cookie-consent button{font-size:100%}.cookie-consent a{font-weight:bold;text-decoration:none}.cookie-consent a:hover{text-decoration:underline}.cookie-consent .no-deco-hover a:hover{text-decoration:none}#main-carousel>.carousel-inner>.item{transform:scale(1.1);}#main-carousel>.carousel-inner>.active{transform:scale(1);transition:0.6s ease-in-out left,transform 4s;}</style><link href="_frame/print.css" rel="stylesheet" type="text/css" media="print">
1<script src="_scripts/cookie/gdpr-ckie.js"></script>
1<script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,"script","https://www.google-analytics.com/analytics.js","ga");ga("create","G-0Q8Q7KS6FQ","auto");ga("send","pageview");window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag("consent","default",{"ad_storage":"denied","ad_user_data":"denied","ad_personalization":"denied","analytics_storage":"denied","functionality_storage":"denied","personalization_storage":"denied","security_storage":"granted","wait_for_update":500});</script>
vendor: 63 bytes, line 1
1<script async src="https://www.googletagmanager.com/gtag/js?id=
1G-D5E230LT02
vendor: 11 bytes, line 1
1"></script>
1<script>
vendor: 118 bytes, line 1
1window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag("js",new Date());gtag("config","
1G-D5E230LT02
vendor: 3 bytes, line 1
1");
1</script>
1<script>
vendor: 388 bytes, line 1
1!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version="2.0";n.queue=[];t=b.createElement(e);t.async=!0;t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,document,"script","https://connect.facebook.net/en_US/fbevents.js");fbq("init","
1457523984376295
vendor: 27 bytes, line 1
1");fbq("track","PageView");
1</script>
1<noscript><img height="1" width="1" alt="" src="https://www.facebook.com/tr?id=457523984376295&ev=PageView&noscript=1"/></noscript></head><body oncontextmenu="return false;"><div id="site"><div id="page"><header><nav id="toolbar3" class="navbar"><div class="navbar-inner"><div class="container-fluid"><ul id="toolbar3_r" class="nav pull-right"><li><div id="sharebox"><a target="_blank" href="https://www.facebook.com/@fmsimmonetic" rel="noopener"><img style="width:2rem" src="_frame/tw-share-facebook.svg" class="anim-zoom" alt="facebook"></a><a target="_blank" href="https://www.linkedin.com/in/immonetic/" rel="noopener"><img style="width:2rem" src="_frame/tw-share-linkedin.svg" class="anim-zoom" alt="linkedin"></a><a target="_blank" href="https://www.youtube.com/channel/UCyzmC-Z4q7FdXPWSOT_pCjA" rel="noopener"><img style="width:2rem" src="_frame/tw-share-youtube.svg" class="anim-zoom" alt="youtube"></a><a target="_blank" href="https://www.instagram.com/antennes_relais/" rel="noopener"><img style="width:2rem" src="_frame/tw-share-instagram.svg" class="anim-zoom" alt="instagram"></a><a target="_blank" href="rss.xml" type="application/rss+xml" rel="noopener"><img style="width:2rem" src="_frame/tw-share-rss.svg" class="anim-zoom" alt="rss"></a></div></li></ul><button type="button" class="btn btn-navbar collapsed" aria-label="Menu" style="float:left" data-toggle="collapse" data-target=".nav-collapse"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><div class="nav-collapse collapse"><ul id="toolbar3_l" class="nav"><li><ul id="mainmenu" class="nav"><li><a href="./">Accueil</a></li><ul class="nav"><li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Propriétaire <small>▼</small></a><ul class="dropdown-menu"><li><a href="tester-mon-adresse.html">Etat des lieux antennes relais</a></li><li><a href="mesures-de-champs-radioelectriques-protocole-anfr.html">Mesurer l'exposition d'un bien aux ondes électromagnétiques</a></li><li><a href="formulaire-valorisation-terrain-immeuble-pour-accueil-antennes-relais.html">Formulaire valorisation terrain, immeuble</a></li><li><a href="formulaire-negociation-renegociation-bail-antennes-relais.html">Assistance négociation, renégociation, reprise de bail</a></li><li><a href="bail-antennes-relais.html">Comprendre les enjeux d'une négociation, cession de bail</a></li><li><a href="optimiser-revenus-site-telecom-existant.html">Optimiser les revenus dâun site télécom</a></li><li><a href="mise-en-location-de-votre-terrain-immeuble-pour-installer-une-antenne-relais.html">Location de votre terrain pour installer un relai</a></li><li><a href="redevance-antennes-relais-bail-loyer-vente.html">Quelle rentabilité pour votre terrain ?</a></li><li><a href="carte-antennes-relais-louer-votre-terrain-bien-a-un-operateur.html">Station relai : carte opérateurs</a></li></ul></li></ul><ul class="nav"><li class="dropdown active"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Opérateur/Gestionnaire <small>▼</small></a><ul class="dropdown-menu"><li><a href="outils-negociateurs.html">Outils négociateurs</a></li><li><a href="operateur-gestionnaire-infrastructures-antennes-relais-decouvrez-nos-services-pour-votre-deploiement.html">Services</a></li><li><a href="legislation-et-jurisprudence-antennes-relais.html">Législation et jurisprudence antennes-relais</a></li><li><a href="prospection-a-distance-de-zones-de-recherche.html">Prospection à distance</a></li></ul></li></ul><ul class="nav"><li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Catalogue <small>▼</small></a><ul class="dropdown-menu"><li><a href="posez-votre-question-antennes-relais.html">questions, assistance, pack négo</a></li></ul></li></ul><li><a href="immonetic-expertise-antennes-relais.html">Qui sommes nous ?</a></li><li><a href="contact-immonetic-demande-information-antennes-relais.html">Contact</a></li><li><a href="blog-antennes-relais.html">BLOG</a></li></ul></li></ul></div></div></div></nav><nav id="toolbar1" class="navbar"><div class="navbar-inner"><div class="container-fluid"><ul id="toolbar1_l" class="nav"><li><a id="logo" href="./" aria-label="logo"><span id="logo-lt"></span><span id="logo-rt"></span><br><span id="logo-sl" class="hidden-phone"></span></a></li></ul><ul id="toolbar1_r" class="nav pull-right"><li><a id="button-cart" data-container="body" href="_checkout.html" title="Panier"><span id="sc_pcount"></span></a></li><li><a id="button-login" href="_accounts.php" title="Mon compte"><i class="fa fa-user fa-2x"></i></a></li><li><form id="searchbox" class="navbar-search" action="_search.html"><input type="text" name="req" id="searchbox-req" class="search-query" placeholder="Rechercher"></form></li></ul></div></div></nav></header>
1<main id="content" class="container-fluid"><div class="row-fluid"><div class="span12"></div></div><div id="topic" class="row-fluid"><div id="topic-inner"><div id="top-content" class="span9" style="background:initial"><h1>Outils négociateurs</h1><div class="row-fluid"><div class="span12 alert" style="overflow:hidden;text-align:center;"><button type="button" class="close" data-dismiss="alert">×</button>
1<script>google_ad_client = "pub-5479908916438170";google_ad_width = 468;google_ad_height = 60;google_ad_format = "468x60_as";google_ad_type = "text_image";google_color_border = "C0C0C0";google_color_bg = "C09853";google_color_link = "0000FF";google_color_url = "C0C0C0";google_color_text = "000000";</script>
1<script src="https://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
1</div></div><div class="twpara-row row-fluid"><div id="5XxINOXi" class="span12 tw-para "><h2><span style="font-size:18px;">Optimisez votre prospection : Générez l'étude automatisée de votre zone de recherche en quelques minutes !</span></h2><div class="ptext"><p><span style="font-size:16px;">Fini les heures perdues à croiser manuellement le cadastre, les règlements d'urbanisme, les raccordements et les contraintes environnementales.</span></p><p><br><span style="font-size:16px;">Importez simplement votre fichier .kmz. Notre algorithme analyse votre zone de recherche et en extrait instantanément toutes les données stratégiques pour qualifier vos sites avant même la première visite terrain :</span></p><p><br><span style="font-size:16px;">ð <b>Couverture globale :</b> Service pleinement opérationnel en <b>France Métropolitaine</b> et aux <b>Antilles</b>, avec prise en compte des spécificités géographiques locales.</span></p><p><span style="font-size:16px;"><br>ð¯ <b>Topographie & Ãmergences</b></span></p><ul><li><span style="font-size:16px;"><b>Le Top 15 des points hauts :</b> Identification des bâtiments les plus hauts (hauteur et altitudes NGF sur zone).</span></li><li><span style="font-size:16px;"><i><i>Masques végétaux</i> :</i>* Estimation des hauteurs boisées pour anticiper les obstacles.</span></li></ul><span style="font-size:16px;">ð <b>Urbanisme & Environnement</b></span><ul><li><span style="font-size:16px;"><b>Zonage PLU/PLUi :</b> Affichage de la zone réglementaire exacte pour chaque parcelle.</span></li><li><span style="font-size:16px;"><b>Alertes Environnementales :</b> Détection automatique des communes soumises à la <b>Loi Littoral</b> et au risque d'<b>
1érosion côtière</b>.</span></li><li><span style="font-size:16px;"><b>Patrimoine :</b> Signalement des périmètres ABF (Monuments historiques <500m).</span></li></ul> <span style="font-size:16px;"> â¡ <b>Infrastructures & Raccordement</b></span><ul><li><span style="font-size:16px;"><b>Réseau Ãlectrique :</b> Détection des postes de transformation Enedis (HTA/BT) à moins de 500m pour anticiper les coûts de raccordement.</span></li><li><span style="font-size:16px;"><b>Fibre Optique :</b> Vérification de l'éligibilité et du statut de déploiement (ARCEP) pour chaque adresse.</span></li><li><span style="font-size:16px;"><b>Antennes existantes :</b> Cartographie des sites ANFR présents dans un rayon de 400m (opérateurs, hauteurs, technologies).</span></li></ul> <span style="font-size:16px;"> ð¢ <b>Ciblage Foncier & OSINT</b></span><ul><li><span style="font-size:16px;"><b>Bailleurs Sociaux :</b> Détection et regroupement visuel du patrimoine des acteurs institutionnels (HLM).</span></li><li><span style="font-size:16px;"><b>Copropriétés & Personnes Morales :</b> Vérification au RNIC et génération automatique de <b>liens d'enquête (Pappers)</b> pour trouver le bon interlocuteur (Syndic, gestionnaire) en un clic.</span></li><li><span style="font-size:16px;"><b>Ãtablissements sensibles :</b> Identification des hôpitaux, écoles ou crèches dans un rayon de 120m pour intégrer une marge de sécurité pour la production des DIM, DIVP.</span></li></ul><p><span style="font-size:16px;"><b>Livrables prêts à l'emploi :</b>Téléchargez une archive contenant un tableau de données exhaustif (.csv) et une cartographie interactive (.kmz) directement exploitable sur Google Earth par vos négociateurs.</span></p><p><span style="font-size:16px;"><br><i>( * ) Les hauteurs végétales sont des estimations basées sur les définitions théoriques de l'IGN, et non des hauteurs réelles mesurées sur site.</i></span></p><p><span style="font-size:16px;">Conçu pour les professionnels des télécoms, ce module vous livre des données issues de bases de données officielles, prêtes à être exploitées directement dans vos outils de travail.</span></p><p><strong style="background-color: initial; color: rgb(28, 28, 28);"><span style="font-size:16px;">Besoin de vous rendre compte d'un résultat concret ? Téléchargez celui de notre ZR fictive sur Paris 10 :</span></strong></p><p><strong><span style="font-size:16px;">- </span></strong><a href="_iserv/dlfiles/dl.php?ddl=zr-fictive-paris-10.kmz" id="lnk3-5XxINOXi" rel="nofollow">Fichier KMZ</a></p><p>- <a href="_iserv/dlfiles/dl.php?ddl=zr-fictive-paris-10.csv" id="lnk2-5XxINOXi" rel="nofollow">Fichier CSV</a></p><p><b style="font-size: 16px; background-color: initial; color: rgb(28, 28, 28);">Prêt à accélérer vos déploiements ? Commandez l'étude de votre zone de recherche dans le formulaire ci-dessous ! </b></p><p><b style="font-size: 16px; background-color: initial; color: rgb(28, 28, 28);">Une fois le paiement effectué, vous recevrez par mail un lien url et un code d'accès unique à notre service.</b></p><p><b style="font-size: 16px; background-color: initial; color: rgb(28, 28, 28);">Besoin de faire l'étude de plusieurs ZR, </b><a onclick="javascript:return(decMail2(this));" href="znvygb?cnpxme#nagraarf-erynvf.se" id="lnk1-5XxINOXi" rel="nofollow" style="font-size: 16px; background-color: initial;">contactez-nous</a><b style="font-size: 16px; background-color: initial; color: rgb(28, 28, 28);"> pour l'achat d'un pack.</b></p><p><br></p><p style="text-align: center;"> 2 <iframe 3 id="JotFormIFrame-262564954333059" 4 title="Etude ZR" 5 onload="window.parent.scrollTo(0,0)" 6 allowtransparency="true" 7 allow="geolocation; microphone; camera; fullscreen; payment" 8 src="https://pci.jotform.com/form/262564954333059" 9 frameborder="0" 10 style="min-width:100%;max-width:100%;height:539px;border:none;" 11 scrolling="no" 12 > 13 </iframe> 14
14<script src='https://cdn.jotfor.ms/s/umd/latest/for-form-embed-handler.js'></script>
14 15
15<script>window.jotformEmbedHandler("iframe[id='JotFormIFrame-262564954333059']", "https://pci.jotform.com/")</script>
15 16 <span style="font-size:16px;"> </span></p><p><br></p><p style="text-align: center;"><br></p></div></div></div><div class="twpara-row row-fluid"><div id="8lT1Hy4P" class="span12 tw-para "><h2 style="text-align:center"><span style="font-size:18px;">Actualités judiciaires du 20 juillet au 20 septembre 2026</span></h2><div class="ptext"><p style="text-align: justify;"><span style="font-size:16px;">Découvrez notre dernière synthèse jurisprudentielle dédiée au déploiement des infrastructures de radiotéléphonie mobile. Cette édition décrypte les tendances récentes des juridictions administratives face aux refus d'urbanisme : contrôle strict de l'intégration paysagère (art. R. 111-27), échec des oppositions fondées sur le seul principe de précaution sanitaire, et application rigoureuse des PLU locaux face à l'urgence d'améliorer la couverture réseau. </span></p><p style="text-align: center;"><a class="btn btn-warning" href="_iserv/dlfiles/dl.php?ddl=lettre-dinformation-immonetic-20260921.pdf" id="lnkb13859de" title="Lettre dâinformation juridique ">ACCES SYNTHESE</a><br><br></p></div></div></div><div class="twpara-row row-fluid"><div id="Day8eXVN" class="span12 tw-para "><h2><span style="font-size:18px;">Carte Etablissements Particuliers (écoles, crèches, hôpitaux ...)<br></span><br></h2><div class="pobj float-l"><picture><source type="image/webp" srcset="_media/img/thumb/capture-decran-2026-07-01-194914.
16webp 160w,_media/img/small/capture-decran-2026-07-01-194914.webp 480w,_media/img/medium/capture-decran-2026-07-01-194914.webp 768w,_media/img/large/capture-decran-2026-07-01-194914.webp 1024w,_media/img/xlarge/capture-decran-2026-07-01-194914.webp 1208w"><source type="image/png" srcset="_media/img/thumb/capture-decran-2026-07-01-194914.png 160w,_media/img/small/capture-decran-2026-07-01-194914.png 480w,_media/img/medium/capture-decran-2026-07-01-194914.png 768w,_media/img/large/capture-decran-2026-07-01-194914.png 1024w,_media/img/xlarge/capture-decran-2026-07-01-194914.png 1208w"><img src="_media/img/thumb/capture-decran-2026-07-01-194914.png" width="160" height="156" style="max-width:100%;width:160px;" alt="" loading="lazy"></picture></div><div class="ptext"><div style="text-align: justify;"><span style="font-size:16px;"><b>Avertissement et limites de responsabilité : </b>Les résultats de proximité et les distances affichés sont fournis à titre purement informatif et indicatif. Le calcul des distances est établi de manière automatisée par rapport aux limites parcellaires ou aux contours de bâtiments répertoriés dans les bases de données publiques (OpenStreetMap, FINESS). Des écarts ou approximations géographiques peuvent exister par rapport aux données cadastrales officielles ou à la réalité physique du terrain. <b>Par ailleurs, une marge de sécurité a été volontairement insérée dans cet outil en appliquant un rayon d'extraction de 150 mètres au lieu des 100 mètres prévus par la réglementation, afin d'inciter expressément l'utilisateur à réaliser un contrôle de vérification ou lui permettre de saisir précisément le rayon.</b> En conséquence, la société décline toute responsabilité quant à l'utilisation, l'interprétation ou l'exactitude de ces résultats. Cet outil constitue un premier niveau d'information qui ne dispense en aucun cas l'utilisateur d'un contrôle rigoureux et d'une vérification technique ou visuelle directement sur site au sein de la zone de recherche.</span></div><div style="text-align: justify;"><br></div><div style="text-align: justify;"><em><strong><span style="font-size:16px;">Afin de garantir la confidentialité de vos données, nous n'enregistrons aucune requête effectuée sur notre site. </span></strong></em></div><div style="text-align: justify;"><br></div><div><br></div><div style="text-align: center;"><link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
17<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
17 18 19<style> 20 .immo-container { font-family: 'Segoe UI', Arial, sans-serif; max-width: 700px; margin: 20px auto; padding: 20px; background: #f8f9fa; border-radius: 10px; border: 1px solid #dadce0; color: #333; box-sizing: border-box; } 21 .immo-title { margin-top: 0; color: #1a73e8; font-size: 20px; } 22 .immo-label { font-weight: 600; display: block; margin-bottom: 6px; font-size: 14px; } 23 .immo-input-text { width: 100%; padding: 11px; box-sizing: border-box; border: 1px solid #ccc; border-radius: 5px; font-size: 14px; } 24 .immo-suggest-box { border: 1px solid #ccc; border-top: none; max-height: 180px; overflow-y: auto; background: white; display: none; position: absolute; width: calc(100% - 40px); z-index: 10000; border-radius: 0 0 5px 5px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); } 25 .immo-suggest-item { padding: 8px 10px; cursor: pointer; border-bottom: 1px solid #f1f3f4; font-size: 13px; } 26 .immo-suggest-item:hover { background-color: #f1f3f4; } 27 .immo-flex { display: flex; margin-top: 15px; align-items: center; gap: 10px; } 28 .immo-input-num { width: 80px; padding: 7px; border: 1px solid #ccc; border-radius: 5px; text-align: center; font-size: 14px; } 29 .immo-btn { margin-top: 15px; width: 100%; padding: 12px; background-color: #1a73e8; color: white; border: none; border-radius: 5px; cursor: pointer; font-weight: bold; font-size: 15px; } 30 .immo-btn:disabled { background-color: #9aa0a6; cursor: not-allowed; } 31 .immo-results-zone { margin-top: 20px; display: none; } 32 .immo-dl-box { margin: 15px 0; padding: 12px; background-color: #e8f0fe; border-radius: 8px; border: 1px solid #1a73e8; display: none; gap: 10px; flex-wrap: wrap; } 33 .immo-dl-btn { padding: 10px 14px; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; color: white; font-size: 13px; display: inline-block; text-decoration: none; } 34 .immo-list { background: white; padding: 12px; border-radius: 6px; border: 1px solid #ddd; max-height: 200px; overflow-y: auto; font-size: 13px; line-height: 1.4; margin-bottom: 15px; } 35 .map-wrapper { position: relative; width: 100%; height: 450px; margin-top: 10px; } 36 #immo_map { width: 100%; height: 100%; border-radius: 8px; border: 1px solid #ccc; z-index: 1; } 37 .map-overlay-title { background: white; padding: 8px 12px; border-radius: 6px; box-shadow: 0 2px 6px rgba(0,0,0,0.15); font-size: 12px; max-width: 260px; margin-top: 100px !important; font-family: Arial, sans-serif; } 38 .map-overlay-footer { background: white; padding: 6px 12px; border-radius: 4px; box-shadow: 0 2px 6px rgba(0,0,0,0.15); font-size: 10px; font-family: Arial, sans-serif; max-width: 320px; line-height: 1.4; } 39 .map-overlay-logo { background: rgba(255,255,255,0.9); padding: 5px 10px; border-radius: 6px; box-shadow: 0 2px 6px rgba(0,0,0,0.15); } 40</style> 41 42<div class="immo-container"> 43 <h3 class="immo-title">ð Saisie d'Adresse & Analyse de Proximité</h3> 44 <div style="position: relative;"> 45 <label class="immo-label">Adresse postale (Saisie prédictive ou libre) :</label> 46 <input type="text" id="immo_addr" autocomplete="new-password" placeholder="Ex: 32 bd de Strasburg, Paris..." class="immo-input-text"> 47 <div id="immo_suggest" class="immo-suggest-box"></div> 48 </div> 49 50 <div style="position: relative; margin-top: 15px;"> 51 <label class="immo-label">Référence du site (Optionnel - Servira de nom de fichier) :</label> 52 <input type="text" id="immo_ref" autocomplete="new-password" placeholder="Ex: Site_Auteuil_Ref_45..." class="immo-input-text"> 53 </div> 54 55 <div class="immo-flex"> 56 <label class="immo-label" style="margin: 0;">Rayon de recherche :</label> 57 <input type="number" id="immo_rayon" value="150" class="immo-input-num"> 58 <span style="font-size:14px; color:#666;">mètres</span> 59 </div> 60 61 <button id="immo_submit" class="immo-btn">Lancer l'extraction</button> 62 63 <div id="immo_results" class="immo-results-zone"> 64 <div id="immo_meta_text" style="font-size: 13px; font-weight: bold; margin-bottom: 10px; color:#5f6368;"></div> 65 66 <div class="immo-dl-box" id="immo_dl_box"> 67 <a id="immo_dl_map" download="carte_proximite_immonetic.html" class="immo-dl-btn" style="background-color: #1a73e8;">ð¥ Télécharger la Carte (HTML)</a> 68 <a id="immo_dl_csv" download="liste_etablissements_150m.csv" class="immo-dl-btn" style="background-color: #34a853;">ð¥ Télécharger la Liste (CSV)</a> 69 <a id="immo_dl_kml" download="analyse_proximite_immonetic.kml" class="immo-dl-btn" style="background-color: #004d40;">ð¥ Télécharger pour Google Earth (KML)</a> 70 </div> 71 72 <div style="font-size: 11px; color: #666; line-height: 1.4; margin: 15px 0; padding: 10px; background: #fff; border-left: 3px solid #9aa0a6; border-radius: 4px;"> 73 <b>Avertissement :</b>
73 Les distances sont calculées de manière automatisée par rapport aux limites parcellaires ou contours de bâtiments publics. Des écarts peuvent exister avec la réalité du terrain. <b>Par défaut, un rayon de 150 mètres a été volontairement appliquée (au lieu des 100 mètres réglementaires) pour plus de sécurité afin d'inciter l'utilisateur à réaliser un contrôle visuel et technique directement sur site. Vous pouvez réduire ce rayon </b> Ce module reste un outil d'information ; nous déclinons toute responsabilité quant à l'utilisation ou l'exactitude de ces résultats. Conditions complètes sur <a href="https://antennes-relais.fr/outils-negociateurs.php" target="_blank" rel="noopener">outils-negociateurs.php</a>. 74 </div> 75 76 <div class="immo-label">Ãtablissements repérés :</div> 77 <div id="immo_text_list" class="immo-list"></div> 78 79 <button id="immo_ruler_btn" class="immo-btn" style="margin-top:10px; background-color:#5f6368; width:auto; display:inline-block; padding:8px 14px; font-size:13px;">ð Activer la règle de mesure</button> 80 81 <div class="map-wrapper"> 82 <div id="immo_map"></div> 83 </div> 84 </div> 85</div> 86
87<script> 88(function() { 89 function executerScriptAnalyse() { 90 const input = document.getElementById('immo_addr'); 91 const btn = document.getElementById('immo_submit'); 92 if (!input || !btn) { 93 setTimeout(executerScriptAnalyse, 250); 94 return; 95 } 96 97 const box = document.getElementById('immo_suggest'); 98 const rayonInput = document.getElementById('immo_rayon'); 99 const refInput = document.getElementById('immo_ref'); 100 const resultsZone = document.getElementById('immo_results'); 101 const textList = document.getElementById('immo_text_list'); 102 const metaText = document.getElementById('immo_meta_text'); 103 const dlBox = document.getElementById('immo_dl_box'); 104 const dlCsv = document.getElementById('immo_dl_csv'); 105 const dlMap = document.getElementById('immo_dl_map'); 106 const dlKml = document.getElementById('immo_dl_kml'); 107 const rulerBtn = document.getElementById('immo_ruler_btn'); 108 109 const URL_LOGO = "https://antennes-relais.fr/_media/img/medium/logo-formulaire.png"; 110 111 let lat = null, lon = null, map = null, circle = null, markerGroup = null; 112 let groupScolaire = null, groupCreche = null, groupSoins = null; 113 let currentData = []; 114 let currentAdresseSaisie = ""; 115 116 let modeMesure = false; 117 let premierPointMesure = null; 118 let mesureMarkers = []; 119 let mesureLigne = null; 120 121 rulerBtn.addEventListener('click', () => { 122 if (!map) return; 123 modeMesure = !modeMesure; 124 if (modeMesure) { 125 rulerBtn.innerText = "ð Règle active (Cliquez 2 points sur la carte)"; 126 rulerBtn.style.backgroundColor = "#e91e63"; 127 map.getContainer().style.cursor = 'crosshair'; 128 } else { 129 rulerBtn.innerText = "ð Activer la règle de mesure"; 130 rulerBtn.style.backgroundColor = "#5f6368"; 131 map.getContainer().style.cursor = ''; 132 nettoyerMesure(); 133 } 134 }); 135 136 function nettoyerMesure() { 137 premierPointMesure = null; 138 mesureMarkers.forEach(m => map.removeLayer(m)); 139 mesureMarkers = []; 140 if (mesureLigne) { map.removeLayer(mesureLigne); mesureLigne = null; } 141 } 142 143 input.addEventListener('input', async (e) => { 144 lat = null; lon = null; 145 const text = e.target.value; 146 if (text.length < 3) { box.style.display = 'none'; return; } 147 try { 148 const res = await fetch('https://photon.komoot.io/api/?q=' + encodeURIComponent(text) + '&lang=fr&limit=5'); 149 const data = await res.json(); 150 box.innerHTML = ''; 151 if (data.features && data.features.length > 0) { 152 box.style.display = 'block'; 153 data.features.forEach(feat => { 154 const p = feat.properties; 155 const label = [p.name, p.street, p.postcode, p.city, p.country].filter(Boolean).join(', '); 156 const item = document.createElement('div'); 157 item.className = 'immo-suggest-item'; 158 item.innerText = label; 159 item.addEventListener('click', () => { 160 const matchNum = input.value.match(/^(\d+)\s*/); 161 const numTape = matchNum ? matchNum[1] : ''; 162 input.value = (numTape && !label.match(/^\d/)) ? numTape + " " + label : label; 163 box.style.display = 'none'; 164 }); 165 box.appendChild(item); 166 }); 167 } else { box.style.display = 'none'; } 168 } catch (err) { console.error(err); } 169 }); 170 171 document.addEventListener('click', (e) => { if (e.target !== input) box.style.display = 'none'; }); 172 173 function getDistance(lat1, lon1, lat2, lon2) { 174 const R = 6371000; 175 const dLat = (lat2 - lat1) * Math.PI / 180; 176 const dLon = (lon2 - lon1) * Math.PI / 180; 177 const a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * Math.sin(dLon/2) * Math.sin(dLon/2); 178 return R * (2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))); 179 } 180 181 function generateKMLCircle(cLat, cLon, radiusMeters) { 182 var points = []; 183 var numPoints = 64; 184 var earthRadius = 6371000;
185 var d = radiusMeters / earthRadius; 186 var lat1 = cLat * Math.PI / 180; 187 var lon1 = cLon * Math.PI / 180; 188 for (var i = 0; i <= numPoints; i++) { 189 var tc = (i * 2 * Math.PI) / numPoints; 190 var latRad = Math.asin(Math.sin(lat1) * Math.cos(d) + Math.cos(lat1) * Math.sin(d) * Math.cos(tc)); 191 var lonRad = lon1 + Math.atan2(Math.sin(tc) * Math.sin(d) * Math.cos(lat1), Math.cos(d) - Math.sin(lat1) * Math.sin(latRad)); 192 points.push((lonRad * 180 / Math.PI) + "," + (latRad * 180 / Math.PI) + ",0"); 193 } 194 return points.join(" "); 195 } 196 197 function createCustomPin(color) { 198 var hexColor = "#34a853"; 199 if (color === "purple") hexColor = "#a142f4"; 200 if (color === "orange") hexColor = "#ff9900"; 201 if (color === "blue") hexColor = "#1a73e8"; 202 203 return L.divIcon({ 204 className: 'custom-pin-' + color, 205 html: '<svg width="30" height="42" viewBox="0 0 30 42" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15 0C6.71 0 0 6.71 0 15C0 26.25 15 42 15 42C15 42 30 26.25 30 15C30 6.71 23.29 0 15 0ZM15 20C12.24 20 10 17.76 10 15C10 12.24 12.24 10 15 10C17.76 10 20 12.24 20 15C20 17.76 17.76 20 15 20Z" fill="' + hexColor + '"/><circle cx="15" cy="15" r="4" fill="#FFFFFF"/></svg>', 206 iconSize: [30, 42], 207 iconAnchor: [15, 42], 208 popupAnchor: [0, -38] 209 }); 210 } 211 212 btn.addEventListener('click', async () => { 213 currentAdresseSaisie = input.value; 214 if (!currentAdresseSaisie) { alert("Veuillez saisir une adresse."); return; } 215 216 btn.innerText = "Extraction en cours..."; 217 btn.disabled = true; 218 dlBox.style.display = "none"; 219 resultsZone.style.display = "none"; 220 nettoyerMesure(); 221 222 try { 223 const response = await fetch('https://photon.komoot.io/api/?q=' + encodeURIComponent(currentAdresseSaisie) + '&lang=fr&limit=1'); 224 const data = await response.json(); 225 if (data.features && data.features.length > 0) { 226 lon = data.features[0].geometry.coordinates[0]; 227 lat = data.features[0].geometry.coordinates[1]; 228 } else { 229 alert("Adresse introuvable."); 230 btn.innerText = "Lancer l'extraction"; btn.disabled = false; return; 231 } 232 233 const rayon = parseInt(rayonInput.value); 234 metaText.innerHTML = "ð Point analysé : " + currentAdresseSaisie + "<br>ð Rayon d'inclusion étudié : " + rayon + " mètres"; 235 currentData = []; 236 textList.innerHTML = ""; 237 238 const deltaLat = rayon / 111000; 239 const deltaLon = rayon / (111000 * Math.cos(lat * Math.PI / 180)); 240 const bbox = (lon - deltaLon) + "," + (lat - deltaLat) + "," + (lon + deltaLon) + "," + (lat + deltaLat); 241 242 try { 243 const opQ = '[out:json][timeout:15];(node["amenity"~"school|kindergarten|childcare|hospital|clinic|social_facility|nursing_home"](around:' + rayon + ',' + lat + ',' + lon + ');way["amenity"~"school|kindergarten|childcare|hospital|clinic|social_facility|nursing_home"](around:' + rayon + ',' + lat + ',' + lon + ');relation["amenity"~"school|kindergarten|childcare|hospital|clinic|social_facility|nursing_home"](around:' + rayon + ',' + lat + ',' + lon + ');node["social_facility"](around:' + rayon + ',' + lat + ',' + lon + ');way["social_facility"](around:' + rayon + ',' + lat + ',' + lon + ');relation["social_facility"](around:' + rayon + ',' + lat + ',' + lon + '););out center geom;'; 244 const overpassURL = "https://overpass-api.de/api/interpreter"; 245 const resReal = await fetch(overpassURL, { method: "POST", body: "data=" + encodeURIComponent(opQ) }); 246 if(resReal.ok) { 247 const d = await resReal.json(); 248 const els = d.elements || []; 249 for (let i = 0; i < els.length; i++) { 250 const el = els[i]; 251 const t = el.tags || {}; 252 let e_lat = null, e_lon = null; 253 let calc_dist = Infinity; 254 let closest_vertex = null; 255 let polygonPoints = null; 256 257 if (el.lat && el.lon) { 258 e_lat = el.lat; 259 e_lon = el.lon; 260 calc_dist = getDistance(lat, lon, e_lat, e_lon);
261 } else if (el.geometry && el.geometry.length > 0) { 262 polygonPoints = el.geometry.map(function(pt) { return [pt.lat, pt.lon]; }); 263 let sum_lat = 0, sum_lon = 0; 264 el.geometry.forEach(pt => { 265 let d_v = getDistance(lat, lon, pt.lat, pt.lon); 266 if (d_v < calc_dist) { 267 calc_dist = d_v; 268 closest_vertex = pt; 269 } 270 sum_lat += pt.lat; 271 sum_lon += pt.lon; 272 }); 273 274 let test_cent_lat = sum_lat / el.geometry.length; 275 let test_cent_lon = sum_lon / el.geometry.length; 276 277 if (getDistance(lat, lon, test_cent_lat, test_cent_lon) <= rayon) { 278 e_lat = test_cent_lat; 279 e_lon = test_cent_lon; 280 } else if (closest_vertex) { 281 e_lat = closest_vertex.lat; 282 e_lon = closest_vertex.lon; 283 } 284 } else if (el.center && el.center.lat && el.center.lon) { 285 e_lat = el.center.lat; 286 e_lon = el.center.lon; 287 calc_dist = getDistance(lat, lon, e_lat, e_lon); 288 } 289 290 if (calc_dist <= rayon && e_lat && e_lon) { 291 var typeLabel = "Ãtablissement scolaire"; 292 var col = "purple"; 293 294 if (t.amenity === 'childcare' || t.amenity === 'kindergarten') { 295 typeLabel = "Crèche / Garderie"; 296 col = "green"; 297 } else if (t.amenity === 'hospital' || t.amenity === 'clinic' || t.amenity === 'nursing_home' || t.social_facility === 'nursing_home' || t.amenity === 'social_facility' || t.social_facility === 'assisted_living') { 298 var name_lower = (t.name || "").toLowerCase(); 299 if (name_lower.includes("cabinet") || name_lower.includes("pharmacie") || name_lower.includes("laboratoire") || name_lower.includes("kiné")) { 300 continue; 301 } 302 if (t.social_facility === 'nursing_home' || t.amenity === 'nursing_home' || name_lower.includes("ehpad") || name_lower.includes("retraite") || name_lower.includes("auteuil") || t.social_facility === 'assisted_living') { 303 typeLabel = "EHPAD / Maison de retraite"; 304 } else { 305 typeLabel = "Hôpital / Clinique"; 306 } 307 col = "orange"; 308 } 309 310 const nom = t.name || typeLabel; 311 let adr = (t['addr:housenumber'] || '') + " " + (t['addr:street'] || '') + " " + (t['addr:postcode'] || '') + " " + (t['addr:city'] || ''); 312 adr = adr.trim(); 313 314 if (!adr) { 315 try { 316 const revRes = await fetch('https://photon.komoot.io/reverse?lon=' + e_lon + '&lat=' + e_lat); 317 if (revRes.ok) { 318 const revData = await revRes.json(); 319 if (revData.features && revData.features.length > 0) { 320 const rp = revData.features[0].properties; 321 adr = ((rp.housenumber || '') + ' ' + (rp.street || '') + ' ' + (rp.postcode || '') + ' ' + (rp.city || '')).trim(); 322 } 323 } 324 } catch(errGeo){} 325 } 326 if (!adr) { adr = "Adresse non spécifiée"; } 327 328 currentData.push({ nom: nom, type: typeLabel, dist: calc_dist.toFixed(1), adr: adr, lat: e_lat, lon: e_lon, color: col, geom: polygonPoints }); 329 } 330 } 331 } 332 } catch(e){} 333 334 try { 335 const requeteFiltrefiness = '(hopital OR hospitalier OR clinique OR ehpad OR "maison de retraite" OR "soins de suite" OR readaptation OR convalescence OR "personnes agees" OR dependantes OR "hebergement pour personnes") AND NOT (pharmacie OR officine OR laboratoire OR cabinet OR medecin OR fitness OR gym OR domicile OR infirmiere OR kine)'; 336 const urlKoumoulFiltre = 'https://opendata.koumoul.com/data-fair/api/v1/datasets/etablissements-finess-france/lines?format=geojson&bbox=' + bbox + '&size=1000&q_mode=simple&qs=' + encodeURIComponent(requeteFiltrefiness); 337 const res = await fetch(urlKoumoulFiltre); 338 if(res.ok) { 339 const d = await res.json(); 340 const feats = d.features || []; 341 for (let i = 0; i < feats.length; i++) { 342 const f = feats[i]; 343 if (!f.geometry || !f.geometry.coordinates) continue; 344 const c = f.geometry.coordinates; 345 const dist = getDistance(lat, lon, c[1], c[0]); 346 if(dist <= rayon) { 347 const p = f.properties; 348 const nom = p.rs || p.rslongue || p.libcategetab || "Ãtablissement de soins médicalisés"; 349 350 var existeDeja = currentData.some(function(x) { 351 return x.nom.toLowerCase().includes(nom.toLowerCase().substring(0, 6)) || getDistance(x.lat, x.lon, c[1], c[0]) < 35; 352 }); 353 354 if (!existeDeja) { 355 let adr = p.adresse ? String(p.adresse).trim() : ""; 356 if (!adr) { 357 adr = ((p.nvoie || '') + ' ' + (p.tvoie || '') + ' ' + (p.lvoie || '')).trim(); 358 } 359 if (!adr || adr.toLowerCase().includes("non specifiee")) { 360 try { 361 const revRes = await fetch('https://photon.komoot.io/reverse?lon=' + c[0] + '&lat=' + c[1]); 362 if (revRes.ok) { 363 const revData = await revRes.json(); 364 if (revData.features && revData.features.length > 0) { 365 const rp = revData.features[0].properties; 366 adr = ((rp.housenumber || '') + ' ' + (rp.street || '') + ' ' + (rp.postcode || '') + ' ' + (rp.city || '')).trim(); 367 } 368 } 369 } catch(errGeo){} 370 } 371 if (!adr) adr = "Adresse non répertoriée"; 372 currentData.push({ nom: nom, type: p.libcategetab || "Soins", dist: dist.toFixed(1), adr: adr, lat: c[1], lon: c[0], color: "orange", geom: null });
373 } 374 } 375 } 376 } 377 } catch(e){} 378 379 var coordMap = {}; 380 currentData.forEach(function(item) { 381 var key = parseFloat(item.lat).toFixed(5) + "_" + parseFloat(item.lon).toFixed(5); 382 if (!coordMap[key]) { coordMap[key] = 0; } 383 coordMap[key]++; 384 if (coordMap[key] > 1) { 385 var angle = (coordMap[key] * 2 * Math.PI) / 8; 386 item.lat = parseFloat(item.lat) + 0.00014 * Math.sin(angle); 387 item.lon = parseFloat(item.lon) + 0.00014 * Math.cos(angle); 388 } 389 }); 390 391 resultsZone.style.display = "block"; 392 if (currentData.length === 0) { 393 textList.innerHTML = "<span style='color:red;'>Aucun établissement trouvé dans ce périmètre.</span>"; 394 } else { 395 currentData.forEach(item => { 396 const div = document.createElement('div'); 397 div.style.marginBottom = "8px"; 398 div.innerHTML = "<b>⢠" + item.nom + "</b> (" + item.type + ") â <b>" + item.dist + " m</b><br><span style='color:#666;'>ð Adresse : " + item.adr + "</span>"; 399 textList.appendChild(div); 400 }); 401 } 402 403 if (!map) { 404 map = L.map('immo_map', { zoomControl: true, attributionControl: true }); 405 markerGroup = L.layerGroup().addTo(map); 406 groupScolaire = L.layerGroup().addTo(map); 407 groupCreche = L.layerGroup().addTo(map); 408 groupSoins = L.layerGroup().addTo(map); 409 410 map.on('click', function(e) { 411 if (!modeMesure) return; 412 if (!premierPointMesure) { 413 premierPointMesure = e.latlng; 414 let m = L.circleMarker(premierPointMesure, { radius: 6, color: '#e91e63', fillColor: '#e91e63', fillOpacity: 1 }).addTo(map); 415 mesureMarkers.push(m); 416 } else { 417 let secondPoint = e.latlng; 418 let m = L.circleMarker(secondPoint, { radius: 6, color: '#e91e63', fillColor: '#e91e63', fillOpacity: 1 }).addTo(map); 419 mesureMarkers.push(m); 420 let d = getDistance(premierPointMesure.lat, premierPointMesure.lng, secondPoint.lat, secondPoint.lng); 421 422 if (mesureLigne) map.removeLayer(mesureLigne); 423 mesureLigne = L.polyline([premierPointMesure, secondPoint], { color: '#e91e63', weight: 3, dashArray: '5, 5' }).addTo(map); 424 425 let milieu = L.latLng((premierPointMesure.lat + secondPoint.lat) / 2, (premierPointMesure.lng + secondPoint.lng) / 2); 426 L.popup().setLatLng(milieu).setContent("<b>Distance mesurée : " + d.toFixed(1) + " m</b>").openOn(map); 427 428 premierPointMesure = null; 429 } 430 }); 431 } else { 432 markerGroup.clearLayers(); 433 groupScolaire.clearLayers(); 434 groupCreche.clearLayers(); 435 groupSoins.clearLayers(); 436 if(circle) map.removeLayer(circle); 437 } 438
439 map.setView([lat, lon], 18); 440 const planLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map); 441 const satLayer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'); 442 443 if(!map._layersControl) { 444 var optionsCalques = { 445 "Ãcoles (Violet)": groupScolaire, 446 "Crèches (Vert)": groupCreche, 447 "Soins médicalisés (Orange)": groupSoins 448 }; 449 map._layersControl = L.control.layers({ "Plan standard": planLayer, "Vue Satellite": satLayer }, optionsCalques, { collapsed: false }).addTo(map); 450 } 451 452 L.marker([lat, lon], { icon: createCustomPin("blue") }).addTo(markerGroup).bindPopup("<b>Adresse cible :</b><br>" + currentAdresseSaisie).openPopup(); 453 circle = L.circle([lat, lon], { radius: rayon, color: 'blue', weight: 2, fillColor: '#1a73e8', fillOpacity: 0.04 }).addTo(map); 454 455 currentData.forEach(item => { 456 var groupeCible = groupScolaire; 457 if (item.color === "green") groupeCible = groupCreche; 458 if (item.color === "orange") groupeCible = groupSoins; 459 460 L.marker([item.lat, item.lon], { icon: createCustomPin(item.color) }) 461 .addTo(groupeCible) 462 .bindPopup("<b>" + item.nom + "</b><br>Type: " + item.type + "<br>Distance: " + item.dist + " m<br>Adresse: " + item.adr); 463 464 if (item.geom) { 465 L.polygon(item.geom, { color: item.color, weight: 2, fillColor: item.color, fillOpacity: 0.15 }) 466 .addTo(groupeCible) 467 .bindPopup("<b>Enceinte foncière :</b><br>" + item.nom); 468 } 469 }); 470 471 if (window.immoTitleControl) { map.removeControl(window.immoTitleControl); } 472 window.immoTitleControl = L.control({ position: 'topleft' }); 473 window.immoTitleControl.onAdd = function() { 474 const d = L.DomUtil.create('div', 'map-overlay-title'); 475 d.innerHTML = "<b>Analyse de proximité proposée par <a href='https://antennes-relais.fr' target='_blank'>https://antennes-relais.fr</a> société Immonetic</b>"; 476 return d; 477 }; 478 window.immoTitleControl.addTo(map); 479 480 if (window.immoFooterControl) { map.removeControl(window.immoFooterControl); } 481 window.immoFooterControl = L.control({ position: 'bottomleft' }); 482 window.immoFooterControl.onAdd = function() { 483 const d = L.DomUtil.create('div', 'map-overlay-footer'); 484 d.innerHTML = "Retrouvez nos actualités sur <a href='https://antennes-relais.fr/blog-antennes-relais.html' target='_blank'>notre blog</a>.<br><b style='color:#cc0000;'>Avertissement :</b> Données indicatives soumises à vérification visuelle obligatoire sur site (marge de sécurité de 150m appliquée). Voir nos <a href='https://antennes-relais.fr/outils-negociateurs.php' target='_blank'>conditions d'utilisation</a>."; 485 return d; 486 }; 487 window.immoFooterControl.addTo(map); 488 489 if (window.immoLogoControl) { map.removeControl(window.immoLogoControl); } 490 window.immoLogoControl = L.control({ position: 'bottomright' }); 491 window.immoLogoControl.onAdd = function() { 492 const d = L.DomUtil.create('div', 'map-overlay-logo'); 493 d.innerHTML = "<img src='" + URL_LOGO + "' style='max-height:35px;' alt='Immonetic'>"; 494 return d; 495 }; 496 window.immoLogoControl.addTo(map); 497 498 setTimeout(() => { map.invalidateSize(); }, 300); 499 500 let refValue = refInput ? refInput.value.trim() : ""; 501 let cleanRef = refValue ? refValue.replace(/[^a-zA-Z0-9-_ ]/g, '').replace(/\s+/g, '_') : ""; 502 503 let nameHtml = cleanRef ? cleanRef + ".html" : "carte_proximite_immonetic.html"; 504 let nameCsv = cleanRef ? cleanRef + ".csv" : "liste_etablissements_150m.csv"; 505 let nameKml = cleanRef ? cleanRef + ".kml" : "analyse_proximite_immonetic.kml"; 506 507 dlMap.setAttribute("download", nameHtml); 508 dlCsv.setAttribute("download", nameCsv); 509 dlKml.setAttribute("download", nameKml); 510 511 let csvContent = "\uFEFFNom;Type_Precis;Source;Distance (metres);Adresse\n"; 512 currentData.forEach(item => { 513 var nClean = String(item.nom || "").split('"').join('').split("'").join(' '); 514 var tClean = String(item.type || "").split('"').join('').split("'").join(' '); 515 var aClean = String(item.adr || "").split('"').join('').split("'").join(' '); 516 csvContent += '"' + nClean + '";"' + tClean + '";"Immonetic";"' + item.dist + '";"' + aClean + '"\n'; 517 }); 518 csvContent += '\n"AVERTISSEMENT : Outil d\'information indicatif soumis à contrôle visuel direct sur site . Conditions d\'utilisation disponibles sur : https://antennes-relais.fr/outils-negociateurs.php";;;;\n'; 519 520 const blobCsv = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); 521 if(dlCsv.href) URL.revokeObjectURL(dlCsv.href); 522 dlCsv.href = URL.createObjectURL(blobCsv); 523 524 var kml = []; 525 kml.push('\x3C?xml version="1.0" encoding="UTF-8"?\x3E'); 526 kml.push('\x3Ckml xmlns="http://www.opengis.net/kml/2.2"\x3E\x3CDocument\x3E'); 527 kml.push('\x3Cname\x3E' + (refValue ? refValue : 'Analyse Immonetic - ' + currentAdresseSaisie.split('"').join('')) + '\x3C/name\x3E'); 528 kml.push('\x3CStyle id="bluePoint"\x3E\x3CIconStyle\x3E\x3CIcon\x3E\x3Chref\x3Ehttp://maps.google.com/mapfiles/kml/paddle/blu-circle.png\x3C/href\x3E\x3C/Icon\x3E\x3C/IconStyle\x3E\x3C/Style\x3E'); 529 kml.push('\x3CStyle id="purplePoint"\x3E\x3CIconStyle\x3E\x3CIcon\x3E\x3Chref\x3Ehttp://maps.google.com/mapfiles/kml/paddle/purple-circle.png\x3C/href\x3E\x3C/Icon\x3E\x3C/IconStyle\x3E\x3C/Style\x3E'); 530 kml.push('\x3CStyle id="greenPoint"\x3E\x3CIconStyle\x3E\x3CIcon\x3E\x3Chref\x3Ehttp://maps.google.com/mapfiles/kml/paddle/grn-circle.png\x3C/href\x3E\x3C/Icon\x3E\x3C/IconStyle\x3E\x3C/Style\x3E'); 531 kml.push('\x3CStyle id="orangePoint"\x3E\x3CIconStyle\x3E\x3CIcon\x3E\x3Chref\x3Ehttp://maps.google.com/mapfiles/kml/paddle/ylw-circle.png\x3C/href\x3E\x3C/Icon\x3E\x3C/IconStyle\x3E\x3C/Style\x3E'); 532 kml.push('\x3CStyle id="zoneCircle"\x3E\x3CLineStyle\x3E\x3Ccolor\x3Effe8731a\x3C/color\x3E\x3Cwidth\x3E3\x3C/width\x3E\x3C/LineStyle\x3E\x3CPolyStyle\x3E\x3Ccolor\x3E40e8731a\x3C/color\x3E\x3C/PolyStyle\x3E\x3C/Style\x3E'); 533 kml.push('\x3CPlacemark\x3E\x3Cname\x3EPoint Pivot Cible\x3C/name\x3E\x3Cdescription\x3E' + currentAdresseSaisie.split('"').join('') + '\x3C/description\x3E\x3CstyleUrl\x3E#bluePoint\x3C/styleUrl\x3E\x3CPoint\x3E\x3Ccoordinates\x3E' + lon + ',' + lat + ',0\x3C/coordinates\x3E\x3C/Point\x3E\x3C/Placemark\x3E'); 534 kml.push('\x3CPlacemark\x3E\x3Cname\x3EPerimetre d\'inclusion (' + rayon + 'm)\x3C/name\x3E\x3CstyleUrl\x3E#zoneCircle\x3C/styleUrl\x3E\x3CPolygon\x3E\x3Ctessellate\x3E1\x3C/tessellate\x3E\x3CouterBoundaryIs\x3E\x3CLinearRing\x3E\x3Ccoordinates\x3E' + generateKMLCircle(lat, lon, rayon) + '\x3C/coordinates\x3E\x3C/LinearRing\x3E\x3C/outerBoundaryIs\x3E\x3C/Polygon\x3E\x3C/Placemark\x3E'); 535 536 var etsCount = 1; 537 currentData.forEach(function(m) { 538 var sId = m.color === "purple" ? "#purplePoint" : (m.color === "green" ? "#greenPoint" : "#orangePoint"); 539 var etsName = "ETS" + etsCount; 540 etsCount++; 541 kml.push('\x3CPlacemark\x3E\x3Cname\x3E' + etsName + '\x3C/name\x3E\x3Cdescription\x3ENom complet : ' + String(m.nom).split('"').join('') + ' \nType : ' + m.type + ' \nDistance : ' + m.dist + ' m \nAdresse : ' + String(m.adr).split('"').join('') + '\x3C/description\x3E\x3CstyleUrl\x3E' + sId + '\x3C/styleUrl\x3E\x3CPoint\x3E\x3Ccoordinates\x3E' + m.lon + ',' + m.lat + ',0\x3C/coordinates\x3E\x3C/Point\x3E\x3C/Placemark\x3E'); 542 }); 543 kml.push('\x3C/Document\x3E\x3C/kml\x3E'); 544 545 const blobKml = new Blob([kml.join('\n')], { type: 'application/vnd.google-earth.kml+xml;charset=utf-8;' }); 546 if(dlKml.href) URL.revokeObjectURL(dlKml.href); 547 dlKml.href = URL.createObjectURL(blobKml); 548 549 var h = []; 550 h.push('\x3C!DOCTYPE html\x3E\x3Chtml lang="fr"\x3E\x3Chead\x3E\x3Cmeta charset="UTF-8"\x3E'); 551 h.push('\x3Ctitle\x3EAnalyse Cartographique - Immonetic\x3C/title\x3E'); 552 h.push('\x3Clink rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" /\x3E'); 553 h.push('\x3Cscript src="https://unpkg.com/[email protected]/dist/leaflet.js"\x3E\x3C/script\x3E'); 554 h.push('\x3Cstyle\x3Ebody{margin:0;padding:0;} #map{width:100vw;height:100vh;} .o-box{background:white;padding:10px 14px;border-radius:6px;box-shadow:0 2px 6px rgba(0,0,0,0.25);font-size:13px;max-width:350px;font-family:sans-serif;} .o-foot{background:white;padding:8px 12px;border-radius:4px;box-shadow:0 2px 6px rgba(0,0,0,0.2);font-size:10px;font-family:sans-serif;max-width:320px;line-height:1.4;}\x3C/style\x3E'); 555 h.push('\x3C/head\x3E\x3Cbody\x3E'); 556 h.push('\x3Cbutton id="ruler_btn" style="position:absolute; top:50%; right:10px; transform:translateY(-50%); z-index:2000 !important; background:white; border:2px solid rgba(0,0,0,0.2); border-radius:4px; padding:8px 12px; font-weight:bold; cursor:pointer; font-family:sans-serif; font-size:12px; color:black; box-shadow:0 2px 6px rgba(0,0,0,0.3);"\x3Eð Règle de mesure\x3C/button\x3E'); 557 h.push('\x3Cdiv id="map"\x3E\x3C/div\x3E'); 558 h.push('\x3Cscript\x3E'); 559 h.push('var map = L.map("map").setView([' + lat + ',' + lon + '], 18);'); 560 h.push('var plan = L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png").addTo(map);'); 561 h.push('var sat = L.tileLayer("https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}");'); 562 h.push('var gScol = L.layerGroup().addTo(map); var gCrech = L.layerGroup().addTo(map); var gSoin = L.layerGroup().addTo(map);'); 563 h.push('L.control.layers({"Plan standard":plan,"Vue Satellite":sat},{"Ãcoles (Violet)":gScol,"Crèches (Vert)":gCrech,"Soins médicalisés (Orange)":gSoin},{collapsed:false}).addTo(map);'); 564 h.push('var title = L.control({position:"topleft"}); title.onAdd = function(){ var d = L.DomUtil.create("div","o-box"); d.innerHTML="<b>Analyse de proximité proposée par \x3Ca href=\'https://antennes-relais.fr\' target=\'_blank\'\x3Ehttps://antennes-relais.fr\x3C/a\x3E société Immonetic</b><br><small>Adresse : ' + currentAdresseSaisie.split('"').join('').split("'").join(' ') + '</small>"; return d; }; title.addTo(map);'); 565 h.push('var footer = L.control({position:"bottomleft"}); footer.onAdd = function(){ var d = L.DomUtil.create("div","o-foot"); d.innerHTML="Retrouvez nos actualités sur \x3Ca href=\'https://antennes-relais.fr/blog-antennes-relais.html\' target=\'_blank\'\x3Enotre blog\x3C/a\x3E.<br>\x3Cb style=\'color:#cc0000;\'\x3EAvertissement :\x3C/b\x3E Données indicatives soumises à vérification visuelle obligatoire sur site (marge de sécurité de 150m appliquée). Voir nos \x3Ca href=\'https://antennes-relais.fr/outils-negociateurs.php\' target=\'_blank\'\x3Econditions d\'utilisation\x3C/a\x3E."; return d; }; footer.addTo(map);'); 566 h.push('var logo = L.control({position:"bottomright"}); logo.onAdd = function(){ var d = L.DomUtil.create("div"); d.innerHTML="\x3Cdiv style=\'background:rgba(255,255,255,0.9);padding:5px;border-radius:4px;box-shadow:0 1px 5px rgba(0,0,0,0.2);\'\x3E<img src=\'' + URL_LOGO + '\' style=\'max-height:45px;\'\x3E</div>"; return d; }; logo.addTo(map);'); 567 h.push('L.marker([' + lat + ',' + lon + '],{icon:L.divIcon({className:"c-p-b",html:\'\x3Csvg width=\"30\" height=\"42\" viewBox=\"0 0 30 42\"\x3E\x3Cpath d=\"M15 0C6.71 0 0 6.71 0 15C0 26.25 15 42 15 42C15 42 30 26.25 30 15C30 6.71 23.29 0 15 0ZM15 20C12.24 20 10 17.76 10 15C10 12.24 12.24 10 15 10C17.76 10 20 12.24 20 15C20 17.76 17.76 20 15 20Z\" fill=\"#1a73e8\"/\x3E\x3Ccircle cx=\"15\" cy=\"15\" r=\"4\" fill=\"#FFFFFF\"/\x3E\x3C/svg\x3E\',iconSize:[30,42],iconAnchor:[15,42],popupAnchor:[0,-38]})}).addTo(map).bindPopup("<b>Point Pivot :</b><br>' + currentAdresseSaisie.split('"').join('').split("'").join(' ') + '").openPopup();'); 568 h.push('L.circle([' + lat + ',' + lon + '],{radius:' + rayon + ',color:"blue",weight:2,fillColor:"#1a73e8",fillOpacity:0.04}).addTo(map);'); 569 h.push('var markersData = ' + JSON.stringify(currentData) + ';'); 570 h.push('markersData.forEach(function(m) {'); 571 h.push(' var tG = gScol; if(m.color==="green") tG = gCrech; if(m.color==="orange") tG = gSoin;'); 572 h.push(' var hexColor = m.color === "purple" ? "#a142f4" : (m.color === "orange" ? "#ff9900" : "#34a853");'); 573 h.push(' L.marker([m.lat, m.lon],{icon:L.divIcon({className:"c-pin",html:\'\x3Csvg width=\"30\" height=\"42\" viewBox=\"0 0 30 42\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"\x3E\x3Cpath d=\"M15 0C6.71 0 0 6.71 0 15C0 26.25 15 42 15 42C15 42 30 26.25 30 15C30 6.71 23.29 0 15 0ZM15 20C12.24 20 10 17.76 10 15C10 12.24 12.24 10 15 10C17.76 10 20 12.24 20 15C20 17.76 17.76 20 15 20Z\" fill=\"\' + hexColor + \'\"/\x3E\x3Ccircle cx=\"15\" cy=\"15\" r=\"4\" fill=\"#FFFFFF\"/\x3E\x3C/svg\x3E\',iconSize:[30,42],iconAnchor:[15,42],popupAnchor:[0,-38]})}
573).addTo(tG).bindPopup("\x3Cb\x3E" + m.nom + "\x3C/b\x3E\x3Cbr\x3EType: " + m.type + "\x3Cbr\x3EDistance: " + m.dist + " m\x3Cbr\x3EAdresse: " + m.adr);'); 574 h.push(' if(m.geom) { L.polygon(m.geom, {color: m.color, weight: 2, fillColor: m.color, fillOpacity: 0.15}).addTo(tG).bindPopup("\x3Cb\x3EEnceinte foncière :\x3C/b\x3E\x3Cbr\x3E" + m.nom); }'); 575 h.push('});'); 576 h.push('var modeM = false; var pPt = null; var mMs = []; var mLg = null;'); 577 h.push('document.getElementById("ruler_btn").addEventListener("click", function() {'); 578 h.push(' modeM = !modeM;'); 579 h.push(' if(modeM) { this.innerText = "ð Règle active (Cliquez 2 points)"; this.style.background = "#e91e63"; this.style.color = "white"; map.getContainer().style.cursor = "crosshair"; }'); 580 h.push(' else { this.innerText = "ð Règle de mesure"; this.style.background = "white"; this.style.color = "black"; map.getContainer().style.cursor = ""; pPt = null; mMs.forEach(function(mk){map.removeLayer(mk);}); mMs=[]; if(mLg){map.removeLayer(mLg);mLg=null;} }'); 581 h.push('});'); 582 h.push('map.on("click", function(ev) {'); 583 h.push(' if(!modeM) return;'); 584 h.push(' if(!pPt) { pPt = ev.latlng; var mk = L.circleMarker(pPt, {radius:6, color:"#e91e63", fillColor:"#e91e63", fillOpacity:1}).addTo(map); mMs.push(mk); }'); 585 h.push(' else { var sPt = ev.latlng; var mk = L.circleMarker(sPt, {radius:6, color:"#e91e63", fillColor:"#e91e63", fillOpacity:1}).addTo(map); mMs.push(mk); var dst = map.distance(pPt, sPt); if(mLg) map.removeLayer(mLg); mLg = L.polyline([pPt, sPt], {color:"#e91e63", weight:3, dashArray:"5,5"}).addTo(map); var ml = L.latLng((pPt.lat+sPt.lat)/2, (pPt.lng+sPt.lng)/2); L.popup().setLatLng(ml).setContent("\x3Cb\x3EDistance : " + dst.toFixed(1) + " m\x3C/b\x3E").openOn(map); pPt = null; }'); 586 h.push('});'); 587 h.push('\x3C/script\x3E\x3C/body\x3E\x3C/html\x3E'); 588 589 const blobMap = new Blob([h.join('\n')], { type: 'text/html;charset=utf-8;' }); 590 if(dlMap.href) URL.revokeObjectURL(dlMap.href); 591 dlMap.href = URL.createObjectURL(blobMap); 592 593 dlBox.style.display = "flex"; 594 resultsZone.style.display = "block"; 595 596 } catch (err) { 597 console.error(err); 598 alert("Erreur de calcul."); 599 } finally { 600 btn.innerText = "Lancer l'extraction"; 601 btn.disabled = false; 602 } 603 }); 604 } 605 606 if (document.readyState === "complete" || document.readyState === "interactive") { 607 executerScriptAnalyse(); 608 } else { 609 window.addEventListener('DOMContentLoaded', executerScriptAnalyse); 610 } 611})(); 612</script>
612</div><p><br></p></div></div></div><div class="twpara-row row-fluid"><div id="0xTLgHjf" class="span12 tw-para "><h2><span style="font-size:18px;">Compresser fichier </span></h2><div class="pobj obj-before" style="text-align:center;"><picture><source type="image/webp" srcset="_media/img/thumb/kling-20260702-image-image-pour-442-1.webp 160w,_media/img/small/kling-20260702-image-image-pour-442-1.webp 480w,_media/img/medium/kling-20260702-image-image-pour-442-1.webp 768w,_media/img/large/kling-20260702-image-image-pour-442-1.webp 1024w,_media/img/xlarge/kling-20260702-image-image-pour-442-1.webp 1205w"><source type="image/png" srcset="_media/img/thumb/kling-20260702-image-image-pour-442-1.png 160w,_media/img/small/kling-20260702-image-image-pour-442-1.png 480w,_media/img/medium/kling-20260702-image-image-pour-442-1.png 768w,_media/img/large/kling-20260702-image-image-pour-442-1.png 1024w,_media/img/xlarge/kling-20260702-image-image-pour-442-1.png 1205w"><img src="_media/img/thumb/kling-20260702-image-image-pour-442-1.png" width="120" height="160" style="max-width:100%;width:120px;" alt="" loading="lazy"></picture></div><div class="ptext"><p><b>Confidentialité et sécurité de traitement :</b>Pour garantir une confidentialité absolue (100 % sécurisée), la compression est réalisée directement au sein de votre navigateur web. Le document PDF est traité localement par la mémoire vive de votre ordinateur grâce à des algorithmes de re-compression d'images binaires. <b>Le fichier ne quitte jamais votre poste de travail et aucune donnée ne transite sur Internet.</b> Vos baux, pièces d'identité et documents financiers restent strictement privés, vous assurant un respect rigoureux du secret professionnel et une conformité native avec le RGPD.</p><p><i>(Le test : vous pouvez utiliser ce compresseur en coupant complètement votre connexion Internet ou en Mode Avion, il fonctionnera parfaitement).</i></p><p><!-- 1. CHARGEMENT DES BIBLIOTHÃQUES SÃCURISÃES -->
613<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.min.js"></script>
vendor: 2 bytes, line 613
613
614<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
614 615 616<!-- 2. FEUILLE DE STYLE (DESIGN DE L'OUTIL) --> 617<style> 618 .compress-container { font-family: 'Segoe UI', Arial, sans-serif; max-width: 650px; margin: 20px auto; padding: 25px; background: #f8f9fa; border-radius: 12px; border: 1px solid #dadce0; color: #333; box-sizing: border-box; } 619 .compress-zone { border: 2px dashed #1a73e8; padding: 30px 20px; background: #fff; border-radius: 8px; text-align: center; cursor: pointer; transition: background 0.2s; } 620 .compress-zone:hover { background: #f1f3f4; } 621 .compress-icon { font-size: 40px; color: #1a73e8; margin-bottom: 10px; } 622 .compress-label { font-weight: 600; font-size: 14px; color: #3c4043; } 623 .compress-browse-btn { width: 100%; padding: 14px; background: #6c757d; color: white; border: none; border-radius: 6px; font-weight: bold; font-size: 15px; cursor: pointer; margin-top: 10px; } 624 .compress-meta-box { margin-top: 15px; padding: 10px; background: #e8f0fe; border-radius: 6px; font-size: 13px; display: none; text-align: left; border: 1px solid #1a73e8; } 625 .compress-options { margin-top: 20px; display: flex; flex-direction: column; gap: 12px; } 626 .compress-select { width: 100%; padding: 10px; border-radius: 6px; border: 1px solid #ccc; background: white; font-size: 14px; font-family: inherit; } 627 .compress-action-btn { width: 100%; padding: 14px; background: #1a73e8; color: white; border: none; border-radius: 6px; font-weight: bold; font-size: 15px; cursor: pointer; margin-top: 15px; } 628 .compress-action-btn:disabled { background: #9aa0a6; cursor: not-allowed; } 629 .compress-progress-wrapper { margin-top: 20px; display: none; } 630 .compress-bar-bg { width: 100%; height: 8px; background: #dadce0; border-radius: 4px; overflow: hidden; margin-top: 6px; } 631 .compress-bar-fill { width: 0%; height: 100%; background: #1a73e8; transition: width 0.1s; } 632 .compress-status-text { font-size: 12px; color: #5f6368; font-weight: bold; text-align: center; } 633 .compress-success-box { margin-top: 20px; padding: 15px; background: #e6f4ea; border: 1px solid #137333; border-radius: 8px; display: none; text-align: center; } 634 .compress-success-text { color: #137333; font-weight: bold; font-size: 14px; margin-bottom: 12px; } 635 .compress-dl-btn { display: inline-block; padding: 10px 20px; background: #137333; color: white; text-decoration: none; font-weight: bold; border-radius: 4px; font-size: 13px; } 636 .compress-secure-banner { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 10px; background: #e6f4ea; border-left: 4px solid #137333; border-radius: 4px; font-size: 11px; color: #137333; margin-top: 20px; font-weight: 500; } 637</style> 638 639<!-- 3. INTERFACE VISUELLE (HTML) --> 640<div class="compress-container"> 641 <div class="compress-zone" id="comp_drop_zone"> 642 <div class="compress-icon">ð</div> 643 <div class="compress-label" id="comp_drop_label">Glissez-déposez votre fichier PDF ici</div> 644 </div> 645 646 <button type="button" class="compress-browse-btn" id="comp_btn_parcourir">Ou cliquez ici pour parcourir vos fichiers</button> 647 <input type="file" id="comp_file_input" style="display:none;" accept="application/pdf"> 648 649 <div class="compress-meta-box" id="comp_meta_box"></div> 650 651 <div class="compress-options"> 652 <div> 653 <label class="compress-label" style="display:block; margin-bottom:5px;">Niveau de compression souhaité :</label> 654 <select id="comp_compress_level" class="compress-select"> 655 <option value="recommandee">Haute Qualité Pro (Rendu ultra-net / Compression optimisée)</option> 656 <option value="forte">Compression standard (Qualité écran intermédiaire)</option> 657 </select> 658 </div> 659 <button id="comp_start_compress_btn" class="compress-action-btn" disabled>Compresser le document PDF</button> 660 </div> 661 662 <div class="compress-progress-wrapper" id="comp_progress_wrapper"> 663 <div class="compress-status-text" id="comp_status_txt">Initialisation du traitement...</div> 664 <div class="compress-bar-bg"> 665 <div class="compress-bar-fill" id="comp_bar_fill"></div> 666 </div> 667 </div> 668 669 <div class="compress-success-box" id="comp_success_box"> 670 <div class="compress-success-text" id="comp_success_txt">Fichier compressé avec succès !</div>
671 <a id="comp_download_link" href="#" class="compress-dl-btn">ð¥ Télécharger le PDF Optimisé</a> 672 </div> 673</div> 674 675<!-- 4. LOGIQUE INTERNE AJUSTÃE (HAUTE NETTETÃ) -->
676<script> 677(function() { 678 function initialiserCompresseur() { 679 const fileInput = document.getElementById('comp_file_input'); 680 const startBtn = document.getElementById('comp_start_compress_btn'); 681 const btnParcourir = document.getElementById('comp_btn_parcourir'); 682 683 if (!fileInput || !startBtn || !btnParcourir) { 684 setTimeout(initialiserCompresseur, 250); 685 return; 686 } 687 688 const dropZone = document.getElementById('comp_drop_zone'); 689 const dropLabel = document.getElementById('comp_drop_label'); 690 const metaBox = document.getElementById('comp_meta_box'); 691 const levelSelect = document.getElementById('comp_compress_level'); 692 const progressWrapper = document.getElementById('comp_progress_wrapper'); 693 const statusTxt = document.getElementById('comp_status_txt'); 694 const barFill = document.getElementById('comp_bar_fill'); 695 const successBox = document.getElementById('comp_success_box'); 696 const successTxt = document.getElementById('comp_success_txt'); 697 const downloadLink = document.getElementById('comp_download_link'); 698 699 pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.worker.min.js'; 700 701 let fichierSelectionne = null; 702 703 btnParcourir.addEventListener('click', function() { fileInput.click(); }); 704 fileInput.addEventListener('change', function(e) { if (e.target.files.length > 0) chargerFichierPDF(e.target.files[0]); }); 705 dropZone.addEventListener('dragover', function(e) { e.preventDefault(); dropZone.style.background = '#e8f0fe'; }); 706 dropZone.addEventListener('dragleave', function(e) { e.preventDefault(); dropZone.style.background = '#fff'; }); 707 dropZone.addEventListener('drop', function(e) { 708 e.preventDefault(); dropZone.style.background = '#fff'; 709 if (e.dataTransfer.files.length > 0) chargerFichierPDF(e.dataTransfer.files[0]); 710 }); 711 712 function chargerFichierPDF(file) { 713 if (file.type !== 'application/pdf') { alert('Format PDF uniquement.'); return; } 714 fichierSelectionne = file; 715 let sizeMo = (file.size / (1024 * 1024)).toFixed(2); 716 dropLabel.innerText = 'Fichier prêt'; 717 metaBox.innerHTML = 'ð <b>Nom :</b> ' + file.name + '<br>âï¸ <b>Poids d\'origine :</b> ' + sizeMo + ' Mo'; 718 metaBox.style.display = 'block'; 719 startBtn.disabled = false; 720 successBox.style.display = 'none'; 721 progressWrapper.style.display = 'none'; 722 } 723 724 startBtn.addEventListener('click', async function() { 725 if (!fichierSelectionne) return; 726 727 startBtn.disabled = true; 728 fileInput.disabled = true; 729 successBox.style.display = 'none'; 730 progressWrapper.style.display = 'block'; 731 barFill.style.width = '0%'; 732 733 try { 734 let fileReader = new FileReader(); 735 fileReader.onload = async function() { 736 try { 737 let typedarray = new Uint8Array(this.result); 738 let loadingTask = pdfjsLib.getDocument({data: typedarray}); 739 let pdf = await loadingTask.promise; 740 let totalPages = pdf.numPages; 741 742 const { jsPDF } = window.jspdf; 743 let docPdf = null; 744 745 // NOUVEAUX RÃGLAGES AGRESSIFS SUR LA NETTETà (Cible 200 DPI+) 746 let scaleRatio = 2.2; // Rendu très pixel-dense pour lisser les polices 747 let imgQuality = 0.82; // Qualité JPEG élevée pour éliminer le "baveux" autour du texte 748 749 if (levelSelect.value === 'forte') { 750 scaleRatio = 1.5; // Ãquivalent à l'ancienne compression recommandée 751 imgQuality = 0.65; 752 } 753 754 for (let i = 1; i <= totalPages; i++) { 755 statusTxt.innerText = 'Rendu Haute Définition de la page ' + i + ' / ' + totalPages + '...'; 756 757 let page = await pdf.getPage(i); 758 let viewport = page.getViewport({ scale: scaleRatio }); 759 760 let canvas = document.createElement('canvas'); 761 let ctx = canvas.getContext('2d'); 762
763 // Amélioration de l'anti-aliasing natif du navigateur 764 ctx.imageSmoothingEnabled = true; 765 ctx.imageSmoothingQuality = 'high'; 766 767 canvas.height = viewport.height; 768 canvas.width = viewport.width; 769 770 let renderContext = { canvasContext: ctx, viewport: viewport }; 771 await page.render(renderContext).promise; 772 773 let jpegUrl = canvas.toDataURL('image/jpeg', imgQuality); 774 let orientationMode = viewport.width > viewport.height ? 'l' : 'p'; 775 776 if (i === 1) { 777 docPdf = new jsPDF({ orientation: orientationMode, unit: 'px', format: [viewport.width, viewport.height], compress: true }); 778 } else { 779 docPdf.addPage([viewport.width, viewport.height], orientationMode); 780 } 781 782 docPdf.addImage(jpegUrl, 'JPEG', 0, 0, viewport.width, viewport.height, undefined, 'SLOW'); 783 784 let pct = Math.round((i / totalPages) * 100); 785 barFill.style.width = pct + '%'; 786 await new Promise(resolve => setTimeout(resolve, 15)); 787 } 788 789 statusTxt.innerText = 'Finalisation du rendu Pro...'; 790 let blobOutput = docPdf.output('blob'); 791 792 let sizeMoAncien = (fichierSelectionne.size / (1024 * 1024)).toFixed(2); 793 let sizeMoNouveau = (blobOutput.size / (1024 * 1024)).toFixed(2); 794 795 if (downloadLink.href) { URL.revokeObjectURL(downloadLink.href); } 796 downloadLink.href = URL.createObjectURL(blobOutput); 797 798 let baseName = fichierSelectionne.name.substring(0, fichierSelectionne.name.lastIndexOf('.')); 799 downloadLink.setAttribute('download', baseName + '_compresse.pdf'); 800 801 successTxt.innerHTML = 'ð¯ Opération réussie !<br>âï¸ Avant : ' + sizeMoAncien + ' Mo â <b>Après : ' + sizeMoNouveau + ' Mo</b>'; 802 successBox.style.display = 'block'; 803 progressWrapper.style.display = 'none'; 804 805 } catch (errInner) { 806 console.error(errInner); 807 alert('Erreur lors du traitement binaire.'); 808 } finally { 809 startBtn.disabled = false; 810 fileInput.disabled = false; 811 } 812 }; 813 fileReader.readAsArrayBuffer(fichierSelectionne); 814 } catch (errOuter) { 815 console.error(errOuter); 816 startBtn.disabled = false; 817 fileInput.disabled = false; 818 } 819 }); 820 } 821 822 if (document.readyState === "complete" || document.readyState === "interactive") { 823 initialiserCompresseur(); 824 } else { 825 window.addEventListener('DOMContentLoaded', initialiserCompresseur); 826 } 827})(); 828</script>
828</p></div></div></div><div style="text-align:right;min-height:28px"><div class="twsharebtnbar-center"><div class="twsharebtn-margin wa-btn"><a href="whatsapp://send?text=Outils+n%C3%A9gociateurs+Etude+ZR+automatis%C3%A9e%20%0Ahttps%3A%2F%2Fantennes-relais.fr%2Foutils-negociateurs.html%235XxINOXi" class="wa_btn"><span>Partager</span></a></div><div class="twsharebtn-margin"><div id="fb-root"></div>
828<script async defer crossorigin="anonymous" src="https://connect.facebook.net/fr_FR/sdk.js#xfbml=1&version=v12.0"></script>
828<div class="fb-share-button" data-href="https://antennes-relais.fr/outils-negociateurs.html#5XxINOXi" data-layout="button" data-size="small"><a target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent("https://antennes-relais.fr/outils-negociateurs.html#5XxINOXi") + '&src=sdkpreparse" class="fb-xfbml-parse-ignore" rel="noopener">Facebook</a></div></div><div class="twsharebtn-margin"><div class="fb-like" data-href="https://antennes-relais.fr/outils-negociateurs.html#5XxINOXi" data-width="100" data-layout="button" data-action="like" data-size="small" data-share="false">Facebook</div></div><div class="twsharebtn-margin"><a href="https://twitter.com/share" class="twitter-share-button" data-url="https://antennes-relais.fr/outils-negociateurs.html#5XxINOXi" data-lang="fr">Tweet</a></div><div class="twsharebtn-margin">
828<script src="https://platform.linkedin.com/in.js" type="text/javascript"> lang: fr_FR</script>
828<script type="IN/Share" data-counter="right"></script>
828</div><div class="twsharebtn pi-btn"><a data-pin-do="buttonPin" data-pin-count="not shown" data-pin-lang="fr" href="https://www.pinterest.com/pin/create/button/?url=https://antennes-relais.fr/outils-negociateurs.html#5XxINOXi&description=Outils+n%C3%A9gociateurs+Etude+ZR+automatis%C3%A9e">Pinterest</a></div></div></div></div><div id="top-sb" class="span3"><div id="SXkEnN8J" class="tw-para "><h2><span style="font-size:18px;">Présentation Vidéo</span></h2><div class="pobj obj-before" style="width:480px;margin-left:auto;margin-right:auto;"><div id="vid_SXkEnN8J" class="wrapper-with-intrinsic-ratio" style="padding-top:30px; padding-bottom:56.25%"><iframe class="element-to-stretch" width="100%" height="100%" src="https://www.youtube.com/embed/W8AfhI9sv1U?fs=1" frameborder="0" allowfullscreen></iframe></div></div><div class="ptext">- <a href="_iserv/dlfiles/dl.php?ddl=documentation-immonetic-zr-automatisee.pdf" id="lnk256d2e73">plaquette présentation</a><div>- <a href="_iserv/dlfiles/dl.php?ddl=engagements-confidentialite-immonetic.pdf" id="lnk056e45d2">engagements de confidentialité</a></div></div></div></div></div></div></main><footer><div id="footersmall" class="row-fluid"><div id="foot-sec1" class="span6 ">© Copyright Antennes Relais. Immonetic - Tous droits réservés.<div><a href="https://antennes-relais.fr/_iserv/twsc/withdrawal.php?lang=fr" title="Exercer votre droit de rétractation en 1 clic" id="lnk952f825c">Exercer votre droit de rétractation en 1 clic</a></div></div><div id="foot-sec2" class="span6 "><div style="text-align: right; "><a href="_tos.html" title="conditions générales de vente et d'utilisation" rel="nofollow">CGUV</a></div></div></div><div id="footerfat" class="row-fluid"><div class="row-fluid"><div id="footerfat_s1" class="span4 tw-para"><span style="color:#DDDDDD;">Contactez-nous</span><hr><span style="color:#FF9900;">Immonetic<br>32 bd de Strasbourg - 75010 Paris<br><span style="font-size:1.33em;">â </span>(+33) 07 56 98 59 56 </span><br><a onclick="javascript:return(decMail2(this));" href="znvygb?pbagnpg#nagraarf-erynvf.se" title="contact">[email protected]</a> <div><br></div><div>Ils parlent de nous<ul><li><a href="https://www.lepoint.fr/stories/tout-savoir-des-antennes-relais-le-guichet-immonetic-30-07-2024-2566752_3919.php" id="lnkce64e12b">Le Point</a></li><li><a href="https://monimmeuble.com/actualite/installation-dantennes-relais-un-nouveau-service-pour-les-coproprietes" title="mise en avant de notre service optim" rel="nofollow" id="lnka29004e3">Copropriété</a></li><li><a href="https://lavienumerique.com/articles/199639/antennes-relaisfr-by-immonetic-la-nouvelle-plateforme-de-reference-pour-obtenir-des-informations-objectives-sur-les-antennes-relais.html" rel="nofollow" id="lnk16826ad9">Vie numérique</a></li><li><a href="https://www.connaitre-ses-droits.net/bail-dantenne-relais-sur-un-terrain-prix-et-conditions-de-la-location/" rel="nofollow" id="lnk6f180528">Droits</a></li><li><a href="https://www.copropriete-travaux.com/amener-un-revenu-supplementaire-a-la-copropriete/" title="https://www.copropriete-travaux.com/amener-un-revenu-supplementaire-a-la-copropriete/" rel="nofollow" id="lnk3dc1bd48">copropriété travaux</a></li><li><a href="https://www.lebloginfos.fr/les-antennes-relais-pionnieres-de-la-communication-moderne/" rel="nofollow" id="lnk2a8d8543">Blog</a></li></ul></div></div><div id="footerfat_s2" class="span4 tw-para"><p><font color="#dddddd">Notice Légale</font></p><hr><ul><li><a href="mentions-legales-et-donnees-personnelles.html" title="Notice Légale" rel="nofollow" id="lnkc532bf80">Notice Légale</a></li><li><a href="_tos.html" id="lnk388e3a40" rel="nofollow">CGUV</a></li><li><span style="color:#FF9900;">Crédit Photo AdobeStock_261994683</span><span style="color:#FF9966;"> </span></li></ul></div><div id="footerfat_s3" class="span4 tw-para"><font color="#dddddd">Nos rubriques</font><div><hr><ul><li><a href="guide-complet.html" id="lnk7c904adf">Guide</a></li><li><a href="https://forum.antennes-relais.fr" id="lnk87af49c7">Forum</a></li><li><a href="./" title="acceuil antennes relais">Accueil </a></li><li><a href="veille-antennes-relais.html" id="lnk08016ee7">Veille</a></li><li><a href="posez-votre-question-antennes-relais.html" title="Une question sur les antennes relais" id="lnk141bbcda">Question</a></li><li><a href="#?twscroll" title="services antennes relais pour opérateur et gestionnaire dâinfrastru
828ctures" id="lnk48b76e6e">Services opérateurs</a> </li><li><a href="mesures-de-champs-radioelectriques-protocole-anfr.html" title="Services antennes relais pour propriétaire">Services propriétaire</a></li><li><a href="actualites-jurisprudence-antennes-relais-outils-aide-decision.html" title="actualités antennes relais">Actualités</a></li><li><a href="immonetic-expertise-antennes-relais.html" title="Immonetic" rel="nofollow">Qui sommes nous ?</a></li><li><a href="_iserv/dlfiles/dl.php?ddl=cp-immonetic-20230829-hd.pdf" title="communiqué de presse antennes relais" id="lnkf1a05920">Plaquette</a></li><li><a href="contact-immonetic-demande-information-antennes-relais.html" title="Contac" id="lnk177a7f0e">Contact</a><!-- Sendinblue Conversations {literal} -->
829<script> 830 (function(d, w, c) { 831 w.SibConversationsID = '6326c06bb641c1495d1c9a47'; 832 w[c] = w[c] || function() { 833 (w[c].q = w[c].q || []).push(arguments); 834 }; 835 var s = d.createElement('script'); 836 s.async = true; 837 s.src = 'https://conversations-widget.sendinblue.com/sib-conversations.js'; 838 if (d.head) d.head.appendChild(s); 839 })(document, window, 'SibConversations'); 840</script>
840 841<!-- /Sendinblue Conversations {/literal} -->
841<script type="text/javascript"> 842 var _ae = { 843 "pid":"666a76c09cc1f071c996f3f3", 844 }; 845 (function() { 846 var element = document.createElement('script'); element.type = 'text/javascript'; element.async = true; 847 element.src = '//static.affilae.com/ae-v3.5.js'; 848 var scr = document.getElementsByTagName('script')[0]; scr.parentNode.insertBefore(element, scr); 849 })(); 850</script>
850<!-- Entrez le script du champ ici. Ce contenu sera inséré tel quel dans votre site. //--></li></ul></div></div></div></div></footer></div></div>
850<script src="_scripts/jquery/jquery.min.js"></script>
850<script src="_scripts/jquery/ui/tw-dialog.js"></script>
850<script src="_scripts/bootstrap/js/bootstrap.min.js"></script>
850<script async defer src="https://assets.pinterest.com/js/pinit.js"></script>
850<script>jQuery(window).on("load",function(){$(".IN-widget").css("vertical-align","top");$(".twitter-tweet-button").css("vertical-align","top");});!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");function ucc(){var a=sessionStorage.getItem("9d8b-cart")||"";if(!a||a=="")b=0;else{var b=0;var c=0;do{c=a.indexOf(")",c);if(c>0){e=c-1;while(e>=0&&a[e]!="=")e--;b+=parseInt(a.substring(e+1,c));c++}}while(c>0)}$("#sc_pcount").text(b)}function showParag(id){if(id.length>1&&id[0]!="#")id="#"+id;var p=$(id).is("a")?$(id).parent().parent():$(id).parent();$("html,body").animate({scrollTop:p.offset().top},"slow");}$("a[href$='?twscroll']").click(function(){var bk=($(this).attr("href")).split("?")[0];$(this).attr("href",bk);if(bk=="#"){$("html,body").animate({scrollTop:0},"slow");}else{if($(bk+"_container").length)bk+="_container";$("html,body").animate({scrollTop:($(bk).offset()).top},"slow");}}); 851function closeTopBanner(){sessionStorage.setItem("12b85caf23689fea8c1bd9713f717893","1");$("#topBanner").remove();moveContent();}function moveContent(){var hh=$("header").outerHeight()+"px";$("#content").css({"position":"relative","top":hh});$("footer").css({"position":"relative","top":hh,"margin-bottom":hh});}function decMail2(e){var s=""+e.href,n=s.lastIndexOf("/"),w;if(s.substr(0,7)=="mailto:")return(true);if(n>0)s=s.substr(n+1);s=s.replace("?",":").replace("#","@").replace(/[a-z]/gi,function(t){return String.fromCharCode(t.charCodeAt(0)+(t.toLowerCase()<"n"?13:-13));});e.href=s;return(true);}function onChangeSiteLang(href){var i=location.href.indexOf("?");if(i>0)href+=location.href.substr(i);document.location.href=href;}</script>
851<script>$(document).ready(function(){ucc();$("#button-cart").popover({placement:"bottom",html:true,content:function(){return sessionStorage.getItem("9d8b-popover")||"<small>VOTRE PANIER EST VIDE</small>"},trigger:"hover"});$("#searchbox>input").click(function(){$(this).select();});$("#searchbox").click(function(e){if(e.offsetX>e.target.width){}else $("#searchbox").submit()});var clickmessage="Le clic droit n'est pas autorisé sur les images de ce site!";function disableclick(e){if(document.all){if(event.button==2||event.button==3){if(event.srcElement.tagName=="IMG"){if(clickmessage!="")alert(clickmessage);return false;}}}else if(document.layers){if(e.which==3){if(clickmessage!= "")alert(clickmessage);return false;}}else if(document.getElementById){if(e.which==3&&e.target.tagName=="IMG" ){if(clickmessage!="")alert(clickmessage);return false;}}}function associateimages(){for(i=0;i<document.images.length;i++)document.images[i].onmousedown=disableclick;}if(document.all){document.onmousedown=disableclick;} else if(document.getElementById){document.onmouseup=disableclick;}else if(document.layers)associateimages();if($(window.location.hash).length)showParag(window.location.hash);if(location.href.indexOf("?")>0&&location.href.indexOf("twtheme=no")>0){$("#toolbar1,#toolbar2,#toolbar3,#footersmall,#footerfat").hide();var idbmk=location.href;idbmk=idbmk.substring(idbmk.lastIndexOf("#")+1,idbmk.lastIndexOf("?"));if(idbmk!=""){idbmk=idbmk.split("?")[0];if($("#"+idbmk+"_container").length)idbmk+="_container";$("html,body").animate({scrollTop:$("#"+idbmk).offset().top},0);}}$(".dropdown-toggle").dropdown();
851$("#site").prepend("<a href='javascript:void(0)' class='toTop' title='Haut de page'><i class='fa fa-arrow-circle-up fa-3x toTopLink'></i></a>");var offset=220;var duration=500;$(window).scroll(function(){if($(this).scrollTop()>offset){$(".toTop").fadeIn(duration);}else{$(".toTop").fadeOut(duration);}});$(".toTop").click(function(event){event.preventDefault();$("html, body").animate({scrollTop:0},duration);return(false);});if(sessionStorage.getItem("12b85caf23689fea8c1bd9713f717893")!="1"){var html='<div id="topBanner" class="alert alert-success shadow fill-available" style="margin:0;border-radius:0;position:relative;z-index:9998;padding-left:180% !important;padding-right:180% !important;margin-left:-180% !important;margin-right:-180% !important;font-size:100%;border-style:solid;border-width:0 0 1px;"><div class="alert-success" style="display:flex;justify-content:center;align-items:center;max-width:940px;"><div style="text-align:center;">Nouveau : Gagnez du temps dans votre prospection en générant de façon automatisée l\'étude de votre ZR ? outils négociateurs dans Opérateur/Gestionnaire</div><div class="closetb" onclick="closeTopBanner()" style="font-size:16px"><i class="fa fa-close"></i></div></div></div>';$("header").prepend(html);}prevScrollpos=window.pageYOffset;var siteMaxWidth=$("#page").css("max-width");if(siteMaxWidth!="none"){for(var i=1;i<=3;i++)$("header").find("#toolbar"+i).css("max-width",siteMaxWidth);$("header").css({"left":"max(0px,50% - "+siteMaxWidth+" / 2)","right":"max(0px,50% - "+siteMaxWidth+" / 2)"});}$("#site").css({"overflow-y":"hidden"});$("header").css({"position":"fixed","top":"0","z-index":"9998","background-color":"hsla(0,0%,0%,0.8)","transition":"top 1s"});$("header").addClass("fill-available");moveContent();$(window).resize(moveContent);$(".btn-navbar").first().on("click",function(){if($(this).hasClass("collapsed")){$("header").css({"position":"relative"});}else{$("header").css({"position":"fixed"});}});$(window).on("scroll",function(){currentScrollPos=window.pageYOffset;if(currentScrollPos<0)return;if(currentScrollPos==0){$("header").css({"zoom":"100%"});}else{$("header").css({"zoom":"75%"});}if(currentScrollPos==0){$("header").css({"box-shadow":"none"});$("header").css({"zoom":"100%"})}else{$("header").css({"box-shadow":"rgba(0, 0, 0, 0.1) 0px 4px 4px 0px"});$("header").css({"zoom":"75%"});}});if(typeof onTOWebPageLoaded=="function")onTOWebPageLoaded();});</script>
851</body></html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.