3

I have built a Mapbox web app with some polygon with different attributes.

The problem is when I query a table and the result is that many polygons have the same attributes. The zoom centre in one of the polygons, but doesn't show all the polygons in the zoom view, with this common attribute as I expected. So at some point the query below doesn't provide the correct information to create the bounding boxes I guess, but I cannot manage to see what is failing if that is the error. This is the query I used to retrieve the polygons depending on the polig_no with other additional data from additional tables:

const sql = `
    SELECT JSONB_BUILD_OBJECT(
        'type',     'FeatureCollection',
        'bbox',     JSONB_BUILD_ARRAY(ST_XMin(ext), ST_YMin(ext), ST_XMax(ext), ST_YMax(ext)),
        'features', features
      )
FROM   (
 SELECT ST_Extent(geom) AS ext,
        ST_AsGeoJSON(f.*)::JSONB AS features
 FROM   (
   SELECT pt.polig_no,
          pt.num_polygons::INT,
          estate_polig,
          class_of_polig,
          registered_status,
          boundary.name boundary,
        ROUND(ST_Area(pt.geom)) area,
          ARRAY[ST_X(ct), ST_Y(ct)] center,
          ARRAY[ST_XMin(box), ST_YMin(box), ST_XMax(box), ST_YMax(box)] AS bbox,
          _rpgeom AS geom
   FROM   poligon_table AS pt,
          inner join lrt l on pt.polig_no = test.polig_no,
          inner join boundary_line boundary on pt.geom && boundary.geom,
          LATERAL ST_Transform(pt.geom, 4326) AS _rpgeom,
          LATERAL ST_Envelope(_rpgeom)) AS box,
          LATERAL ST_PointOnSurface(_rpgeom) AS ct
          where pt.polig_no = $1::text
          order by st_area(st_intersection(pt.geom, boundary.geom)) desc
 ) AS f
) q
;
    `;

I don't know if it is related but also happens with large polygons doesn't show the whole area and needs to be zoom to see it.

EXTENDED QUESTION: That is how I add the fitBounds to the GIS app after creating the map, but not sure if I ma doing correct as teh results doesnt seems to be working

map = new mapboxgl.Map({
      container: container.current,
      style: 'url to map box style'
      center: [-2, 53],
      zoom: 5.75,
      accessToken: mapAccessToken,
      antialias: true
    });

    setMap(map);

    map.on('load', () => map.fitBounds(boundingBox, { duration: 0, maxZoom: 17, padding: 30 }));

1 Answer 1

3

You are creating one bounding box per geometry, in contrast to an aggregated extent - while you do not mention how the actual zoom action is implemented, e.g. a call to fitBounds will only ever be able to use a single one of the bboxes.

Given your approach, the most Mapbox-like way would probably be to iterate over the returned rows on the client, extending a LatLngBounds object with the bbox coordinate array:

var bounds = new mapboxgl.LngLatBounds();

<payload>.forEach(row => {
  bounds.extend(row.bbox);
});

map.fitBounds(bounds);

However, I would prefer to return a valid FeatureCollection including a global bbox member directly:

SELECT JSONB_BUILD_OBJECT(
         'type',     'FeatureCollection',
         'bbox',     JSONB_BUILD_ARRAY(ST_XMin(ext), ST_YMin(ext), ST_XMax(ext), ST_YMax(ext)),
         'features', features
       )
FROM   (
  SELECT ST_Extent(geom) AS ext,
         ST_AsGeoJSON(f.*)::JSONB AS features
  FROM   (
    SELECT pt.title_no, 
           pt.num_polygons::INT,
           pt.rec_status,
           ROUND(ST_Area(pt.geom)) area,
           ARRAY[ST_X(ct), ST_Y(ct)] center,
           ARRAY[ST_XMin(box), ST_YMin(box), ST_XMax(box), ST_YMax(box)] AS bbox,
           _rpgeom AS geom
    FROM   polygon_table AS pt,
           LATERAL ST_Transform(pt.geom, 4326) AS _rpgeom,
           LATERAL ST_Envelope(_rpgeom)) AS box,
           LATERAL ST_PointOnSurface(_rpgeom) AS ct
  ) AS f
) q
;

which you can then pass to fitBounds directly. Note that you will still get the per-feature bbox member in the resulting object.

1
  • 1
    I have edited the question and the full query because I couldn't manage to make it work Commented Jun 1, 2021 at 12:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.