<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div class="elementToProof">That is php code. if that is what you want, but I don't do php.</div>
<div class="elementToProof"><br>
</div>
<div class="elementToProof">SQL function: <span style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<b><code>ST_HexagonGrid</code></b><code>(</code>float8 <var class="pdparam elementToProof" style="color: rgb(0, 0, 0);">
<div class="elementToProof"><span style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">size</span></div>
</var>, geometry <var class="pdparam elementToProof" style="color: rgb(0, 0, 0);">
<div class="elementToProof"><span style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">bounds</span></div>
</var><code>)</code>;</span></div>
<div class="elementToProof"><br>
</div>
<div class="elementToProof">This will create a set of hexagons according to the parameters you pass:</div>
<div class="elementToProof">size - the length of one side of the hexagon</div>
<div class="elementToProof">geometry - a Postgis geometry used to determine the extent covered by the set of hexagon polygons.</div>
<div class="elementToProof"><br>
</div>
<div class="elementToProof">You will need to determine the hex size you want generated for each scale, but the extent should be the same for all scales.</div>
<div class="elementToProof"><br>
</div>
<div class="elementToProof">I suggest you ask for SQL code, not just code, unless you prefer Python, or R or some other language.</div>
<div class="elementToProof"><br>
</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="Signature" style="color: inherit;">
<div style="margin-right: 0px; margin-left: 0px; font-family: Calibri, Arial, Helvetica, sans-serif;">
Brent Wood<br>
<br>
Principal Technician, Fisheries<br>
NIWA<br>
DDI:  +64 (4) 3860529</div>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Sylvain Ard <sylvain.ard@gmail.com><br>
<b>Sent:</b> Saturday, March 15, 2025 09:07<br>
<b>To:</b> Brent Wood <Brent.Wood@niwa.co.nz><br>
<b>Cc:</b> qgis-user@lists.osgeo.org <qgis-user@lists.osgeo.org><br>
<b>Subject:</b> Re: [Qgis-user] question</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div>sorry I ask chatGPT to make hexagons size constant, this is its code :</div>
<div>I precise that I ask it to make circles and squares too</div>
<div>backend :</div>
<div><br>
</div>
<div>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<?php</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
header('Content-Type: application/json');</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
// Connexion Redis</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$redis = new Redis();</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$redis->connect('127.0.0.1', 6379);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$redis->auth('your_strong_password');</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
// Connexion PostgreSQL</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$pdo = new PDO("pgsql:host=localhost;dbname=database", "user", "password", [</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
]);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$shape = $_GET['shape'] ?? 'hexagone';</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$bbox = explode(',', $_GET['bbox']);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$size = $_GET['size'] ?? 1000;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$radius = $_GET['radius'] ?? 500;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$resolution = $_GET['resolution'] ?? 8;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$zoom = $_GET['zoom'] ?? 2;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$cacheKey = "$shape:" . implode('-', $bbox) . ":$size:$radius:$resolution:$zoom";</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
// Vérifier le cache Redis</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
if ($redis->exists($cacheKey)) {</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    echo $redis->get($cacheKey);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    exit;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
}</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
list($minLng, $minLat, $maxLng, $maxLat) = $bbox;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$params = [':minLng' => $minLng, ':minLat' => $minLat, ':maxLng' => $maxLng, ':maxLat' => $maxLat];</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
if ($shape === "hexagone") {</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    $sql = "</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        SELECT h3_geo_to_h3(ST_Y(geom), ST_X(geom), :resolution) AS h3_cell, COUNT(*) AS point_count</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        FROM your_points_table</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        WHERE geom && ST_MakeEnvelope(:minLng, :minLat, :maxLng, :maxLat, 4326)</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        GROUP BY h3_cell;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    ";</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    $params[':resolution'] = $resolution;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
} elseif ($shape === "cercle") {</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    $sql = "</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        SELECT ST_AsGeoJSON(ST_Buffer(geom::geography, :radius)::geometry) AS shape, COUNT(*) AS point_count</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        FROM your_points_table</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        WHERE geom && ST_MakeEnvelope(:minLng, :minLat, :maxLng, :maxLat, 4326)</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        GROUP BY shape;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    ";</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    $params[':radius'] = $radius;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
} else {</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    $sql = "</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        SELECT ST_AsGeoJSON(ST_Envelope(ST_Buffer(geom::geography, :size, 'quad_segs=1')::geometry)) AS shape, COUNT(*) AS point_count</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        FROM your_points_table</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        WHERE geom && ST_MakeEnvelope(:minLng, :minLat, :maxLng, :maxLat, 4326)</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        GROUP BY shape;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    ";</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    $params[':size'] = $size;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
}</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$stmt = $pdo->prepare($sql);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$stmt->execute($params);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
// Mise en cache Redis (10 minutes)</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
$redis->setEx($cacheKey, 600, json_encode($result));</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
echo json_encode($result);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<br>
</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
frontend :</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<!DOCTYPE html></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<html lang="fr"></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<head></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <meta charset="UTF-8"></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <title>Cartographie Dynamique (PHP + jQuery)</title></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <link rel="stylesheet" href="<a href="https://unpkg.com/leaflet/dist/leaflet.css" originalsrc="https://unpkg.com/leaflet/dist/leaflet.css">https://unpkg.com/leaflet/dist/leaflet.css</a>"></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <script src="<a href="https://unpkg.com/leaflet/dist/leaflet.js" originalsrc="https://unpkg.com/leaflet/dist/leaflet.js">https://unpkg.com/leaflet/dist/leaflet.js</a>"></script></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <script src="<a href="https://code.jquery.com/jquery-3.6.0.min.js" originalsrc="https://code.jquery.com/jquery-3.6.0.min.js">https://code.jquery.com/jquery-3.6.0.min.js</a>"></script></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <style></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        #map { height: 500px; width: 100%; }</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    </style></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
</head></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<body></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<h2>Choisissez la forme :</h2></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<select id="shapeSelector"></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <option value="hexagone">Hexagone</option></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <option value="cercle">Cercle</option></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <option value="carre">Carré</option></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
</select></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<div id="map"></div></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<script></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    const map = L.map('map').setView([0, 0], 2);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    L.tileLayer('https://{s}.<a href="http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png').addTo(map" originalsrc="http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png').addTo(map">tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map</a>);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    let layer;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    let currentShape = 'hexagone';</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    function getColor(count) {</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        return count > 100 ? '#800026' :</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
               count > 50  ? '#BD0026' :</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
               count > 20  ? '#E31A1C' :</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
               count > 10  ? '#FC4E2A' :</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
                             '#FFEDA0';</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    }</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    function fetchData() {</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        const bounds = map.getBounds();</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        const bbox = `${bounds.getWest()},${bounds.getSouth()},${bounds.getEast()},${bounds.getNorth()}`;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        const zoom = map.getZoom();</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        $.getJSON(`backend.php?shape=${currentShape}&bbox=${bbox}&size=1000&radius=500&resolution=8&zoom=${zoom}`, function (data) {</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
            if (layer) map.removeLayer(layer);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
            layer = L.geoJSON(data.map(item => JSON.parse(item.shape || item.h3_cell)), {</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
                style: (feature) => ({</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
                    color: getColor(feature.properties?.point_count || 0),</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
                    weight: 2,</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
                    fillOpacity: 0.5</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
                })</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
            }).addTo(map);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        });</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    }</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    $("#shapeSelector").change(function () {</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        currentShape = $(this).val();</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        fetchData();</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    });</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    map.on('moveend zoomend', fetchData);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    fetchData();</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
</script></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
</body></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
</html></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
</p>
<div class="x_MsoNormal" align="center" style="text-align:center; margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<hr size="2" width="100%" align="center">
</div>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<br>
</p>
</div>
<div>
<div dir="ltr" class="x_gmail_signature" data-smartmail="gmail_signature">
<div dir="ltr">
<div>
<div dir="ltr">
<div>
<div>
<div>
<div>Sylvain Ard<br>
0549507724<br>
0778380991</div>
<div><a href="mailto:sylvain.ard@gmail.com" target="_blank">sylvain.ard@gmail.com</a></div>
<div><a href="http://sylvain-ard.fr/" originalsrc="http://sylvain-ard.fr/" target="_blank">https://www.sylvain-ard.fr</a><br>
</div>
Entreprise individuelle SIRET : 80079243400022<br>
</div>
Appt 26 Bât A Résidence Le Patio<br>
</div>
83 rue de la Bugellerie<br>
</div>
86000 Poitiers<br>
</div>
</div>
</div>
</div>
</div>
<br>
</div>
<br>
<div class="x_gmail_quote x_gmail_quote_container">
<div dir="ltr" class="x_gmail_attr">Le ven. 14 mars 2025 à 20:59, Sylvain Ard <<a href="mailto:sylvain.ard@gmail.com">sylvain.ard@gmail.com</a>> a écrit :<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div dir="ltr">
<div>this is the code of chatGPT with H3 :</div>
<div>backend :</div>
<div><br>
</div>
<div>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif"><?php</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">header('Content-Type: application/json');</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif"> </span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">$pdo = new PDO("pgsql:host=localhost;dbname=database", "user", "password", [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">$redis = new Redis();</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">$redis->connect('127.0.0.1', 6379);</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">$redis->auth('password');</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif"> </span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">$shape = $_GET['shape'];</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">$bbox = explode(',', $_GET['bbox']);</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">$size = $_GET['size'] ?? null;</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">$radius = $_GET['radius'] ?? null;</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">$resolution = $_GET['resolution'] ?? 8;</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif"> </span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">$cacheKey = "$shape:" . implode('-', $bbox) . ":$size:$radius:$resolution";</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif"> </span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">if ($redis->exists($cacheKey)) {</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">    echo $redis->get($cacheKey);</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">    exit;</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">}</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif"> </span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">if ($shape === "hexagone") {</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">    $sql = "</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">        SELECT h3_geo_to_h3(ST_Y(geom), ST_X(geom), :resolution) AS h3_cell, COUNT(*) AS point_count</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">        FROM your_points_table</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">        WHERE geom && ST_MakeEnvelope(:minLng, :minLat, :maxLng, :maxLat, 4326)</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">        GROUP BY h3_cell;</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">    ";</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">    $params = [':resolution' => $resolution, ':minLng' => $bbox[0], ':minLat' => $bbox[1], ':maxLng' => $bbox[2], ':maxLat' => $bbox[3]];</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">} elseif ($shape === "cercle") {</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">    $sql = "</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">        SELECT ST_AsGeoJSON(ST_Buffer(geom::geography, :radius)::geometry) AS shape, COUNT(*) AS point_count</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">        FROM your_points_table</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">        WHERE geom && ST_MakeEnvelope(:minLng, :minLat, :maxLng, :maxLat, 4326)</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">        GROUP BY shape;</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">    ";</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">    $params = [':radius' => $radius, ':minLng' => $bbox[0], ':minLat' => $bbox[1], ':maxLng' => $bbox[2], ':maxLat' => $bbox[3]];</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">} else {</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">    $sql = "</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">        SELECT ST_AsGeoJSON(ST_Envelope(ST_Buffer(geom::geography, :size, 'quad_segs=1')::geometry)) AS shape, COUNT(*) AS point_count</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">        FROM your_points_table</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">        WHERE geom && ST_MakeEnvelope(:minLng, :minLat, :maxLng, :maxLat, 4326)</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">        GROUP BY shape;</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">    ";</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">    $params = [':size' => $size, ':minLng' => $bbox[0], ':minLat' => $bbox[1], ':maxLng' => $bbox[2], ':maxLat' => $bbox[3]];</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">}</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif"> </span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">$stmt = $pdo->prepare($sql);</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">$stmt->execute($params);</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">$result = $stmt->fetchAll(PDO::FETCH_ASSOC);</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif"> </span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">$redis->setEx($cacheKey, 3600, json_encode($result));</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">echo json_encode($result);</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif"><br>
</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif">frontend :</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif"><br>
</span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<!DOCTYPE html></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<html lang="fr"></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<head></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <meta charset="UTF-8"></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <title>Cartographie avec Forme Sélectionnée</title></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <link rel="stylesheet" href="<a href="https://unpkg.com/leaflet/dist/leaflet.css" originalsrc="https://unpkg.com/leaflet/dist/leaflet.css" target="_blank">https://unpkg.com/leaflet/dist/leaflet.css</a>"></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <script src="<a href="https://unpkg.com/leaflet/dist/leaflet.js" originalsrc="https://unpkg.com/leaflet/dist/leaflet.js" target="_blank">https://unpkg.com/leaflet/dist/leaflet.js</a>"></script></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <script src="<a href="https://code.jquery.com/jquery-3.6.0.min.js" originalsrc="https://code.jquery.com/jquery-3.6.0.min.js" target="_blank">https://code.jquery.com/jquery-3.6.0.min.js</a>"></script></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <style></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        #map { height: 500px; width: 100%; }</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    </style></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
</head></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<body></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<h2>Choisissez la forme :</h2></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<select id="shapeSelector"></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <option value="hexagone">Hexagone</option></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <option value="cercle">Cercle</option></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    <option value="carre">Carré</option></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
</select></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<div id="map"></div></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<script></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    const map = L.map('map').setView([0, 0], 2);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    L.tileLayer('https://{s}.<a href="http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png').addTo(map" originalsrc="http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png').addTo(map" target="_blank">tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map</a>);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    let layer;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    function fetchData(shape) {</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        const bbox = "-10,-10,10,10";</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        const url = `backend.php?shape=${shape}&bbox=${bbox}&size=1000&radius=500&resolution=8`;</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        $.getJSON(url, function (data) {</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
            if (layer) map.removeLayer(layer);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
            layer = L.geoJSON(data, {</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
                style: {</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
                    color: shape === "carre" ? "green" : shape === "cercle" ? "blue" : "red",</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
                    weight: 2,</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
                    fillOpacity: 0.4</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
                }</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
            }).addTo(map);</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        });</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    }</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    $("#shapeSelector").change(function () {</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
        fetchData($(this).val());</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    });</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
    fetchData("hexagone"); // Chargement initial</p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
</script></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
 </p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
</body></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
<span style="font-size:12pt; line-height:107%; font-family:"Times New Roman",serif"></span></p>
<p class="x_MsoNormal" style="margin:0cm 0cm 8pt; line-height:107%; font-size:11pt; font-family:Aptos,sans-serif">
</html></p>
</div>
<div><br>
</div>
<div>
<div dir="ltr" class="x_gmail_signature">
<div dir="ltr">
<div>
<div dir="ltr">
<div>
<div>
<div>
<div>Sylvain Ard<br>
0549507724<br>
0778380991</div>
<div><a href="mailto:sylvain.ard@gmail.com" target="_blank">sylvain.ard@gmail.com</a></div>
<div><a href="http://sylvain-ard.fr/" originalsrc="http://sylvain-ard.fr/" target="_blank">https://www.sylvain-ard.fr</a><br>
</div>
Entreprise individuelle SIRET : 80079243400022<br>
</div>
Appt 26 Bât A Résidence Le Patio<br>
</div>
83 rue de la Bugellerie<br>
</div>
86000 Poitiers<br>
</div>
</div>
</div>
</div>
</div>
<br>
</div>
<br>
<div class="x_gmail_quote">
<div dir="ltr" class="x_gmail_attr">Le ven. 14 mars 2025 à 20:49, Sylvain Ard <<a href="mailto:sylvain.ard@gmail.com" target="_blank">sylvain.ard@gmail.com</a>> a écrit :<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div dir="ltr">
<div>yes but H3 can't simplify the job ?</div>
<div>
<div dir="ltr" class="x_gmail_signature">
<div dir="ltr">
<div>
<div dir="ltr">
<div>
<div>
<div>
<div>Sylvain Ard<br>
0549507724<br>
0778380991</div>
<div><a href="mailto:sylvain.ard@gmail.com" target="_blank">sylvain.ard@gmail.com</a></div>
<div><a href="http://sylvain-ard.fr/" originalsrc="http://sylvain-ard.fr/" target="_blank">https://www.sylvain-ard.fr</a><br>
</div>
Entreprise individuelle SIRET : 80079243400022<br>
</div>
Appt 26 Bât A Résidence Le Patio<br>
</div>
83 rue de la Bugellerie<br>
</div>
86000 Poitiers<br>
</div>
</div>
</div>
</div>
</div>
<br>
</div>
<br>
<div class="x_gmail_quote">
<div dir="ltr" class="x_gmail_attr">Le ven. 14 mars 2025 à 20:48, Brent Wood <<a href="mailto:Brent.Wood@niwa.co.nz" target="_blank">Brent.Wood@niwa.co.nz</a>> a écrit :<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div>
<div dir="ltr">
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Hi,</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Off the top of my head...</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Postgis can easily cope with millions of records. Given the points are there, use that to create the hexagons as required - this can be done using
<a href="https://postgis.net/docs/ST_HexagonGrid.html" originalsrc="https://postgis.net/docs/ST_HexagonGrid.html" id="x_m_7822214219746514384m_-7618079101520814894m_4221934677744483969LPlnk" target="_blank">
https://postgis.net/docs/ST_HexagonGrid.html</a></div>
<div><br>
</div>
<div>If you set up your QGIS project with preset zoom levels, and create a set of appropriately sized hexagons for each zoom level, then populate a column with the number of points it contains.</div>
<div><br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
There will be some devilish details - as you zoom in, the polygon's real area will get smaller, so will contain less points. A fixed symbology will therefore change the colour range with the scale.</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Calculating a normalised value, perhaps something like instead of the no of points, you calculate a normalised value - the hex at each scale with the most points gets 100, the rest get a value based on the no of points/the max for that scale, so all polygon
 datasets will have colours set to values between 0 and 100. All doable with SQL.</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Do all the data stuff in Postgis, then just plot in QGIS.</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
There are various ways to set QGIS up for this, but one reasonably straightforward way that should work is having a separate hexagon layer for each scale, with a scale limit on displaying it so that all map scales are represented by one of the hexagon layers,
 with the fixed zoom levels/scales, set the same symbology for each layer, then  group them into a single group.</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Something to consider anyway...</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Cheers</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div id="x_m_7822214219746514384m_-7618079101520814894m_4221934677744483969Signature" style="color:inherit">
<div style="margin-right:0px; margin-left:0px; font-family:Calibri,Arial,Helvetica,sans-serif">
Brent Wood<br>
<br>
Principal Technician, Fisheries<br>
NIWA<br>
DDI:  +64 (4) 3860529</div>
</div>
<div id="x_m_7822214219746514384m_-7618079101520814894m_4221934677744483969appendonsend">
</div>
<hr style="display:inline-block; width:98%">
<div id="x_m_7822214219746514384m_-7618079101520814894m_4221934677744483969divRplyFwdMsg" dir="ltr">
<font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> QGIS-User <<a href="mailto:qgis-user-bounces@lists.osgeo.org" target="_blank">qgis-user-bounces@lists.osgeo.org</a>> on behalf of Sylvain Ard via QGIS-User <<a href="mailto:qgis-user@lists.osgeo.org" target="_blank">qgis-user@lists.osgeo.org</a>><br>
<b>Sent:</b> Friday, March 14, 2025 23:35<br>
<b>To:</b> <a href="mailto:qgis-user@lists.osgeo.org" target="_blank">qgis-user@lists.osgeo.org</a> <<a href="mailto:qgis-user@lists.osgeo.org" target="_blank">qgis-user@lists.osgeo.org</a>><br>
<b>Subject:</b> [Qgis-user] question</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div>Hello,<br>
I'd like a map with hexagons that are darker the more points there are underneath. My points are in a PostgreSQL table. If there are no points, there should be no hexagon. The hexagons have a constant size on the screen, so they have to be recalculated each
 time the map is zoomed in. I want a truly optimized solution because I have millions of points. So, perhaps I could use QGIS-server.<br>
Please suggest a solution for both the server and client side.<br>
Best regards</div>
<div>PS : my map must be like GBIF maps</div>
<div><br>
</div>
<div>
<div dir="ltr">
<div dir="ltr">
<div>
<div dir="ltr">
<div>
<div>
<div>
<div>Sylvain Ard<br>
0549507724<br>
0778380991</div>
<div><a href="mailto:sylvain.ard@gmail.com" target="_blank">sylvain.ard@gmail.com</a></div>
<div><a href="http://sylvain-ard.fr/" originalsrc="http://sylvain-ard.fr/" target="_blank">https://www.sylvain-ard.fr</a><br>
</div>
Entreprise individuelle SIRET : 80079243400022<br>
</div>
Appt 26 Bât A Résidence Le Patio<br>
</div>
83 rue de la Bugellerie<br>
</div>
86000 Poitiers<br>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<table cellspacing="20" style="width:600px; font-size:8pt; font-family:Arial">
<tbody>
<tr>
<td><a href="https://www.niwa.co.nz/" target="_blank"><img src="https://www.niwa.co.nz/static/niwa-2018-horizontal-180.png">
</a></td>
<td>
<table style="width:500px">
<tbody>
<tr>
<td><span>Brent Wood <br>
<font color="#1793d2">Principal Technician - GIS and Spatial Data Management</font><br>
<font color="#1793d2">Programme Leader - Environmental Information Delivery</font><br>
+64-4-386-0529<br>
<br>
National Institute of Water & Atmospheric Research Ltd (NIWA)<br>
301 Evans Bay Parade Hataitai Wellington New Zealand<br>
<b>Connect with NIWA:</b> <a href="https://www.niwa.co.nz/" target="_blank">niwa.co.nz</a>
<a href="https://www.facebook.com/nzniwa" originalsrc="https://www.facebook.com/nzniwa" target="_blank">
Facebook</a> <a href="https://www.linkedin.com/company/niwa" originalsrc="https://www.linkedin.com/company/niwa" target="_blank">
LinkedIn</a> <a href="https://twitter.com/niwa_nz" originalsrc="https://twitter.com/niwa_nz" target="_blank">
Twitter</a> <a href="https://www.instagram.com/niwa_science" originalsrc="https://www.instagram.com/niwa_science" target="_blank">
Instagram</a> <a href="https://www.youtube.com/channel/UCJ-j3MLMg1H59Ak2UaNLL3A" originalsrc="https://www.youtube.com/channel/UCJ-j3MLMg1H59Ak2UaNLL3A" target="_blank">
YouTube</a> </span></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<font face="Arial" size="1">To ensure compliance with legal requirements and to maintain cyber security standards, NIWA's IT systems are subject to ongoing monitoring, activity logging and auditing. This monitoring and auditing service may be provided by third
 parties. Such third parties can access information transmitted to, processed by and stored on NIWA's IT systems.
<br>
Note: This email is intended solely for the use of the addressee and may contain information that is confidential or subject to legal professional privilege. If you receive this email in error please immediately notify the sender and delete the email.
</font></div>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</body>
</html>