# 2.1 Contiguity-Based Weights

Contiguity means that two spatial units share a common border of non-zero length. Operationally, we can further distinguish between a ***rook*** and a ***queen*** criterion of contiguity, in analogy to the moves allowed for the such-named pieces on a chess board.

The rook criterion defines neighbors by the existence of a common edge between two spatial units. The queen criterion is somewhat more encompassing and defines neighbors as spatial units sharing a common edge or a common vertex.

For more information, please read: <https://geodacenter.github.io/workbook/4a_contig_weights/lab4a.html>

**CONTENTS**

1. queen\_weights()
2. rook\_weights()
3. weights\_astext()
4. save weights

### queen\_weights()

**Synopsis**

Short version:

```sql
bytea queen_weights(integer gid, geometry the_geom)
```

Full Version:

```sql
bytea queen_weights(integer gid, geometry the_geom,
    integer ord, 
    boolean include_lowerorder, 
    float precision_threshold)
```

{% hint style="info" %}
queen\_weights() is a WINDOW SQL function, which performs weights creation across a set of table rows. Unlike the regular AGGREGATE function, a WINDOW function does not cause rows to become grouped into a single output row -- the rows retain their separate identities.  A WINDOW function call always contains an OVER() clause.
{% endhint %}

**Arguments**

| Input Arguments      | Type     | Description                                                                                                                                                                                         |
| -------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| gid                  | integer  | the feature id of geometry: e.g. gid, fid, ogc*fid,* cartod&#x62;*\_*&#x69;d                                                                                                                        |
| the\_geom            | geometry | the geometry (only points and polygons are supported)                                                                                                                                               |
| ord                  | integer  | order of contiguity. Default is 1.                                                                                                                                                                  |
| include\_lowerorder  | boolean  | boolean value indicates whether or not the lower order neighbors should be included in the weights structure. Default is FALSE.                                                                     |
| precision\_threshold | boolean  | (for polygons only) the distance of precision to determine which polygons are neighbors when the underlying geometries are insufficient to allow for an exact match of coordinates. Default is 0.0. |

**Return**

| **Value** | Description                                                                                 |
| --------- | ------------------------------------------------------------------------------------------- |
| bytea     | the weights structure for each observation in binary format, which is defined in table 2.1. |

**Examples**

```sql
SELECT queen_weights(gid, the_geom) OVER() FROM natregimes;

                                                         queen_weights                                                          
--------------------------------------------------------------------------------------------------------------------------------
 \x7707000008002007000021070000740700001e070000c707000075070000c3070000c4070000
 \x7a0000000700680000004e0000005c0000007b0000008d0000009700000098000000
 \xeb0000000600ea000000cb000000ce000000020100000101000004010000
 \x510400000600ea030000e90300005204000050040000bc040000c1040000
 ...
```

Table 2.1: The binary format of weights structure&#x20;

| Bytes | Data Type | Length  | Description                             |
| ----- | --------- | ------- | --------------------------------------- |
| 0-3   | uint32\_t | 4 bytes | index of i-th observation/row           |
| 4-5   | uint16\_t | 2 bytes | number of neighbors of i-th observation |
| 6-9   | uint32\_t | 4 bytes | index of first neighbor                 |
| 10-13 | float     | 4 bytes | weights value of first neighbor         |
| ...   | ...       | ...     | index of n-th neighbor                  |
| ...   | ...       | ...     | weights value of n-th neighbor          |

### rook\_weights()

**Synopsis**

Short version:

```sql
bytea rook_weights(integer gid, geometry winset the_geom)
```

Full Version:

```sql
bytea rook_weights(integer gid, geometry winset the_geom,
    integer ord, 
    boolean include_lowerorder, 
    float precision_threshold)
```

### weights\_astext()

The help function to view the content of the weights information.

**Synopsis**

```sql
text weights_astext(bytea weights)
```

**Examples**

```sql
SELECT weights_astext(tmp.queen_weights) FROM (
    SELECT queen_weights(gid, the_geom) OVER(ORDER BY gid) FROM natregimes
) AS tmp;

                             weights_astext                             
--------------------------------------------------------------------------
 1:[23,31,41]
 2:[3,4,70]
 3:[2,5,63,70]
 4:[2,28,32,43,56,69,70]
...

```

### Save Weights

To save the results of queen\_weights(), the best practice is to save the results with the feature id, e.g. `gid`,  in a new table. For example:

```sql
CREATE TABLE nat_queen_w AS (
    SELECT gid, queen_weights(gid, the_geom) AS queen_w OVER() 
    FROM natregimes
);
-- CREATE index on gid
-- CREATE INDEX natqueen_gid_idx ON nat_queen_w (gid)
```

Or, one can create a new `bytea` column, and update its values from the results of queen\_weights() function.  For example:

```sql
-- add column queen_w
ALTER TABLE natregimes ADD COLUMN IF NOT EXISTS queen_w bytea;
-- save weights 
UPDATE natregimes SET queen_w = tmp.queen_weights FROM (
    SELECT gid, queen_weights(gid, the_geom) OVER() natregimes
) AS tmp
WHERE natregimes.gid = tmp.gid;
```

{% hint style="info" %}
The second approach is much slower than the first one when updating a large table, e.g. with millions of records.
{% endhint %}
