Omniscope Custom Blocks › Preparation/Geo/Centroids

Centroids from GeoJSON

Finds a centre point (latitude and longitude) for each shape, from records with GeoJSON or WKT shapes or from a GeoJSON file or shapefile, and outputs it with the shape's ID or other fields.

Preparation › Geo Python

Open the demo in Omniscope Download demo.ioz Sample data: districts.csv Source on GitHub

Omniscope custom block · Preparation

One point per region: a latitude and longitude for the centre of every shape in a boundary file, ready to pin, label or measure from.

Python · geopandas, pandas · geopandas installed on first run

The problem it solves

Boundaries (sales territories, council districts, delivery zones) describe each region as a shape, in a boundary file or as GeoJSON or WKT text in a table. A map can draw the shapes, but a lot of analysis wants one point per region: a pin with the region's total, a label, a distance from the region to a site, a join to other point data. Working out the centre of a shape by hand is not practical, and the obvious shortcut, the middle of its bounding box, can be far off for an irregular region.

The block reads the shapes, from records on its input or from a file, and outputs one record per shape with the shape's ID and a Lat and Long for its centre. For a C- or L-shaped region, where the true centroid falls outside the shape, it can give a point that is guaranteed to be inside instead.

How it works

What goes in

Districts (sample-data/districts.csv)

Four invented districts with made-up names and shapes, each boundary as WKT text (shortened here).

District code District name Households Boundary
D01 Ashcombe 4200 POLYGON ((-1.6 53.12, -1.4 53.12, ...))
D02 Brackenford 2900 POLYGON ((-1.4 53.12, -1.2 53.12, ...))
D03 Coldharbour Vale 3600 POLYGON ((-1.6 53, -1.35 53, ...))
D04 Dunmere 1800 MULTIPOLYGON (((-1.35 53, -1.2 53, ...)), ((-1.1 53.05, ...)))

Ashcombe and Brackenford interlock (Brackenford is L-shaped); Dunmere has a detached second part to the east.

The options

Option Demo setting What it does
Geometry field Boundary The field holding each shape (GeoJSON or WKT).
ID field (empty) The field that names each shape; empty keeps every other field.
Shapes file, Shape ID property (empty) Not used: the shapes come from the input.
Point Centroid The centre of the area, or a point guaranteed to be inside the shape.

What comes out

Centre points (Point = Centroid)

District code District name Households Lat Long
D01 Ashcombe 4200 53.18636 -1.44591
D02 Brackenford 2900 53.16250 -1.27375
D03 Coldharbour Vale 3600 53.06000 -1.47500
D04 Dunmere 1800 53.06031 -1.26281

The same with Point = Point inside the shape

District name Lat Long
Ashcombe 53.20000 -1.43000
Brackenford 53.20000 -1.23000
Coldharbour Vale 53.06000 -1.47500
Dunmere 53.06000 -1.27500

Brackenford's centroid (53.1625, -1.27375) lies in the corner of the L, which belongs to Ashcombe: a pin there would mark the wrong district. The point inside the shape sits in Brackenford's eastern arm. For the rectangle (Coldharbour Vale) the two are the same.

Where it pays off

Sales and territories: Territory pins

Put one point per sales territory on a map, sized by revenue, rather than shading whole shapes.

Public sector: Distances from areas

Measure from each district's centre to the nearest clinic, school or depot, with the distance blocks in the same workflow.

Logistics: Zone labels

Label delivery zones on a map with their codes, using points that are guaranteed to sit inside each zone.

Data preparation: Joining area data to point data

Give area-level figures (population, households) a location so they can be plotted beside customer or site points.

Use cases describe typical scenarios and are illustrative; the sample data is invented.

Why do this in Omniscope

How it fits into an Omniscope workflow

Boundaries (Database or File) → Centroids from GeoJSON → Join (on the district code, with area figures) → Report (map view)

Connect a table with one shape per record (GeoJSON or WKT text), or leave the input empty and choose a file in the options. Join the output to a table of figures per region on the ID, then plot Lat and Long in a map view, or feed them to a distance block.

Try it

  1. Open the demo project (demo.iox on the demo server, or import demo.ioz from this folder): a File block loads districts.csv, four invented districts with their boundaries as WKT.
  2. The question: where should each district's pin go?
  3. Open the block: Geometry field is Boundary, ID field is empty, Point is Centroid. Run it.
  4. Look at the output: four records with the code, name and households plus Lat and Long (the Boundary field is left out). Brackenford's point (53.1625, -1.27375) is in Ashcombe's corner.
  5. Change Point to Point inside the shape and run again: Brackenford's point moves to 53.2, -1.23, inside its own boundary.

Running in Omniscope

Omniscope workflow
Omniscope workflow

The demo project's workflow: the sample data, the block, and a Validate data check on its output.

Language and libraries

Python. It uses geopandas (BSD 3-Clause), with Shapely (BSD 3-Clause) for reading GeoJSON and WKT text and for the centre points, pyproj (MIT) for converting coordinates and pyogrio (MIT) for reading the file formats; and pandas (BSD 3-Clause).

pandas is part of Omniscope's Python environment. geopandas is listed in the block's dependencies, so Omniscope installs it (and the packages it needs) with pip on first run if it is missing; the server needs access to the Python package index for that, or geopandas installed beforehand.

Tested

The block is covered by automated tests that run its script against a stand-in for Omniscope's Python API: the sample shapes as WKT records (the same points as from the file), GeoJSON text, mixed and unreadable shapes, the input's ID field, the input taking precedence over the file, the sample file with and without an ID property, points inside the shapes, a shapefile in British National Grid, a zipped shapefile, an unknown property, a missing or unreadable file, a shape with no geometry, existing Lat and Long properties, an empty file, and 20,000 shapes.

Reference

Fields it reads

NameTypeWhat it does
Geometry fieldFieldThe input field holding each shape as GeoJSON geometry or WKT text, in longitude / latitude (WGS 84).
ID fieldFieldOptional: the input field that identifies each shape, kept beside Lat and Long. Leave empty to keep every field except the geometry.

Options

NameTypeWhat it does
Shapes fileFileUsed when no geometry field is chosen. A path on the server to a GeoJSON file (.geojson, .json), a shapefile (.shp, with its .shx, .dbf and .prj files beside it, or a .zip of them) or a GeoPackage (.gpkg).
Shape ID propertyTextFor a shapes file: the property that identifies each shape, for example "code" or "name" (case matters). Leave empty to output every property.
PointChoiceCentroid: the centre of the shape's area, which can fall outside a C- or L-shaped region or between the parts of a region in several pieces. Point inside the shape: a point guaranteed to be within the shape, near its middle.

Outputs

OutputWhat it holds
CentroidsOne record per shape: its ID (or other fields / properties) and Lat, Long of its centre point, in degrees (WGS 84).