jsGeoDa
  • jsGeoDa (beta)
  • User Guide
    • Installation
    • Hello jsgeoda!
    • Load Spatial Data
  • Choropleth Mapping
    • Basic Mapping
    • Cartogram
    • Rate Mapping
    • Spatial Rate Mapping
  • Spatial Weights
    • Contiguity-Based Weights
    • Distance-Based Weights
    • Kernel Weights
  • Local Spatial Autocorrelation
    • Local Moran
    • Local Geary
    • Local Getis-Ord G
    • Local Join Count
    • Quantile LISA
  • Multivariate Local Spatial Autocorrelation
    • Local Neighbor Match Test
    • Multivariate Local Geary
    • Bivariate Local Join Count
    • Multivariate Local Join Count
    • Multivariate Quantile LISA
  • Spatial Clustering
    • SKATER
    • REDCAP
    • SCHC
    • AZP
    • Max-p
  • Cluster Analysis
  • HDBScan
  • Fast K-Medoids
  • API REFERENCE
    • jsgeoda
Powered by GitBook
On this page
  • skater()
  • Arguments
  • Return

Was this helpful?

  1. Spatial Clustering

SKATER

PreviousMultivariate Quantile LISANextREDCAP

Last updated 3 years ago

Was this helpful?

Spatial C(K)luster Analysis by Tree Edge Removal (SKATER) is an optimized algorithm to prune the minimum spanning tree into several clusters that their values of selected variables are as similar as possible while retaining the contiguity structure. For more information, please read

skater()

function skater(
    WeightResult w,
    Number k, 
    Array vals,
    Number min_bound, 
    Array bound_vals,
    String scale_method,
    String distance_type)

Arguments

Name

Type

Description

weights

WeightsResult

The weights object WeightsResult

k

Number

The number of clusters

values

Array

The list of numeric vectors of selected variable

min_bound

Number

The minimum value that the sum value of bounding variable int each cluster should be greater than

bound_vals

Array

The numeric vector of selected bounding variable

scale_method

String

The scaling method: {'raw', 'standardize', 'demean', 'mad', 'range_standardize', 'range_adjust'}

distance_method

String

The distance method: {"euclidean", "manhattan"}

Return

Type

Description

ClusteringResult

The Clustering object: {'total_ss', 'within_ss', 'between_ss', 'ratio', 'clusters'}

Examples

const jsgeoda = require('jsgeoda');
const fs = require('fs');

// load data
const data = fs.readFileSync('./data/natregimes.geojson').buffer;

// create jsgeoda instance
const geoda = await jsgeoda.New();

// load geojson in jsgeoda
const nat = geoda.read_geojson(data);

// create a queen contiguity weights
const w = geoda.queen_weights(nat);

// get values
const hr60 = geoda.get_col(nat, "HR60");
const ue60 = geoda.get_col(nat, "UE60");

// set minimum bound
const po60 = geoda.get_col(nat, "PO60");

// apply skater
const skater = geoda.skater(w, 10, [hr60, ue60], 17845200, po60);

import React, { Component } from "react";
import ReactDOM from "react-dom";
import DeckGL from "@deck.gl/react";
import { GeoJsonLayer } from "@deck.gl/layers";
import { StaticMap } from "react-map-gl";
import colorbrewer from "colorbrewer";
import jsgeoda from "jsgeoda";

// Set your mapbox access token here
const MAPBOX_TOKEN =
  "pk.eyJ1IjoibGl4dW45MTAiLCJhIjoiY2locXMxcWFqMDAwenQ0bTFhaTZmbnRwaiJ9.VRNeNnyb96Eo-CorkJmIqg";

// The geojson data
const DATA_URL = `https://webgeoda.github.io/data/natregimes.geojson`;

class App extends Component {
  constructor() {
    super();
    this.state = {
      mapId: "",
      layer: null,
      viewPort: {
        longitude: -100.4,
        latitude: 38.74,
        zoom: 2.5,
        maxZoom: 20
      }
    };
  }

  // load spatial data when mount this component
  loadSpatialData(geoda) {
    fetch(DATA_URL)
      .then((res) => res.arrayBuffer())
      .then((data) => {
        // load geojson in jsgeoda, an unique id (string) will be returned for further usage
        const nat = geoda.read_geojson(data);
        const w = geoda.queen_weights(nat);
        const hr60 = geoda.get_col(nat, "HR60");
        const ue60 = geoda.get_col(nat, "UE60");
        const po60 = geoda.get_col(nat, "PO60");
        const redcap = geoda.skater(w, 10, [hr60, ue60], 17845200, po60);
        //const redcap = geoda.redcap(w, 10, [hr60, ue60], "fullorder-wardlinkage", 17845200, po60);
        //const redcap = geoda.azp_tabu(w, 20, [hr60, ue60], 10, 10, 1, [], [po60],[17845200]);
        //const redcap = geoda.azp_sa(w, 20, [hr60, ue60], 0.85, 1, 1, [], [po60],[17845200]);
        //const redcap = geoda.maxp_greedy(w, [hr60, ue60],  1, [po60],[17845200]);
        const colors = colorbrewer["Paired"][10].map((c) =>
          c
            .toLowerCase()
            .match(/[0-9a-f]{2}/g)
            .map((x) => parseInt(x, 16))
        );

        // Viewport settings
        const view_port = geoda.get_viewport(
          nat,
          window.innerHeight,
          window.innerWidth
        );

        // Create GeoJsonLayer
        const layer = new GeoJsonLayer({
          id: "GeoJsonLayer",
          data: DATA_URL,
          filled: true,
          getFillColor: (f) => this.getFillColor(f, redcap.clusters, colors),
          stroked: true,
          pickable: true
        });

        // Trigger to draw map
        this.setState({
          mapId: nat,
          layer: layer,
          viewPort: view_port
        });
      });
  }

  componentDidMount() {
    // jsgeoda.New() function will create an instance from WASM
    jsgeoda.New().then((geoda) => {
      this.loadSpatialData(geoda);
    });
  }

  // Determine which color for which geometry
  getFillColor(f, clusters, colors) {
    const i = f.properties.POLY_ID - 1;
    const c = clusters[i] - 1;
    return colors[c];
  }

  render() {
    return (
      <div>
        <DeckGL
          initialViewState={this.state.viewPort}
          layers={[this.state.layer]}
          controller={true}
          getTooltip={({ object }) =>
            object && `${object.properties.NAME}: ${object.properties.HR60}`
          }
        >
          <StaticMap mapboxApiAccessToken={MAPBOX_TOKEN} />
        </DeckGL>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));

Try it yourself in the playground (jsgeoda + deck.gl):

https://geodacenter.github.io/workbook/9c_spatial3/lab9c.html#skater