Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

turf-isobands

Package Overview
Dependencies
Maintainers
8
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

turf-isobands - npm Package Compare versions

Comparing version 1.0.0 to 1.0.1

conrec.js

536

index.js

@@ -14,3 +14,24 @@ //https://github.com/jasondavies/conrec.js

var size = require('turf-size');
var Conrec = require('./conrec.js');
/**
* Takes a FeatureCollection of points with z values and an array of
* value breaks and generates filled contour isobands. These are commonly
* used to create elevation maps, but can be used for general data
* interpolation as well.
*
* @module turf/isobands
* @param {GeoJSONFeatureCollection} points
* @param {string} z - a property name from which z values will be pulled
* @param {number} resolution - resolution of the underlying grid
* @return {Array<number>} breaks - where to draw contours
* @example
* var fs = require('fs')
* var z = 'elevation'
* var resolution = 15
* var breaks = [.1, 22, 45, 55, 65, 85, 95, 105, 120, 180]
* var points = JSON.parse(fs.readFileSync('/path/to/points.geojson'))
* var isobanded = turf.isobands(points, z, resolution, breaks)
* console.log(isobanded)
*/
module.exports = function(points, z, resolution, breaks){

@@ -167,516 +188,1 @@ var addEdgesResult = addEdges(points, z, resolution);

}
/**
* Copyright (c) 2010, Jason Davies.
*
* All rights reserved. This code is based on Bradley White's Java version,
* which is in turn based on Nicholas Yue's C++ version, which in turn is based
* on Paul D. Bourke's original Fortran version. See below for the respective
* copyright notices.
*
* See http://local.wasp.uwa.edu.au/~pbourke/papers/conrec/ for the original
* paper by Paul D. Bourke.
*
* The vector conversion code is based on http://apptree.net/conrec.htm by
* Graham Cox.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1996-1997 Nicholas Yue
*
* This software is copyrighted by Nicholas Yue. This code is based on Paul D.
* Bourke's CONREC.F routine.
*
* The authors hereby grant permission to use, copy, and distribute this
* software and its documentation for any purpose, provided that existing
* copyright notices are retained in all copies and that this notice is
* included verbatim in any distributions. Additionally, the authors grant
* permission to modify this software and its documentation for any purpose,
* provided that such modifications are not distributed without the explicit
* consent of the authors and that existing copyright notices are retained in
* all copies. Some of the algorithms implemented by this software are
* patented, observe all applicable patent law.
*
* IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
* EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS
* PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO
* OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
* MODIFICATIONS.
*/
exports.Conrec = Conrec;
var EPSILON = 1e-10;
function pointsEqual(a, b) {
var x = a.x - b.x, y = a.y - b.y;
return x * x + y * y < EPSILON;
}
function reverseList(list) {
var pp = list.head;
while (pp) {
// swap prev/next pointers
var temp = pp.next;
pp.next = pp.prev;
pp.prev = temp;
// continue through the list
pp = temp;
}
// swap head/tail pointers
var temp = list.head;
list.head = list.tail;
list.tail = temp;
}
function ContourBuilder(level) {
this.level = level;
this.s = null;
this.count = 0;
}
ContourBuilder.prototype.remove_seq = function(list) {
// if list is the first item, static ptr s is updated
if (list.prev) {
list.prev.next = list.next;
} else {
this.s = list.next;
}
if (list.next) {
list.next.prev = list.prev;
}
--this.count;
}
ContourBuilder.prototype.addSegment = function(a, b) {
var ss = this.s;
var ma = null;
var mb = null;
var prependA = false;
var prependB = false;
while (ss) {
if (ma == null) {
// no match for a yet
if (pointsEqual(a, ss.head.p)) {
ma = ss;
prependA = true;
} else if (pointsEqual(a, ss.tail.p)) {
ma = ss;
}
}
if (mb == null) {
// no match for b yet
if (pointsEqual(b, ss.head.p)) {
mb = ss;
prependB = true;
} else if (pointsEqual(b, ss.tail.p)) {
mb = ss;
}
}
// if we matched both no need to continue searching
if (mb != null && ma != null) {
break;
} else {
ss = ss.next;
}
}
// c is the case selector based on which of ma and/or mb are set
var c = ((ma != null) ? 1 : 0) | ((mb != null) ? 2 : 0);
switch(c) {
case 0: // both unmatched, add as new sequence
var aa = {p: a, prev: null};
var bb = {p: b, next: null};
aa.next = bb;
bb.prev = aa;
// create sequence element and push onto head of main list. The order
// of items in this list is unimportant
ma = {head: aa, tail: bb, next: this.s, prev: null, closed: false};
if (this.s) {
this.s.prev = ma;
}
this.s = ma;
++this.count; // not essential - tracks number of unmerged sequences
break;
case 1: // a matched, b did not - thus b extends sequence ma
var pp = {p: b};
if (prependA) {
pp.next = ma.head;
pp.prev = null;
ma.head.prev = pp;
ma.head = pp;
} else {
pp.next = null;
pp.prev = ma.tail;
ma.tail.next = pp;
ma.tail = pp;
}
break;
case 2: // b matched, a did not - thus a extends sequence mb
var pp = {p: a};
if (prependB) {
pp.next = mb.head;
pp.prev = null;
mb.head.prev = pp;
mb.head = pp;
} else {
pp.next = null;
pp.prev = mb.tail;
mb.tail.next = pp;
mb.tail = pp;
}
break;
case 3: // both matched, can merge sequences
// if the sequences are the same, do nothing, as we are simply closing this path (could set a flag)
if (ma === mb) {
var pp = {p: ma.tail.p, next: ma.head, prev: null};
ma.head.prev = pp;
ma.head = pp;
ma.closed = true;
break;
}
// there are 4 ways the sequence pair can be joined. The current setting of prependA and
// prependB will tell us which type of join is needed. For head/head and tail/tail joins
// one sequence needs to be reversed
switch((prependA ? 1 : 0) | (prependB ? 2 : 0)) {
case 0: // tail-tail
// reverse ma and append to mb
reverseList(ma);
// fall through to head/tail case
case 1: // head-tail
// ma is appended to mb and ma discarded
mb.tail.next = ma.head;
ma.head.prev = mb.tail;
mb.tail = ma.tail;
//discard ma sequence record
this.remove_seq(ma);
break;
case 3: // head-head
// reverse ma and append mb to it
reverseList(ma);
// fall through to tail/head case
case 2: // tail-head
// mb is appended to ma and mb is discarded
ma.tail.next = mb.head;
mb.head.prev = ma.tail;
ma.tail = mb.tail;
//discard mb sequence record
this.remove_seq(mb);
break;
}
}
}
/**
* Implements CONREC.
*
* @param {function} drawContour function for drawing contour. Defaults to a
* custom "contour builder", which populates the
* contours property.
*/
function Conrec(drawContour) {
if (!drawContour) {
var c = this;
c.contours = {};
/**
* drawContour - interface for implementing the user supplied method to
* render the countours.
*
* Draws a line between the start and end coordinates.
*
* @param startX - start coordinate for X
* @param startY - start coordinate for Y
* @param endX - end coordinate for X
* @param endY - end coordinate for Y
* @param contourLevel - Contour level for line.
*/
this.drawContour = function(startX, startY, endX, endY, contourLevel, k) {
var cb = c.contours[k];
if (!cb) {
cb = c.contours[k] = new ContourBuilder(contourLevel);
}
cb.addSegment({x: startX, y: startY}, {x: endX, y: endY});
}
this.contourList = function() {
var l = [];
var a = c.contours;
for (var k in a) {
var s = a[k].s;
var level = a[k].level;
while (s) {
var h = s.head;
var l2 = [];
l2.level = level;
l2.k = k;
while (h && h.p) {
l2.push(h.p);
h = h.next;
}
l.push(l2);
s = s.next;
}
}
l.sort(function(a, b) { return a.k - b.k });
return l;
}
} else {
this.drawContour = drawContour;
}
this.h = new Array(5);
this.sh = new Array(5);
this.xh = new Array(5);
this.yh = new Array(5);
}
/**
* contour is a contouring subroutine for rectangularily spaced data
*
* It emits calls to a line drawing subroutine supplied by the user which
* draws a contour map corresponding to real*4data on a randomly spaced
* rectangular grid. The coordinates emitted are in the same units given in
* the x() and y() arrays.
*
* Any number of contour levels may be specified but they must be in order of
* increasing value.
*
*
* @param {number[][]} d - matrix of data to contour
* @param {number} ilb,iub,jlb,jub - index bounds of data matrix
*
* The following two, one dimensional arrays (x and y) contain
* the horizontal and vertical coordinates of each sample points.
* @param {number[]} x - data matrix column coordinates
* @param {number[]} y - data matrix row coordinates
* @param {number} nc - number of contour levels
* @param {number[]} z - contour levels in increasing order.
*/
Conrec.prototype.contour = function(d, ilb, iub, jlb, jub, x, y, nc, z) {
var h = this.h, sh = this.sh, xh = this.xh, yh = this.yh;
var drawContour = this.drawContour;
this.contours = {};
/** private */
var xsect = function(p1, p2){
return (h[p2]*xh[p1]-h[p1]*xh[p2])/(h[p2]-h[p1]);
}
var ysect = function(p1, p2){
return (h[p2]*yh[p1]-h[p1]*yh[p2])/(h[p2]-h[p1]);
}
var m1;
var m2;
var m3;
var case_value;
var dmin;
var dmax;
var x1 = 0.0;
var x2 = 0.0;
var y1 = 0.0;
var y2 = 0.0;
// The indexing of im and jm should be noted as it has to start from zero
// unlike the fortran counter part
var im = [0, 1, 1, 0];
var jm = [0, 0, 1, 1];
// Note that castab is arranged differently from the FORTRAN code because
// Fortran and C/C++ arrays are transposed of each other, in this case
// it is more tricky as castab is in 3 dimensions
var castab = [
[
[0, 0, 8], [0, 2, 5], [7, 6, 9]
],
[
[0, 3, 4], [1, 3, 1], [4, 3, 0]
],
[
[9, 6, 7], [5, 2, 0], [8, 0, 0]
]
];
for (var j=(jub-1);j>=jlb;j--) {
for (var i=ilb;i<=iub-1;i++) {
var temp1, temp2;
temp1 = Math.min(d[i][j],d[i][j+1]);
temp2 = Math.min(d[i+1][j],d[i+1][j+1]);
dmin = Math.min(temp1,temp2);
temp1 = Math.max(d[i][j],d[i][j+1]);
temp2 = Math.max(d[i+1][j],d[i+1][j+1]);
dmax = Math.max(temp1,temp2);
if (dmax>=z[0]&&dmin<=z[nc-1]) {
for (var k=0;k<nc;k++) {
if (z[k]>=dmin&&z[k]<=dmax) {
for (var m=4;m>=0;m--) {
if (m>0) {
// The indexing of im and jm should be noted as it has to
// start from zero
h[m] = d[i+im[m-1]][j+jm[m-1]]-z[k];
xh[m] = x[i+im[m-1]];
yh[m] = y[j+jm[m-1]];
} else {
h[0] = 0.25*(h[1]+h[2]+h[3]+h[4]);
xh[0]=0.5*(x[i]+x[i+1]);
yh[0]=0.5*(y[j]+y[j+1]);
}
if (h[m]>EPSILON) {
sh[m] = 1;
} else if (h[m]<-EPSILON) {
sh[m] = -1;
} else
sh[m] = 0;
}
//
// Note: at this stage the relative heights of the corners and the
// centre are in the h array, and the corresponding coordinates are
// in the xh and yh arrays. The centre of the box is indexed by 0
// and the 4 corners by 1 to 4 as shown below.
// Each triangle is then indexed by the parameter m, and the 3
// vertices of each triangle are indexed by parameters m1,m2,and
// m3.
// It is assumed that the centre of the box is always vertex 2
// though this isimportant only when all 3 vertices lie exactly on
// the same contour level, in which case only the side of the box
// is drawn.
//
//
// vertex 4 +-------------------+ vertex 3
// | \ / |
// | \ m-3 / |
// | \ / |
// | \ / |
// | m=2 X m=2 | the centre is vertex 0
// | / \ |
// | / \ |
// | / m=1 \ |
// | / \ |
// vertex 1 +-------------------+ vertex 2
//
//
//
// Scan each triangle in the box
//
for (m=1;m<=4;m++) {
m1 = m;
m2 = 0;
if (m!=4) {
m3 = m+1;
} else {
m3 = 1;
}
case_value = castab[sh[m1]+1][sh[m2]+1][sh[m3]+1];
if (case_value!=0) {
switch (case_value) {
case 1: // Line between vertices 1 and 2
x1=xh[m1];
y1=yh[m1];
x2=xh[m2];
y2=yh[m2];
break;
case 2: // Line between vertices 2 and 3
x1=xh[m2];
y1=yh[m2];
x2=xh[m3];
y2=yh[m3];
break;
case 3: // Line between vertices 3 and 1
x1=xh[m3];
y1=yh[m3];
x2=xh[m1];
y2=yh[m1];
break;
case 4: // Line between vertex 1 and side 2-3
x1=xh[m1];
y1=yh[m1];
x2=xsect(m2,m3);
y2=ysect(m2,m3);
break;
case 5: // Line between vertex 2 and side 3-1
x1=xh[m2];
y1=yh[m2];
x2=xsect(m3,m1);
y2=ysect(m3,m1);
break;
case 6: // Line between vertex 3 and side 1-2
x1=xh[m3];
y1=yh[m3];
x2=xsect(m1,m2);
y2=ysect(m1,m2);
break;
case 7: // Line between sides 1-2 and 2-3
x1=xsect(m1,m2);
y1=ysect(m1,m2);
x2=xsect(m2,m3);
y2=ysect(m2,m3);
break;
case 8: // Line between sides 2-3 and 3-1
x1=xsect(m2,m3);
y1=ysect(m2,m3);
x2=xsect(m3,m1);
y2=ysect(m3,m1);
break;
case 9: // Line between sides 3-1 and 1-2
x1=xsect(m3,m1);
y1=ysect(m3,m1);
x2=xsect(m1,m2);
y2=ysect(m1,m2);
break;
default:
break;
}
// Put your processing code here and comment out the printf
//printf("%f %f %f %f %f\n",x1,y1,x2,y2,z[k]);
drawContour(x1,y1,x2,y2,z[k],k);
}
}
}
}
}
}
}
}
{
"name": "turf-isobands",
"version": "1.0.0",
"version": "1.0.1",
"description": "turf isobands module",

@@ -5,0 +5,0 @@ "main": "index.js",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc