Repository: pissang/geometry-extrude Branch: master Commit: b658c3d3f06b Files: 36 Total size: 2.9 MB Directory structure: gitextract_sfii8sv8/ ├── .babelrc ├── .gitattributes ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── dist/ │ └── geometry-extrude.js ├── index.d.ts ├── package.json ├── rollup.config.js ├── src/ │ ├── main.js │ ├── math.js │ └── simplify.js └── test/ ├── asset/ │ ├── buildings-ny.geojson │ ├── pisa.hdr │ └── street.geojson ├── distortion.html ├── extrude-bevel.html ├── extrude-dude.html ├── extrude-exclude-bottom.html ├── extrude-hole.html ├── extrude-multipolygon.html ├── extrude-normal.html ├── extrude-polyline.html ├── extrude-simple.html ├── extrude-simplify.html ├── extrude-star.html ├── extrude-uv.html ├── geojson.html ├── lib/ │ ├── claygl-advanced-renderer.js │ ├── claygl.js │ └── dat.gui.js ├── polygon-offset.html ├── polyline-offset.html ├── slerp.html └── street.html ================================================ FILE CONTENTS ================================================ ================================================ FILE: .babelrc ================================================ { "presets": [ [ "@babel/preset-env", { "modules": false } ] ] } ================================================ FILE: .gitattributes ================================================ # Auto detect text files and perform LF normalization * text=auto ================================================ FILE: .gitignore ================================================ node_modules package-lock.json ================================================ FILE: .npmignore ================================================ test screenshot ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2018 pissang Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Geometry Extrude A small and fast JavaScript library for extruding 2D polygons and polylines to 3D meshes. It depends on [earcut](https://github.com/mapbox/earcut) to do triangulation. ## Features + Extrude polygons with holes. + Extrude polylines with specific line thickness. + Generate `position` / `uv` / `normal` / `indices` TypedArray. + Support bevel style. ## Basic Usage Install with npm ``` npm i geometry-extrude ``` Extrude a simple square with hole ```js import {extrudePolygon} from 'geometry-extrude'; const squareWithHole = [ [[0, 0], [10, 0], [10, 10], [0, 10]], // Hole [[2, 2], [8, 2], [8, 8], [2, 8]] ]; const {indices, position, uv, normal} = extrudePolygon([squareWithHole], { depth: 2 }); ``` ### Use with ClayGL ```js const {indices, position, uv, normal} = extrudePolygon(squareWithHole); const geometry = new clay.Geometry(); geometry.attributes.position.value = position; geometry.attributes.texcoord0.value = uv; geometry.attributes.normal.value = normal; geometry.indices = indices; ``` ### Use with ThreeJS ```js const {indices, position, uv, normal} = extrudePolygon(squareWithHole); const geometry = new THREE.BufferGeometry(); geometry.addAttribute('position', new THREE.Float32BufferAttribute(position, 3)); geometry.addAttribute('normal', new THREE.Float32BufferAttribute(normal, 3)); geometry.setIndex(new THREE.Uint16BufferAttribute(indices, 1)); ``` [Example](https://github.com/pissang/geometry-extrude-example-threejs) ### Use with regl ```js const {indices, position, uv, normal} = extrudePolygon(squareWithHole); const draw = regl({ frag: `...`, vert: `...`, attributes: { position: position, uv: uv, normal: norma }, elements: indices }); ``` [Example](https://github.com/pissang/geometry-extrude-example-regl) ## Full API List ### extrudePolygon ```js extrudePolygon( // polygons same with coordinates of MultiPolygon type geometry in GeoJSON // See http://wiki.geojson.org/GeoJSON_draft_version_6#MultiPolygon polygons: GeoJSONMultiPolygonGeometry, // Options of extrude opts: { // Can be a constant value, or a function. // Default to be 1. depth?: ((idx: number) => number) | number, // Size of bevel, default to be 0, which is no bevel. bevelSize?: number, // Segments of bevel, default to be 2. Larger value will lead to smoother bevel. bevelSegments?: number, // Polygon or polyline simplification tolerance. Default to be 0. // Use https://www.npmjs.com/package/simplify-js to do the simplification. Same with the tolerance parameter in it. The unit is same with depth and bevelSize simplify?: number, // If has smooth side, default to be false. smoothSide?: boolean, // If has smooth bevel, default to be false. smoothBevel?: boolean, // If exclude bottom faces, default to be false. // Usefull when bottom side can't be seen. excludeBottom?: boolean, // Transform the polygon to fit this rect. // Will keep polygon aspect if only width or height is given. fitRect?: {x?: number, y?: number, width?: number: height?: number}, // Translate the polygon. Default to be [0, 0] // Will be ignored if fitRect is given. translate?: ArrayLike, // Scale the polygon. Default to be [1, 1] // Will be ignored if fitRect is given. scale?: ArrayLike } ) => { indices: Uint16Array|Uint32Array, position: Float32Array, normal: Float32Array, uv: Float32Array, boundingRect: {x: number, y: number, width: number, height: number} } ``` ### extrudePolyline ```typescript extrudePolyline( // polylines same with coordinates of MultiLineString type geometry in GeoJSON // See http://wiki.geojson.org/GeoJSON_draft_version_6#MultiLineString polylines: GeoJSONMultiLineStringGeometry, // Options of extrude opts: { ////// Extended from opts in extrudePolygon // Thickness of line, default to be 1 lineWidth?: number, // default to be 2 miterLimit?: number } ) => { indices: Uint16Array|Uint32Array, position: Float32Array, normal: Float32Array, uv: Float32Array, boundingRect: {x: number, y: number, width: number, height: number} } ``` ### extrudeGeoJSON ```typescript extrudeGeoJSON( // Extrude geojson with Polygon/LineString/MultiPolygon/MultiLineString geometries. geojson: GeoJSON, // Options of extrude opts: { ////// Extended from opts in extrudePolygon // Can be a constant value, or a function with parameter of each feature in geojson. // Default to be 1. depth?: ((feature: GeoJSONFeature) => number) | number // Thickness of line, default to be 1 lineWidth?: number, // default to be 2 miterLimit?: number } ) => { // Same result with extrudePolygon polygon: Object, // Same result with extrudePolyline polyline: Object } ``` ================================================ FILE: dist/geometry-extrude.js ================================================ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.geometryExtrude = {})); })(this, (function (exports) { 'use strict'; var earcut$2 = {exports: {}}; earcut$2.exports = earcut; earcut$2.exports.default = earcut; function earcut(data, holeIndices, dim) { dim = dim || 2; var hasHoles = holeIndices && holeIndices.length, outerLen = hasHoles ? holeIndices[0] * dim : data.length, outerNode = linkedList(data, 0, outerLen, dim, true), triangles = []; if (!outerNode || outerNode.next === outerNode.prev) return triangles; var minX, minY, maxX, maxY, x, y, invSize; if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox if (data.length > 80 * dim) { minX = maxX = data[0]; minY = maxY = data[1]; for (var i = dim; i < outerLen; i += dim) { x = data[i]; y = data[i + 1]; if (x < minX) minX = x; if (y < minY) minY = y; if (x > maxX) maxX = x; if (y > maxY) maxY = y; } // minX, minY and invSize are later used to transform coords into integers for z-order calculation invSize = Math.max(maxX - minX, maxY - minY); invSize = invSize !== 0 ? 1 / invSize : 0; } earcutLinked(outerNode, triangles, dim, minX, minY, invSize); return triangles; } // create a circular doubly linked list from polygon points in the specified winding order function linkedList(data, start, end, dim, clockwise) { var i, last; if (clockwise === (signedArea(data, start, end, dim) > 0)) { for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last); } else { for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last); } if (last && equals(last, last.next)) { removeNode(last); last = last.next; } return last; } // eliminate colinear or duplicate points function filterPoints(start, end) { if (!start) return start; if (!end) end = start; var p = start, again; do { again = false; if (!p.steiner && (equals(p, p.next) || area$1(p.prev, p, p.next) === 0)) { removeNode(p); p = end = p.prev; if (p === p.next) break; again = true; } else { p = p.next; } } while (again || p !== end); return end; } // main ear slicing loop which triangulates a polygon (given as a linked list) function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { if (!ear) return; // interlink polygon nodes in z-order if (!pass && invSize) indexCurve(ear, minX, minY, invSize); var stop = ear, prev, next; // iterate through ears, slicing them one by one while (ear.prev !== ear.next) { prev = ear.prev; next = ear.next; if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) { // cut off the triangle triangles.push(prev.i / dim); triangles.push(ear.i / dim); triangles.push(next.i / dim); removeNode(ear); // skipping the next vertex leads to less sliver triangles ear = next.next; stop = next.next; continue; } ear = next; // if we looped through the whole remaining polygon and can't find any more ears if (ear === stop) { // try filtering points and slicing again if (!pass) { earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); // if this didn't work, try curing all small self-intersections locally } else if (pass === 1) { ear = cureLocalIntersections(filterPoints(ear), triangles, dim); earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); // as a last resort, try splitting the remaining polygon into two } else if (pass === 2) { splitEarcut(ear, triangles, dim, minX, minY, invSize); } break; } } } // check whether a polygon node forms a valid ear with adjacent nodes function isEar(ear) { var a = ear.prev, b = ear, c = ear.next; if (area$1(a, b, c) >= 0) return false; // reflex, can't be an ear // now make sure we don't have other points inside the potential ear var p = ear.next.next; while (p !== ear.prev) { if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area$1(p.prev, p, p.next) >= 0) return false; p = p.next; } return true; } function isEarHashed(ear, minX, minY, invSize) { var a = ear.prev, b = ear, c = ear.next; if (area$1(a, b, c) >= 0) return false; // reflex, can't be an ear // triangle bbox; min & max are calculated like this for speed var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x), minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y), maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x), maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y); // z-order range for the current triangle bbox; var minZ = zOrder(minTX, minTY, minX, minY, invSize), maxZ = zOrder(maxTX, maxTY, minX, minY, invSize); var p = ear.prevZ, n = ear.nextZ; // look for points inside the triangle in both directions while (p && p.z >= minZ && n && n.z <= maxZ) { if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area$1(p.prev, p, p.next) >= 0) return false; p = p.prevZ; if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area$1(n.prev, n, n.next) >= 0) return false; n = n.nextZ; } // look for remaining points in decreasing z-order while (p && p.z >= minZ) { if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area$1(p.prev, p, p.next) >= 0) return false; p = p.prevZ; } // look for remaining points in increasing z-order while (n && n.z <= maxZ) { if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area$1(n.prev, n, n.next) >= 0) return false; n = n.nextZ; } return true; } // go through all polygon nodes and cure small local self-intersections function cureLocalIntersections(start, triangles, dim) { var p = start; do { var a = p.prev, b = p.next.next; if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { triangles.push(a.i / dim); triangles.push(p.i / dim); triangles.push(b.i / dim); // remove two nodes involved removeNode(p); removeNode(p.next); p = start = b; } p = p.next; } while (p !== start); return filterPoints(p); } // try splitting polygon into two and triangulate them independently function splitEarcut(start, triangles, dim, minX, minY, invSize) { // look for a valid diagonal that divides the polygon into two var a = start; do { var b = a.next.next; while (b !== a.prev) { if (a.i !== b.i && isValidDiagonal(a, b)) { // split the polygon in two by the diagonal var c = splitPolygon(a, b); // filter colinear points around the cuts a = filterPoints(a, a.next); c = filterPoints(c, c.next); // run earcut on each half earcutLinked(a, triangles, dim, minX, minY, invSize); earcutLinked(c, triangles, dim, minX, minY, invSize); return; } b = b.next; } a = a.next; } while (a !== start); } // link every hole into the outer loop, producing a single-ring polygon without holes function eliminateHoles(data, holeIndices, outerNode, dim) { var queue = [], i, len, start, end, list; for (i = 0, len = holeIndices.length; i < len; i++) { start = holeIndices[i] * dim; end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; list = linkedList(data, start, end, dim, false); if (list === list.next) list.steiner = true; queue.push(getLeftmost(list)); } queue.sort(compareX); // process holes from left to right for (i = 0; i < queue.length; i++) { outerNode = eliminateHole(queue[i], outerNode); outerNode = filterPoints(outerNode, outerNode.next); } return outerNode; } function compareX(a, b) { return a.x - b.x; } // find a bridge between vertices that connects hole with an outer ring and and link it function eliminateHole(hole, outerNode) { var bridge = findHoleBridge(hole, outerNode); if (!bridge) { return outerNode; } var bridgeReverse = splitPolygon(bridge, hole); // filter collinear points around the cuts var filteredBridge = filterPoints(bridge, bridge.next); filterPoints(bridgeReverse, bridgeReverse.next); // Check if input node was removed by the filtering return outerNode === bridge ? filteredBridge : outerNode; } // David Eberly's algorithm for finding a bridge between hole and outer polygon function findHoleBridge(hole, outerNode) { var p = outerNode, hx = hole.x, hy = hole.y, qx = -Infinity, m; // find a segment intersected by a ray from the hole's leftmost point to the left; // segment's endpoint with lesser x will be potential connection point do { if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); if (x <= hx && x > qx) { qx = x; if (x === hx) { if (hy === p.y) return p; if (hy === p.next.y) return p.next; } m = p.x < p.next.x ? p : p.next; } } p = p.next; } while (p !== outerNode); if (!m) return null; if (hx === qx) return m; // hole touches outer segment; pick leftmost endpoint // look for points inside the triangle of hole point, segment intersection and endpoint; // if there are no points found, we have a valid connection; // otherwise choose the point of the minimum angle with the ray as connection point var stop = m, mx = m.x, my = m.y, tanMin = Infinity, tan; p = m; do { if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { tan = Math.abs(hy - p.y) / (hx - p.x); // tangential if (locallyInside(p, hole) && (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) { m = p; tanMin = tan; } } p = p.next; } while (p !== stop); return m; } // whether sector in vertex m contains sector in vertex p in the same coordinates function sectorContainsSector(m, p) { return area$1(m.prev, m, p.prev) < 0 && area$1(p.next, m, m.next) < 0; } // interlink polygon nodes in z-order function indexCurve(start, minX, minY, invSize) { var p = start; do { if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize); p.prevZ = p.prev; p.nextZ = p.next; p = p.next; } while (p !== start); p.prevZ.nextZ = null; p.prevZ = null; sortLinked(p); } // Simon Tatham's linked list merge sort algorithm // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html function sortLinked(list) { var i, p, q, e, tail, numMerges, pSize, qSize, inSize = 1; do { p = list; list = null; tail = null; numMerges = 0; while (p) { numMerges++; q = p; pSize = 0; for (i = 0; i < inSize; i++) { pSize++; q = q.nextZ; if (!q) break; } qSize = inSize; while (pSize > 0 || (qSize > 0 && q)) { if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { e = p; p = p.nextZ; pSize--; } else { e = q; q = q.nextZ; qSize--; } if (tail) tail.nextZ = e; else list = e; e.prevZ = tail; tail = e; } p = q; } tail.nextZ = null; inSize *= 2; } while (numMerges > 1); return list; } // z-order of a point given coords and inverse of the longer side of data bbox function zOrder(x, y, minX, minY, invSize) { // coords are transformed into non-negative 15-bit integer range x = 32767 * (x - minX) * invSize; y = 32767 * (y - minY) * invSize; x = (x | (x << 8)) & 0x00FF00FF; x = (x | (x << 4)) & 0x0F0F0F0F; x = (x | (x << 2)) & 0x33333333; x = (x | (x << 1)) & 0x55555555; y = (y | (y << 8)) & 0x00FF00FF; y = (y | (y << 4)) & 0x0F0F0F0F; y = (y | (y << 2)) & 0x33333333; y = (y | (y << 1)) & 0x55555555; return x | (y << 1); } // find the leftmost node of a polygon ring function getLeftmost(start) { var p = start, leftmost = start; do { if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p; p = p.next; } while (p !== start); return leftmost; } // check if a point lies within a convex triangle function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0; } // check if a diagonal between two polygon nodes is valid (lies in polygon interior) function isValidDiagonal(a, b) { return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible (area$1(a.prev, a, b.prev) || area$1(a, b.prev, b)) || // does not create opposite-facing sectors equals(a, b) && area$1(a.prev, a, a.next) > 0 && area$1(b.prev, b, b.next) > 0); // special zero-length case } // signed area of a triangle function area$1(p, q, r) { return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); } // check if two points are equal function equals(p1, p2) { return p1.x === p2.x && p1.y === p2.y; } // check if two segments intersect function intersects(p1, q1, p2, q2) { var o1 = sign(area$1(p1, q1, p2)); var o2 = sign(area$1(p1, q1, q2)); var o3 = sign(area$1(p2, q2, p1)); var o4 = sign(area$1(p2, q2, q1)); if (o1 !== o2 && o3 !== o4) return true; // general case if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1 if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1 if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2 if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2 return false; } // for collinear points p, q, r, check if point q lies on segment pr function onSegment(p, q, r) { return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y); } function sign(num) { return num > 0 ? 1 : num < 0 ? -1 : 0; } // check if a polygon diagonal intersects any polygon segments function intersectsPolygon(a, b) { var p = a; do { if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b)) return true; p = p.next; } while (p !== a); return false; } // check if a polygon diagonal is locally inside the polygon function locallyInside(a, b) { return area$1(a.prev, a, a.next) < 0 ? area$1(a, b, a.next) >= 0 && area$1(a, a.prev, b) >= 0 : area$1(a, b, a.prev) < 0 || area$1(a, a.next, b) < 0; } // check if the middle point of a polygon diagonal is inside the polygon function middleInside(a, b) { var p = a, inside = false, px = (a.x + b.x) / 2, py = (a.y + b.y) / 2; do { if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y && (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)) inside = !inside; p = p.next; } while (p !== a); return inside; } // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; // if one belongs to the outer ring and another to a hole, it merges it into a single ring function splitPolygon(a, b) { var a2 = new Node(a.i, a.x, a.y), b2 = new Node(b.i, b.x, b.y), an = a.next, bp = b.prev; a.next = b; b.prev = a; a2.next = an; an.prev = a2; b2.next = a2; a2.prev = b2; bp.next = b2; b2.prev = bp; return b2; } // create a node and optionally link it with previous one (in a circular doubly linked list) function insertNode(i, x, y, last) { var p = new Node(i, x, y); if (!last) { p.prev = p; p.next = p; } else { p.next = last.next; p.prev = last; last.next.prev = p; last.next = p; } return p; } function removeNode(p) { p.next.prev = p.prev; p.prev.next = p.next; if (p.prevZ) p.prevZ.nextZ = p.nextZ; if (p.nextZ) p.nextZ.prevZ = p.prevZ; } function Node(i, x, y) { // vertex index in coordinates array this.i = i; // vertex coordinates this.x = x; this.y = y; // previous and next vertex nodes in a polygon ring this.prev = null; this.next = null; // z-order curve value this.z = null; // previous and next nodes in z-order this.prevZ = null; this.nextZ = null; // indicates whether this is a steiner point this.steiner = false; } // return a percentage difference between the polygon area and its triangulation area; // used to verify correctness of triangulation earcut.deviation = function (data, holeIndices, dim, triangles) { var hasHoles = holeIndices && holeIndices.length; var outerLen = hasHoles ? holeIndices[0] * dim : data.length; var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim)); if (hasHoles) { for (var i = 0, len = holeIndices.length; i < len; i++) { var start = holeIndices[i] * dim; var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; polygonArea -= Math.abs(signedArea(data, start, end, dim)); } } var trianglesArea = 0; for (i = 0; i < triangles.length; i += 3) { var a = triangles[i] * dim; var b = triangles[i + 1] * dim; var c = triangles[i + 2] * dim; trianglesArea += Math.abs( (data[a] - data[c]) * (data[b + 1] - data[a + 1]) - (data[a] - data[b]) * (data[c + 1] - data[a + 1])); } return polygonArea === 0 && trianglesArea === 0 ? 0 : Math.abs((trianglesArea - polygonArea) / polygonArea); }; function signedArea(data, start, end, dim) { var sum = 0; for (var i = start, j = end - dim; i < end; i += dim) { sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); j = i; } return sum; } // turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts earcut.flatten = function (data) { var dim = data[0][0].length, result = {vertices: [], holes: [], dimensions: dim}, holeIndex = 0; for (var i = 0; i < data.length; i++) { for (var j = 0; j < data[i].length; j++) { for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); } if (i > 0) { holeIndex += data[i - 1].length; result.holes.push(holeIndex); } } return result; }; var earcut$1 = earcut$2.exports; /* (c) 2017, Vladimir Agafonkin Simplify.js, a high-performance JS polyline simplification library mourner.github.io/simplify-js */ // to suit your point format, run search/replace for '.x' and '.y'; // for 3D version, see 3d branch (configurability would draw significant performance overhead) // square distance between 2 points function getSqDist(p1, p2) { var dx = p1[0] - p2[0], dy = p1[1] - p2[1]; return dx * dx + dy * dy; } // square distance from a point to a segment function getSqSegDist(p, p1, p2) { var x = p1[0], y = p1[1], dx = p2[0] - x, dy = p2[1] - y; if (dx !== 0 || dy !== 0) { var t = ((p[0] - x) * dx + (p[1] - y) * dy) / (dx * dx + dy * dy); if (t > 1) { x = p2[0]; y = p2[1]; } else if (t > 0) { x += dx * t; y += dy * t; } } dx = p[0] - x; dy = p[1] - y; return dx * dx + dy * dy; } // rest of the code doesn't care about point format // basic distance-based simplification function simplifyRadialDist(points, sqTolerance) { var prevPoint = points[0], newPoints = [prevPoint], point; for (var i = 1, len = points.length; i < len; i++) { point = points[i]; if (getSqDist(point, prevPoint) > sqTolerance) { newPoints.push(point); prevPoint = point; } } if (prevPoint !== point) newPoints.push(point); return newPoints; } function simplifyDPStep(points, first, last, sqTolerance, simplified) { var maxSqDist = sqTolerance, index; for (var i = first + 1; i < last; i++) { var sqDist = getSqSegDist(points[i], points[first], points[last]); if (sqDist > maxSqDist) { index = i; maxSqDist = sqDist; } } if (maxSqDist > sqTolerance) { if (index - first > 1) simplifyDPStep(points, first, index, sqTolerance, simplified); simplified.push(points[index]); if (last - index > 1) simplifyDPStep(points, index, last, sqTolerance, simplified); } } // simplification using Ramer-Douglas-Peucker algorithm function simplifyDouglasPeucker(points, sqTolerance) { var last = points.length - 1; var simplified = [points[0]]; simplifyDPStep(points, 0, last, sqTolerance, simplified); simplified.push(points[last]); return simplified; } // both algorithms combined for awesome performance function simplify(points, tolerance, highestQuality) { if (points.length <= 2) return points; var sqTolerance = tolerance !== undefined ? tolerance * tolerance : 1; points = highestQuality ? points : simplifyRadialDist(points, sqTolerance); points = simplifyDouglasPeucker(points, sqTolerance); return points; } function dot(v1, v2) { return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; } function v2Dot(v1, v2) { return v1[0] * v2[0] + v1[1] * v2[1]; } function normalize(out, v) { var x = v[0]; var y = v[1]; var z = v[2]; var d = Math.sqrt(x * x + y * y + z * z); out[0] = x / d; out[1] = y / d; out[2] = z / d; return out; } function v2Normalize(out, v) { var x = v[0]; var y = v[1]; var d = Math.sqrt(x * x + y * y); out[0] = x / d; out[1] = y / d; return out; } function scale(out, v, s) { out[0] = v[0] * s; out[1] = v[1] * s; out[2] = v[2] * s; return out; } function scaleAndAdd(out, v1, v2, s) { out[0] = v1[0] + v2[0] * s; out[1] = v1[1] + v2[1] * s; out[2] = v1[2] + v2[2] * s; return out; } function v2Add(out, v1, v2) { out[0] = v1[0] + v2[0]; out[1] = v1[1] + v2[1]; return out; } function v3Sub(out, v1, v2) { out[0] = v1[0] - v2[0]; out[1] = v1[1] - v2[1]; out[2] = v1[2] - v2[2]; return out; } function v3Normalize(out, v) { var x = v[0]; var y = v[1]; var z = v[2]; var d = Math.sqrt(x * x + y * y + z * z); out[0] = x / d; out[1] = y / d; out[2] = z / d; return out; } function v3Cross(out, v1, v2) { var ax = v1[0], ay = v1[1], az = v1[2], bx = v2[0], by = v2[1], bz = v2[2]; out[0] = ay * bz - az * by; out[1] = az * bx - ax * bz; out[2] = ax * by - ay * bx; return out; } var rel = []; // start and end must be normalized function slerp(out, start, end, t) { // https://keithmaggio.wordpress.com/2011/02/15/math-magician-lerp-slerp-and-nlerp/ var cosT = dot(start, end); var theta = Math.acos(cosT) * t; scaleAndAdd(rel, end, start, -cosT); normalize(rel, rel); // start and rel Orthonormal basis scale(out, start, Math.cos(theta)); scaleAndAdd(out, out, rel, Math.sin(theta)); return out; } function lineIntersection(x1, y1, x2, y2, x3, y3, x4, y4, out, writeOffset) { var dx1 = x2 - x1; var dx2 = x4 - x3; var dy1 = y2 - y1; var dy2 = y4 - y3; var cross = dy2 * dx1 - dx2 * dy1; var tmp1 = y1 - y3; var tmp2 = x1 - x3; var t1 = (dx2 * tmp1 - dy2 * tmp2) / cross; // const t2 = (dx1 * tmp1 - dy1 * tmp2) / cross; if (out) { writeOffset = writeOffset || 0; out[writeOffset] = x1 + t1 * (x2 - x1); out[writeOffset + 1] = y1 + t1 * (y2 - y1); } return t1; } function area(points, start, end) { // Signed polygon area var n = end - start; if (n < 3) { return 0; } var area = 0; for (var i = (end - 1) * 2, j = start * 2; j < end * 2;) { var x0 = points[i]; var y0 = points[i + 1]; var x1 = points[j]; var y1 = points[j + 1]; i = j; j += 2; area += x0 * y1 - x1 * y0; } return area; } // TODO fitRect x, y are negative? function triangulate(vertices, holes) { var dimensions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 2; return earcut$1(vertices, holes, dimensions); } function flatten(data) { return earcut$1.flatten(data); } var v1 = []; var v2 = []; var v = []; function innerOffsetPolygon(vertices, out, start, end, outStart, offset, miterLimit, close, removeIntersections // offsetLines ) { var checkMiterLimit = miterLimit != null; var cursor = outStart; var indicesMap = null; if (checkMiterLimit) { indicesMap = new Uint32Array(end - start); } var prevOffsetX; var prevOffsetY; var prevCursor; var tmpIntersection = []; for (var i = start; i < end; i++) { var nextIdx = i === end - 1 ? start : i + 1; var prevIdx = i === start ? end - 1 : i - 1; var x1 = vertices[prevIdx * 2]; var y1 = vertices[prevIdx * 2 + 1]; var x2 = vertices[i * 2]; var y2 = vertices[i * 2 + 1]; var x3 = vertices[nextIdx * 2]; var y3 = vertices[nextIdx * 2 + 1]; v1[0] = x2 - x1; v1[1] = y2 - y1; v2[0] = x3 - x2; v2[1] = y3 - y2; v2Normalize(v1, v1); v2Normalize(v2, v2); checkMiterLimit && (indicesMap[i] = cursor); var needCheckIntersection = false; var offsetX = void 0; var offsetY = void 0; if (!close && i === start) { v[0] = v2[1]; v[1] = -v2[0]; v2Normalize(v, v); prevOffsetX = out[cursor * 2] = x2 + v[0] * offset; prevOffsetY = out[cursor * 2 + 1] = y2 + v[1] * offset; prevCursor = cursor; // offsetLines && offsetLines.push([x2, y2, prevOffsetX, prevOffsetY, cursor]) cursor++; } else if (!close && i === end - 1) { v[0] = v1[1]; v[1] = -v1[0]; v2Normalize(v, v); offsetX = x2 + v[0] * offset; offsetY = y2 + v[1] * offset; needCheckIntersection = true; } else { // PENDING Why using sub will lost the direction info. v2Add(v, v2, v1); var tmp = v[1]; v[1] = -v[0]; v[0] = tmp; v2Normalize(v, v); var cosA = v2Dot(v, v2); var sinA = Math.sqrt(1 - cosA * cosA); // PENDING // Make sure it's offset lines instead of vertices. var miter = offset * Math.min(10, 1 / sinA); var isCovex = offset * cosA < 0; if (checkMiterLimit && 1 / sinA > miterLimit && isCovex) { // No need to check line intersection on the outline. var mx = x2 + v[0] * offset; var my = y2 + v[1] * offset; var halfA = Math.acos(sinA) / 2; var dist = Math.tan(halfA) * Math.abs(offset); out[cursor * 2] = mx + v[1] * dist; out[cursor * 2 + 1] = my - v[0] * dist; cursor++; out[cursor * 2] = mx - v[1] * dist; out[cursor * 2 + 1] = my + v[0] * dist; cursor++; } else { offsetX = x2 + v[0] * miter; offsetY = y2 + v[1] * miter; needCheckIntersection = true; } if (needCheckIntersection) { // TODO Handle with whole. if (removeIntersections && prevOffsetX != null) { // Greedy, only check with previous offset line // PENDING: Is it necessary to check with other lines? var t = lineIntersection(x1, y1, prevOffsetX, prevOffsetY, x2, y2, offsetX, offsetY, tmpIntersection, 0); // Use a eplison if (t >= -1e-2 && t <= 1 + 1e-2) { // Update previous offset points. out[prevCursor * 2] = offsetX = tmpIntersection[0]; out[prevCursor * 2 + 1] = offsetY = tmpIntersection[1]; } } prevOffsetX = out[cursor * 2] = offsetX; prevOffsetY = out[cursor * 2 + 1] = offsetY; prevCursor = cursor; // offsetLines && offsetLines.push([x2, y2, offsetX, offsetY, cursor]) cursor++; } } } return indicesMap; } function offsetPolygon(vertices, holes, offset, miterLimit, close) { var offsetVertices = miterLimit != null ? [] : new Float32Array(vertices.length); var exteriorSize = holes && holes.length ? holes[0] : vertices.length / 2; innerOffsetPolygon(vertices, offsetVertices, 0, exteriorSize, 0, offset, miterLimit, close, true); if (holes) { for (var i = 0; i < holes.length; i++) { var start = holes[i]; var end = holes[i + 1] || vertices.length / 2; innerOffsetPolygon(vertices, offsetVertices, start, end, miterLimit != null ? offsetVertices.length / 2 : start, offset, miterLimit, close, false); } } // TODO holes // Remove intersections of offseted polygon // let len = offsetLines.length; // let tmpIntersection = []; // for (let i = 0; i < len; i++) { // const line1 = offsetLines[i]; // for (let k = i + 1; k < len; k++) { // const line2 = offsetLines[k]; // const t = lineIntersection( // line1[0], line1[1], line1[2], line1[3], // line2[0], line2[1], line2[2], line2[3], tmpIntersection, 0 // ); // // Use a eplison // if (t >= -1e-2 && t <= 1 + 1e-2) { // const cursor1 = line1[4] * 2; // const cursor2 = line2[4] * 2; // // Update // offsetVertices[cursor1] = offsetVertices[cursor2] = line1[2] = line2[2] = tmpIntersection[0]; // offsetVertices[cursor1 + 1] = offsetVertices[cursor2 + 1] = line1[3] = line2[3]= tmpIntersection[1]; // } // } // } return offsetVertices; } function reversePoints(points, stride, start, end) { for (var i = 0; i < Math.floor((end - start) / 2); i++) { for (var j = 0; j < stride; j++) { var a = (i + start) * stride + j; var b = (end - i - 1) * stride + j; var tmp = points[a]; points[a] = points[b]; points[b] = tmp; } } return points; } function convertToClockwise(vertices, holes) { var polygonVertexCount = vertices.length / 2; var start = 0; var end = holes && holes.length ? holes[0] : polygonVertexCount; if (area(vertices, start, end) > 0) { reversePoints(vertices, 2, start, end); } for (var h = 1; h < (holes ? holes.length : 0) + 1; h++) { start = holes[h - 1]; end = holes[h] || polygonVertexCount; if (area(vertices, start, end) < 0) { reversePoints(vertices, 2, start, end); } } } function normalizeOpts(opts) { opts.depth = opts.depth || 1; opts.bevelSize = opts.bevelSize || 0; opts.bevelSegments = opts.bevelSegments == null ? 2 : opts.bevelSegments; opts.smoothBevel = opts.smoothBevel || false; opts.simplify = opts.simplify || 0; if (opts.smoothSide == null) { opts.smoothSide = 'auto'; } if (opts.smoothSideThreshold == null) { opts.smoothSideThreshold = 0.9; } // Normalize bevel options. if (typeof opts.depth === 'number') { opts.bevelSize = Math.min(!(opts.bevelSegments > 0) ? 0 : opts.bevelSize, opts.depth / 2); } if (!(opts.bevelSize > 0)) { opts.bevelSegments = 0; } opts.bevelSegments = Math.round(opts.bevelSegments); var boundingRect = opts.boundingRect; opts.translate = opts.translate || [0, 0]; opts.scale = opts.scale || [1, 1]; if (opts.fitRect) { var targetX = opts.fitRect.x == null ? boundingRect.x || 0 : opts.fitRect.x; var targetY = opts.fitRect.y == null ? boundingRect.y || 0 : opts.fitRect.y; var targetWidth = opts.fitRect.width; var targetHeight = opts.fitRect.height; if (targetWidth == null) { if (targetHeight != null) { targetWidth = targetHeight / boundingRect.height * boundingRect.width; } else { targetWidth = boundingRect.width; targetHeight = boundingRect.height; } } else if (targetHeight == null) { targetHeight = targetWidth / boundingRect.width * boundingRect.height; } opts.scale = [targetWidth / boundingRect.width, targetHeight / boundingRect.height]; opts.translate = [(targetX - boundingRect.x) * opts.scale[0], (targetY - boundingRect.y) * opts.scale[1]]; } } function generateNormal(indices, position) { function v3Set(p, a, b, c) { p[0] = a; p[1] = b; p[2] = c; } var p1 = []; var p2 = []; var p3 = []; var v21 = []; var v32 = []; var n = []; var len = indices.length; var normals = new Float32Array(position.length); for (var f = 0; f < len;) { var i1 = indices[f++] * 3; var i2 = indices[f++] * 3; var i3 = indices[f++] * 3; v3Set(p1, position[i1], position[i1 + 1], position[i1 + 2]); v3Set(p2, position[i2], position[i2 + 1], position[i2 + 2]); v3Set(p3, position[i3], position[i3 + 1], position[i3 + 2]); v3Sub(v21, p1, p2); v3Sub(v32, p2, p3); v3Cross(n, v21, v32); // Already be weighted by the triangle area for (var _i = 0; _i < 3; _i++) { normals[i1 + _i] = normals[i1 + _i] + n[_i]; normals[i2 + _i] = normals[i2 + _i] + n[_i]; normals[i3 + _i] = normals[i3 + _i] + n[_i]; } } for (var i = 0; i < normals.length;) { v3Set(n, normals[i], normals[i + 1], normals[i + 2]); v3Normalize(n, n); normals[i++] = n[0]; normals[i++] = n[1]; normals[i++] = n[2]; } return normals; } // 0,0----1,0 // 0,1----1,1 var quadToTriangle = [[0, 0], [1, 0], [1, 1], [0, 0], [1, 1], [0, 1]]; // Add side vertices and indices. Include bevel. function addExtrudeSide(out, _ref, start, end, cursors, opts) { var vertices = _ref.vertices, topVertices = _ref.topVertices, splittedMap = _ref.splittedMap, depth = _ref.depth, rect = _ref.rect; var ringVertexCount = end - start; var splitBevel = opts.smoothBevel ? 1 : 2; var bevelSize = Math.min(depth / 2, opts.bevelSize); var bevelSegments = opts.bevelSegments; var vertexOffset = cursors.vertex; var size = Math.max(rect.width, rect.height, depth); var isDuplicateVertex = splittedMap ? function (idx) { var nextIdx = (idx + 1) % ringVertexCount; return splittedMap[idx + start] === splittedMap[nextIdx + start]; } : function (idx) { return false; }; // Side vertices if (bevelSize > 0) { var v0 = [0, 0, 1]; var _v = []; var _v2 = [0, 0, -1]; var _v3 = []; var ringCount = 0; var vLen = new Float32Array(ringVertexCount); for (var k = 0; k < 2; k++) { var z = k === 0 ? depth - bevelSize : bevelSize; for (var s = 0; s <= bevelSegments * splitBevel; s++) { var uLen = 0; var prevX = void 0; var prevY = void 0; for (var i = 0; i < ringVertexCount; i++) { var idx = (i % ringVertexCount + start) * 2; var rawIdx = splittedMap ? splittedMap[idx / 2] * 2 : idx; _v[0] = vertices[idx] - topVertices[rawIdx]; _v[1] = vertices[idx + 1] - topVertices[rawIdx + 1]; _v[2] = 0; var l = Math.sqrt(_v[0] * _v[0] + _v[1] * _v[1]); _v[0] /= l; _v[1] /= l; var t = (Math.floor(s / splitBevel) + s % splitBevel) / bevelSegments; k === 0 ? slerp(_v3, v0, _v, t) : slerp(_v3, _v, _v2, t); var t2 = k === 0 ? t : 1 - t; var a = bevelSize * Math.sin(t2 * Math.PI / 2); var b = l * Math.cos(t2 * Math.PI / 2); // ellipse radius var r = bevelSize * l / Math.sqrt(a * a + b * b); var x = _v3[0] * r + topVertices[rawIdx]; var y = _v3[1] * r + topVertices[rawIdx + 1]; var zz = _v3[2] * r + z; out.position[cursors.vertex * 3] = x; out.position[cursors.vertex * 3 + 1] = y; out.position[cursors.vertex * 3 + 2] = zz; // TODO Cache and optimize if (i > 0) { uLen += Math.sqrt((prevX - x) * (prevX - x) + (prevY - y) * (prevY - y)); } if (s > 0 || k > 0) { var tmp = (cursors.vertex - ringVertexCount) * 3; var prevX2 = out.position[tmp]; var prevY2 = out.position[tmp + 1]; var prevZ2 = out.position[tmp + 2]; vLen[i] += Math.sqrt((prevX2 - x) * (prevX2 - x) + (prevY2 - y) * (prevY2 - y) + (prevZ2 - zz) * (prevZ2 - zz)); } out.uv[cursors.vertex * 2] = uLen / size; out.uv[cursors.vertex * 2 + 1] = vLen[i] / size; prevX = x; prevY = y; cursors.vertex++; // Just ignore this face if vertex are duplicted in `splitVertices` if (isDuplicateVertex(i)) { continue; } if (splitBevel > 1 && s % splitBevel || splitBevel === 1 && s >= 1) { for (var f = 0; f < 6; f++) { var m = (quadToTriangle[f][0] + i) % ringVertexCount; var n = quadToTriangle[f][1] + ringCount; out.indices[cursors.index++] = (n - 1) * ringVertexCount + m + vertexOffset; } } } ringCount++; } } } else { for (var _k = 0; _k < 2; _k++) { var _z = _k === 0 ? depth : 0; var _uLen = 0; var _prevX = void 0; var _prevY = void 0; for (var _i2 = 0; _i2 < ringVertexCount; _i2++) { var _idx = (_i2 + start) * 2; var _x = vertices[_idx]; var _y = vertices[_idx + 1]; var vtx3 = cursors.vertex * 3; var vtx2 = cursors.vertex * 2; out.position[vtx3] = _x; out.position[vtx3 + 1] = _y; out.position[vtx3 + 2] = _z; if (_i2 > 0) { _uLen += Math.sqrt((_prevX - _x) * (_prevX - _x) + (_prevY - _y) * (_prevY - _y)); } out.uv[vtx2] = _uLen / size; out.uv[vtx2 + 1] = _z / size; _prevX = _x; _prevY = _y; cursors.vertex++; } } } // Connect the side var sideStartRingN = bevelSize > 0 ? bevelSegments * splitBevel + 1 : 1; for (var _i3 = 0; _i3 < ringVertexCount; _i3++) { // Just ignore this face if vertex are duplicted in `splitVertices` if (isDuplicateVertex(_i3)) { continue; } for (var _f = 0; _f < 6; _f++) { var _m = (quadToTriangle[_f][0] + _i3) % ringVertexCount; var _n = quadToTriangle[_f][1] + sideStartRingN; out.indices[cursors.index++] = (_n - 1) * ringVertexCount + _m + vertexOffset; } } } function addTopAndBottom(_ref2, out, cursors, opts) { var indices = _ref2.indices, topVertices = _ref2.topVertices, rect = _ref2.rect, depth = _ref2.depth; if (topVertices.length <= 4) { return; } var vertexOffset = cursors.vertex; // Top indices var indicesLen = indices.length; for (var i = 0; i < indicesLen; i++) { out.indices[cursors.index++] = vertexOffset + indices[i]; } var size = Math.max(rect.width, rect.height); // Top and bottom vertices for (var k = 0; k < (opts.excludeBottom ? 1 : 2); k++) { for (var _i4 = 0; _i4 < topVertices.length; _i4 += 2) { var x = topVertices[_i4]; var y = topVertices[_i4 + 1]; var vtx3 = cursors.vertex * 3; var vtx2 = cursors.vertex * 2; out.position[vtx3] = x; out.position[vtx3 + 1] = y; out.position[vtx3 + 2] = (1 - k) * depth; out.uv[vtx2] = (x - rect.x) / size; out.uv[vtx2 + 1] = (y - rect.y) / size; cursors.vertex++; } } // Bottom indices if (!opts.excludeBottom) { var vertexCount = topVertices.length / 2; for (var _i5 = 0; _i5 < indicesLen; _i5 += 3) { for (var _k2 = 0; _k2 < 3; _k2++) { out.indices[cursors.index++] = vertexOffset + vertexCount + indices[_i5 + 2 - _k2]; } } } } /** * Split vertices for sharp side. */ function splitVertices(vertices, holes, smoothSide, smoothSideThreshold) { var isAutoSmooth = smoothSide == null || smoothSide === 'auto'; if (smoothSide === true) { return { vertices: vertices, holes: holes }; } var newVertices = []; var newHoles = holes && []; var count = vertices.length / 2; var v1 = []; var v2 = []; // Map of splitted index to raw index var splittedMap = []; var start = 0; var end = 0; var polysCount = (holes ? holes.length : 0) + 1; for (var h = 0; h < polysCount; h++) { if (h === 0) { end = holes && holes.length ? holes[0] : count; } else { start = holes[h - 1]; end = holes[h] || count; } for (var i = start; i < end; i++) { var x2 = vertices[i * 2]; var y2 = vertices[i * 2 + 1]; var nextIdx = i === end - 1 ? start : i + 1; var x3 = vertices[nextIdx * 2]; var y3 = vertices[nextIdx * 2 + 1]; if (isAutoSmooth) { var prevIdx = i === start ? end - 1 : i - 1; var x1 = vertices[prevIdx * 2]; var y1 = vertices[prevIdx * 2 + 1]; v1[0] = x1 - x2; v1[1] = y1 - y2; v2[0] = x3 - x2; v2[1] = y3 - y2; v2Normalize(v1, v1); v2Normalize(v2, v2); var angleCos = v2Dot(v1, v2) * 0.5 + 0.5; if (1 - angleCos > smoothSideThreshold) { newVertices.push(x2, y2); splittedMap.push(i); } else { newVertices.push(x2, y2, x2, y2); splittedMap.push(i, i); } } else { newVertices.push(x2, y2, x2, y2); splittedMap.push(i, i); } } if (h < polysCount - 1 && newHoles) { newHoles.push(newVertices.length / 2); } } return { vertices: new Float32Array(newVertices), splittedMap: splittedMap, holes: newHoles }; } function innerExtrudeTriangulatedPolygon(preparedData, opts) { var indexCount = 0; var vertexCount = 0; for (var p = 0; p < preparedData.length; p++) { var _preparedData$p = preparedData[p], indices = _preparedData$p.indices, _vertices = _preparedData$p.vertices, splittedMap = _preparedData$p.splittedMap, topVertices = _preparedData$p.topVertices, holes = _preparedData$p.holes, depth = _preparedData$p.depth; var bevelSize = Math.min(depth / 2, opts.bevelSize); var bevelSegments = !(bevelSize > 0) ? 0 : opts.bevelSegments; holes = holes || []; indexCount += indices.length * (opts.excludeBottom ? 1 : 2); vertexCount += topVertices.length / 2 * (opts.excludeBottom ? 1 : 2); var ringCount = 2 + bevelSegments * 2; var start = 0; var end = 0; for (var h = 0; h < holes.length + 1; h++) { if (h === 0) { end = holes.length ? holes[0] : _vertices.length / 2; } else { start = holes[h - 1]; end = holes[h] || _vertices.length / 2; } var faceEnd = splittedMap ? splittedMap[end - 1] + 1 : end; var faceStart = splittedMap ? splittedMap[start] : start; indexCount += (faceEnd - faceStart) * 6 * (ringCount - 1); var sideRingVertexCount = end - start; vertexCount += sideRingVertexCount * ringCount // Double the bevel vertex number if not smooth + (!opts.smoothBevel ? bevelSegments * sideRingVertexCount * 2 : 0); } } var data = { position: new Float32Array(vertexCount * 3), indices: new (vertexCount > 0xffff ? Uint32Array : Uint16Array)(indexCount), uv: new Float32Array(vertexCount * 2) }; var cursors = { vertex: 0, index: 0 }; for (var d = 0; d < preparedData.length; d++) { addTopAndBottom(preparedData[d], data, cursors, opts); } for (var _d = 0; _d < preparedData.length; _d++) { var _preparedData$_d = preparedData[_d], _holes = _preparedData$_d.holes, _vertices2 = _preparedData$_d.vertices; var _vertexCount = _vertices2.length / 2; var _start = 0; var _end = _holes && _holes.length ? _holes[0] : _vertexCount; // Add exterior addExtrudeSide(data, preparedData[_d], _start, _end, cursors, opts); // Add holes if (_holes) { for (var _h = 0; _h < _holes.length; _h++) { _start = _holes[_h]; _end = _holes[_h + 1] || _vertexCount; addExtrudeSide(data, preparedData[_d], _start, _end, cursors, opts); } } } // Wrap uv for (var i = 0; i < data.uv.length; i++) { var val = data.uv[i]; if (val > 0 && Math.round(val) === val) { data.uv[i] = 1; } else { data.uv[i] = val % 1; } } data.normal = generateNormal(data.indices, data.position); // PENDING data.boundingRect = preparedData[0] && preparedData[0].rect; return data; } function convertPolylineToTriangulatedPolygon(polyline, polylineIdx, opts) { var lineWidth = opts.lineWidth; var pointCount = polyline.length; var points = new Float32Array(pointCount * 2); var translate = opts.translate || [0, 0]; var scale = opts.scale || [1, 1]; for (var i = 0, k = 0; i < pointCount; i++) { points[k++] = polyline[i][0] * scale[0] + translate[0]; points[k++] = polyline[i][1] * scale[1] + translate[1]; } if (area(points, 0, pointCount) < 0) { reversePoints(points, 2, 0, pointCount); } var insidePoints = []; var outsidePoints = []; var miterLimit = opts.miterLimit; var outsideIndicesMap = innerOffsetPolygon(points, outsidePoints, 0, pointCount, 0, -lineWidth / 2, miterLimit, false, true); reversePoints(points, 2, 0, pointCount); var insideIndicesMap = innerOffsetPolygon(points, insidePoints, 0, pointCount, 0, -lineWidth / 2, miterLimit, false, true); var polygonVertexCount = (insidePoints.length + outsidePoints.length) / 2; var polygonVertices = new Float32Array(polygonVertexCount * 2); var offset = 0; var outsidePointCount = outsidePoints.length / 2; for (var _i6 = 0; _i6 < outsidePoints.length; _i6++) { polygonVertices[offset++] = outsidePoints[_i6]; } for (var _i7 = 0; _i7 < insidePoints.length; _i7++) { polygonVertices[offset++] = insidePoints[_i7]; } // Built indices var indices = new (polygonVertexCount > 0xffff ? Uint32Array : Uint16Array)(((pointCount - 1) * 2 + (polygonVertexCount - pointCount * 2)) * 3); var off = 0; for (var _i8 = 0; _i8 < pointCount - 1; _i8++) { var i2 = _i8 + 1; indices[off++] = outsidePointCount - 1 - outsideIndicesMap[_i8]; indices[off++] = outsidePointCount - 1 - outsideIndicesMap[_i8] - 1; indices[off++] = insideIndicesMap[_i8] + 1 + outsidePointCount; indices[off++] = outsidePointCount - 1 - outsideIndicesMap[_i8]; indices[off++] = insideIndicesMap[_i8] + 1 + outsidePointCount; indices[off++] = insideIndicesMap[_i8] + outsidePointCount; if (insideIndicesMap[i2] - insideIndicesMap[_i8] === 2) { indices[off++] = insideIndicesMap[_i8] + 2 + outsidePointCount; indices[off++] = insideIndicesMap[_i8] + 1 + outsidePointCount; indices[off++] = outsidePointCount - outsideIndicesMap[i2] - 1; } else if (outsideIndicesMap[i2] - outsideIndicesMap[_i8] === 2) { indices[off++] = insideIndicesMap[i2] + outsidePointCount; indices[off++] = outsidePointCount - 1 - (outsideIndicesMap[_i8] + 1); indices[off++] = outsidePointCount - 1 - (outsideIndicesMap[_i8] + 2); } } var topVertices = opts.bevelSize > 0 ? offsetPolygon(polygonVertices, [], opts.bevelSize, null, true) : polygonVertices; var boundingRect = opts.boundingRect; var res = splitVertices(polygonVertices, null, opts.smoothSide, opts.smoothSideThreshold); return { vertices: res.vertices, rawVertices: vertices, splittedMap: res.splittedMap, indices: indices, topVertices: topVertices, rect: { x: boundingRect.x * scale[0] + translate[0], y: boundingRect.y * scale[1] + translate[1], width: boundingRect.width * scale[0], height: boundingRect.height * scale[1] }, depth: typeof opts.depth === 'function' ? opts.depth(polylineIdx) : opts.depth, holes: [] }; } function removeClosePointsOfPolygon(polygon, epsilon) { var newPolygon = []; for (var k = 0; k < polygon.length; k++) { var points = polygon[k]; var newPoints = []; var len = points.length; var x1 = points[len - 1][0]; var y1 = points[len - 1][1]; var dist = 0; for (var i = 0; i < len; i++) { var x2 = points[i][0]; var y2 = points[i][1]; var dx = x2 - x1; var dy = y2 - y1; dist += Math.sqrt(dx * dx + dy * dy); if (dist > epsilon) { newPoints.push(points[i]); dist = 0; } x1 = x2; y1 = y2; } if (newPoints.length >= 3) { newPolygon.push(newPoints); } } return newPolygon.length > 0 ? newPolygon : null; } function simplifyPolygon(polygon, tolerance) { var newPolygon = []; for (var k = 0; k < polygon.length; k++) { var points = polygon[k]; points = simplify(points, tolerance, true); if (points.length >= 3) { newPolygon.push(points); } } return newPolygon.length > 0 ? newPolygon : null; } /** * * @param {Array} polygons Polygons array that match GeoJSON MultiPolygon geometry. * @param {Object} [opts] * @param {number|Function} [opts.depth] * @param {number} [opts.bevelSize = 0] * @param {number} [opts.bevelSegments = 2] * @param {number} [opts.simplify = 0] * @param {boolean} [opts.smoothSide = 'auto'] * @param {boolean} [opts.smoothSideThreshold = 0.9] // Will not smooth sharp side. * @param {boolean} [opts.smoothBevel = false] * @param {boolean} [opts.excludeBottom = false] * @param {Object} [opts.fitRect] translate and scale will be ignored if fitRect is set * @param {Array} [opts.translate] * @param {Array} [opts.scale] * * @return {Object} {indices, position, uv, normal, boundingRect} */ function extrudePolygon(polygons, opts) { opts = Object.assign({}, opts); var min = [Infinity, Infinity]; var max = [-Infinity, -Infinity]; for (var i = 0; i < polygons.length; i++) { updateBoundingRect(polygons[i][0], min, max); } opts.boundingRect = opts.boundingRect || { x: min[0], y: min[1], width: max[0] - min[0], height: max[1] - min[1] }; normalizeOpts(opts); var preparedData = []; var translate = opts.translate || [0, 0]; var scale = opts.scale || [1, 1]; var boundingRect = opts.boundingRect; var transformdRect = { x: boundingRect.x * scale[0] + translate[0], y: boundingRect.y * scale[1] + translate[1], width: boundingRect.width * scale[0], height: boundingRect.height * scale[1] }; var epsilon = Math.min(boundingRect.width, boundingRect.height) / 1e5; for (var _i9 = 0; _i9 < polygons.length; _i9++) { var newPolygon = removeClosePointsOfPolygon(polygons[_i9], epsilon); if (!newPolygon) { continue; } var simplifyTolerance = opts.simplify / Math.max(scale[0], scale[1]); if (simplifyTolerance > 0) { newPolygon = simplifyPolygon(newPolygon, simplifyTolerance); } if (!newPolygon) { continue; } var _earcut$flatten = earcut$1.flatten(newPolygon), _vertices3 = _earcut$flatten.vertices, holes = _earcut$flatten.holes, dimensions = _earcut$flatten.dimensions; for (var k = 0; k < _vertices3.length;) { _vertices3[k] = _vertices3[k++] * scale[0] + translate[0]; _vertices3[k] = _vertices3[k++] * scale[1] + translate[1]; } convertToClockwise(_vertices3, holes); if (dimensions !== 2) { throw new Error('Only 2D polygon points are supported'); } var topVertices = opts.bevelSize > 0 ? offsetPolygon(_vertices3, holes, opts.bevelSize, null, true) : _vertices3; var indices = triangulate(topVertices, holes, dimensions); var res = splitVertices(_vertices3, holes, opts.smoothSide, opts.smoothSideThreshold); preparedData.push({ indices: indices, vertices: res.vertices, rawVertices: _vertices3, topVertices: topVertices, holes: res.holes, splittedMap: res.splittedMap, rect: transformdRect, depth: typeof opts.depth === 'function' ? opts.depth(_i9) : opts.depth }); } return innerExtrudeTriangulatedPolygon(preparedData, opts); } /** * * @param {Array} polylines Polylines array that match GeoJSON MultiLineString geometry. * @param {Object} [opts] * @param {number} [opts.depth] * @param {number} [opts.bevelSize = 0] * @param {number} [opts.bevelSegments = 2] * @param {number} [opts.simplify = 0] * @param {boolean} [opts.smoothSide = 'auto'] * @param {boolean} [opts.smoothSideThreshold = 0.9] // Will not smooth sharp side. * @param {boolean} [opts.smoothBevel = false] * @param {boolean} [opts.excludeBottom = false] * @param {boolean} [opts.lineWidth = 1] * @param {boolean} [opts.miterLimit = 2] * @param {Object} [opts.fitRect] translate and scale will be ignored if fitRect is set * @param {Array} [opts.translate] * @param {Array} [opts.scale] * @param {Object} [opts.boundingRect] * @return {Object} {indices, position, uv, normal, boundingRect} */ function extrudePolyline(polylines, opts) { opts = Object.assign({}, opts); var min = [Infinity, Infinity]; var max = [-Infinity, -Infinity]; for (var i = 0; i < polylines.length; i++) { updateBoundingRect(polylines[i], min, max); } opts.boundingRect = opts.boundingRect || { x: min[0], y: min[1], width: max[0] - min[0], height: max[1] - min[1] }; normalizeOpts(opts); var scale = opts.scale || [1, 1]; if (opts.lineWidth == null) { opts.lineWidth = 1; } if (opts.miterLimit == null) { opts.miterLimit = 2; } var preparedData = []; // Extrude polyline to polygon for (var _i10 = 0; _i10 < polylines.length; _i10++) { var newPolyline = polylines[_i10]; var simplifyTolerance = opts.simplify / Math.max(scale[0], scale[1]); if (simplifyTolerance > 0) { newPolyline = simplify(newPolyline, simplifyTolerance, true); } preparedData.push(convertPolylineToTriangulatedPolygon(newPolyline, _i10, opts)); } return innerExtrudeTriangulatedPolygon(preparedData, opts); } function updateBoundingRect(points, min, max) { for (var i = 0; i < points.length; i++) { min[0] = Math.min(points[i][0], min[0]); min[1] = Math.min(points[i][1], min[1]); max[0] = Math.max(points[i][0], max[0]); max[1] = Math.max(points[i][1], max[1]); } } /** * * @param {Object} geojson * @param {Object} [opts] * @param {number} opts.depth * @param {number} [opts.bevelSize = 0] * @param {number} [opts.bevelSegments = 2] * @param {number} [opts.simplify = 0] * @param {boolean} [opts.smoothSide = 'auto'] * @param {boolean} [opts.smoothSideThreshold = 0.9] // Will not smooth sharp side. * @param {boolean} [opts.smoothBevel = false] * @param {boolean} [opts.excludeBottom = false] * @param {boolean} [opts.lineWidth = 1] * @param {boolean} [opts.miterLimit = 2] * @param {Object} [opts.fitRect] translate and scale will be ignored if fitRect is set * @param {Array} [opts.translate] * @param {Array} [opts.scale] * @param {Object} [opts.boundingRect] * @return {Object} {polyline: {indices, position, uv, normal}, polygon: {indices, position, uv, normal}} */ // TODO Not merge feature function extrudeGeoJSON(geojson, opts) { opts = Object.assign({}, opts); var polylines = []; var polygons = []; var polylineFeatureIndices = []; var polygonFeatureIndices = []; var min = [Infinity, Infinity]; var max = [-Infinity, -Infinity]; if (geojson.type === 'LineString' || geojson.type === 'MultiLineString' || geojson.type === 'Polygon' || geojson.type === 'MultiPolygon') { geojson = { features: [{ geometry: geojson }] }; } for (var i = 0; i < geojson.features.length; i++) { var feature = geojson.features[i]; var geometry = feature.geometry; if (geometry && geometry.coordinates) { switch (geometry.type) { case 'LineString': polylines.push(geometry.coordinates); polylineFeatureIndices.push(i); updateBoundingRect(geometry.coordinates, min, max); break; case 'MultiLineString': for (var k = 0; k < geometry.coordinates.length; k++) { polylines.push(geometry.coordinates[k]); polylineFeatureIndices.push(i); updateBoundingRect(geometry.coordinates[k], min, max); } break; case 'Polygon': polygons.push(geometry.coordinates); polygonFeatureIndices.push(i); updateBoundingRect(geometry.coordinates[0], min, max); break; case 'MultiPolygon': for (var _k3 = 0; _k3 < geometry.coordinates.length; _k3++) { polygons.push(geometry.coordinates[_k3]); polygonFeatureIndices.push(i); updateBoundingRect(geometry.coordinates[_k3][0], min, max); } break; } } } opts.boundingRect = opts.boundingRect || { x: min[0], y: min[1], width: max[0] - min[0], height: max[1] - min[1] }; var originalDepth = opts.depth; return { polyline: extrudePolyline(polylines, Object.assign(opts, { depth: function depth(idx) { if (typeof originalDepth === 'function') { return originalDepth(geojson.features[polylineFeatureIndices[idx]]); } return originalDepth; } })), polygon: extrudePolygon(polygons, Object.assign(opts, { depth: function depth(idx) { if (typeof originalDepth === 'function') { return originalDepth(geojson.features[polygonFeatureIndices[idx]]); } return originalDepth; } })) }; } exports.extrudeGeoJSON = extrudeGeoJSON; exports.extrudePolygon = extrudePolygon; exports.extrudePolyline = extrudePolyline; exports.flatten = flatten; exports.offsetPolygon = offsetPolygon; exports.triangulate = triangulate; Object.defineProperty(exports, '__esModule', { value: true }); })); //# sourceMappingURL=geometry-extrude.js.map ================================================ FILE: index.d.ts ================================================ type Rect = { x?: number, y?: number, width?: number, height?: number } type BasicExtrudeOpt = { bevelSize?: number, bevelSegments?: number, simplify?: number, smoothSide?: boolean | 'auto', smoothSideThreshold?: number, smoothBevel?: boolean, excludeBottom?: boolean, fitRect?: Rect, translate?: ArrayLike, scale?: ArrayLike } type ExtrudeResult = { indices: Uint16Array|Uint32Array, position: Float32Array, normal: Float32Array, uv: Float32Array, boundingRect: Rect } type Polygon = ArrayLike>>; type Polyline = ArrayLike>; type GeoJSONPolygonGeometry = { type: 'Polygon', coordinates: Polygon } type GeoJSONLineStringGeometry = { type: 'LineString', coordinates: Polyline } type GeoJSONMultiPolygonGeometry = { type: 'MultiPolygon', coordinates: Array } type GeoJSONMultiLineStringGeometry = { type: 'MultiLineString', coordinates: Array } type GeoJSONFeature = { geometry: GeoJSONPolygonGeometry | GeoJSONLineStringGeometry | GeoJSONMultiPolygonGeometry | GeoJSONMultiLineStringGeometry, properties: Object } type GeoJSON = { features: Array } interface GeometryExtrudeStatic { extrudePolygon(polygons: ArrayLike, opts: BasicExtrudeOpt & { depth: ((idx: number) => number) | number }): ExtrudeResult extrudePolyline(polylines: ArrayLike, opts: BasicExtrudeOpt & { depth: ((idx: number) => number) | number lineWidth?: number miterLimit?: number }): ExtrudeResult extrudeGeoJSON( geojson: GeoJSON | GeoJSONPolygonGeometry | GeoJSONLineStringGeometry | GeoJSONMultiLineStringGeometry | GeoJSONMultiPolygonGeometry, opts: BasicExtrudeOpt & { depth: ((feature: GeoJSONFeature) => number) | number lineWidth?: number miterLimit?: number } ): {polygon: ExtrudeResult, polyline: ExtrudeResult} } declare const exports: GeometryExtrudeStatic; export = exports; export as namespace geometryExtrude; ================================================ FILE: package.json ================================================ { "name": "geometry-extrude", "version": "0.2.1", "main": "dist/geometry-extrude.js", "scripts": { "dev": "rollup -c -w", "build": "rollup -c && uglifyjs -c -m -- dist/geometry-extrude.js > dist/geometry-extrude.min.js" }, "types": "index.d.ts", "repository": "https://github.com/pissang/geometry-extrude", "license": "MIT", "dependencies": { "earcut": "^2.1.3" }, "devDependencies": { "@babel/core": "^7.15.8", "@babel/preset-env": "^7.15.8", "@rollup/plugin-babel": "^5.3.0", "@rollup/plugin-commonjs": "^21.0.1", "@rollup/plugin-node-resolve": "^13.0.6", "rollup": "^2.58.0", "uglify-js": "3.3.28" } } ================================================ FILE: rollup.config.js ================================================ import nodeResolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import babel from '@rollup/plugin-babel'; export default { input: __dirname + '/src/main.js', plugins: [ nodeResolve(), commonjs(), babel({ exclude: ['node_modules/**'] }) ], // sourceMap: true, output: [ { format: 'umd', name: 'geometryExtrude', sourcemap: true, file: 'dist/geometry-extrude.js' } ] }; ================================================ FILE: src/main.js ================================================ // TODO fitRect x, y are negative? // TODO Extrude dimensions // TODO bevel="top"|"bottom" // TODO Not add top and bottom vertices if area is 0 import earcut from 'earcut'; import doSimplify from './simplify'; import { slerp, v2Normalize, v2Dot, v2Add, area, v3Normalize, v3Sub, v3Cross, lineIntersection } from './math'; export function triangulate(vertices, holes, dimensions=2) { return earcut(vertices, holes, dimensions); }; export function flatten(data) { return earcut.flatten(data); } const v1 = []; const v2 = []; const v = []; function innerOffsetPolygon( vertices, out, start, end, outStart, offset, miterLimit, close, removeIntersections, // offsetLines ) { const checkMiterLimit = miterLimit != null; let cursor = outStart; let indicesMap = null; if (checkMiterLimit) { indicesMap = new Uint32Array(end - start); } let prevOffsetX; let prevOffsetY; let prevCursor; let tmpIntersection = []; for (let i = start; i < end; i++) { const nextIdx = i === end - 1 ? start : i + 1; const prevIdx = i === start ? end - 1 : i - 1; const x1 = vertices[prevIdx * 2]; const y1 = vertices[prevIdx * 2 + 1]; const x2 = vertices[i * 2]; const y2 = vertices[i * 2 + 1]; const x3 = vertices[nextIdx * 2]; const y3 = vertices[nextIdx * 2 + 1]; v1[0] = x2 - x1; v1[1] = y2 - y1; v2[0] = x3 - x2; v2[1] = y3 - y2; v2Normalize(v1, v1); v2Normalize(v2, v2); checkMiterLimit && (indicesMap[i] = cursor); let needCheckIntersection = false; let offsetX; let offsetY; if (!close && i === start) { v[0] = v2[1]; v[1] = -v2[0]; v2Normalize(v, v); prevOffsetX = out[cursor * 2] = x2 + v[0] * offset; prevOffsetY = out[cursor * 2 + 1] = y2 + v[1] * offset; prevCursor = cursor; // offsetLines && offsetLines.push([x2, y2, prevOffsetX, prevOffsetY, cursor]) cursor++; } else if (!close && i === end - 1) { v[0] = v1[1]; v[1] = -v1[0]; v2Normalize(v, v); offsetX = x2 + v[0] * offset; offsetY = y2 + v[1] * offset; needCheckIntersection = true; } else { // PENDING Why using sub will lost the direction info. v2Add(v, v2, v1); const tmp = v[1]; v[1] = -v[0]; v[0] = tmp; v2Normalize(v, v); const cosA = v2Dot(v, v2); const sinA = Math.sqrt(1 - cosA * cosA); // PENDING // Make sure it's offset lines instead of vertices. const miter = offset * Math.min(10, 1 / sinA); const isCovex = offset * cosA < 0; if (checkMiterLimit && (1 / sinA) > miterLimit && isCovex) { // No need to check line intersection on the outline. const mx = x2 + v[0] * offset; const my = y2 + v[1] * offset; const halfA = Math.acos(sinA) / 2; const dist = Math.tan(halfA) * Math.abs(offset); out[cursor * 2] = mx + v[1] * dist; out[cursor * 2 + 1] = my - v[0] * dist; cursor++; out[cursor * 2] = mx - v[1] * dist; out[cursor * 2 + 1] = my + v[0] * dist; cursor++; } else { offsetX = x2 + v[0] * miter; offsetY = y2 + v[1] * miter; needCheckIntersection = true; } if (needCheckIntersection) { // TODO Handle with whole. if (removeIntersections && prevOffsetX != null) { // Greedy, only check with previous offset line // PENDING: Is it necessary to check with other lines? const t = lineIntersection( x1, y1, prevOffsetX, prevOffsetY, x2, y2, offsetX, offsetY, tmpIntersection, 0 ); // Use a eplison if (t >= -1e-2 && t <= 1 + 1e-2) { // Update previous offset points. out[prevCursor * 2] = offsetX = tmpIntersection[0]; out[prevCursor * 2 + 1] = offsetY = tmpIntersection[1]; } } prevOffsetX = out[cursor * 2] = offsetX; prevOffsetY = out[cursor * 2 + 1] = offsetY; prevCursor = cursor; // offsetLines && offsetLines.push([x2, y2, offsetX, offsetY, cursor]) cursor++; } } } return indicesMap; } export function offsetPolygon(vertices, holes, offset, miterLimit, close) { const offsetVertices = miterLimit != null ? [] : new Float32Array(vertices.length); const exteriorSize = (holes && holes.length) ? holes[0] : vertices.length / 2; const offsetLines = []; innerOffsetPolygon( vertices, offsetVertices, 0, exteriorSize, 0, offset, miterLimit, close, true ); if (holes) { for (let i = 0; i < holes.length; i++) { const start = holes[i]; const end = holes[i + 1] || vertices.length / 2; innerOffsetPolygon( vertices, offsetVertices, start, end, miterLimit != null ? offsetVertices.length / 2 : start, offset, miterLimit, close, false ); } } // TODO holes // Remove intersections of offseted polygon // let len = offsetLines.length; // let tmpIntersection = []; // for (let i = 0; i < len; i++) { // const line1 = offsetLines[i]; // for (let k = i + 1; k < len; k++) { // const line2 = offsetLines[k]; // const t = lineIntersection( // line1[0], line1[1], line1[2], line1[3], // line2[0], line2[1], line2[2], line2[3], tmpIntersection, 0 // ); // // Use a eplison // if (t >= -1e-2 && t <= 1 + 1e-2) { // const cursor1 = line1[4] * 2; // const cursor2 = line2[4] * 2; // // Update // offsetVertices[cursor1] = offsetVertices[cursor2] = line1[2] = line2[2] = tmpIntersection[0]; // offsetVertices[cursor1 + 1] = offsetVertices[cursor2 + 1] = line1[3] = line2[3]= tmpIntersection[1]; // } // } // } return offsetVertices; } function reversePoints(points, stride, start, end) { for (let i = 0; i < Math.floor((end - start) / 2); i++) { for (let j = 0; j < stride; j++) { const a = (i + start) * stride + j; const b = (end - i - 1) * stride + j; const tmp = points[a]; points[a] = points[b]; points[b] = tmp; } } return points; } function convertToClockwise(vertices, holes) { let polygonVertexCount = vertices.length / 2; let start = 0; let end = holes && holes.length ? holes[0] : polygonVertexCount; if (area(vertices, start, end) > 0) { reversePoints(vertices, 2, start, end); } for (let h = 1; h < (holes ? holes.length : 0) + 1; h++) { start = holes[h - 1]; end = holes[h] || polygonVertexCount; if (area(vertices, start, end) < 0) { reversePoints(vertices, 2, start, end); } } } function normalizeOpts(opts) { opts.depth = opts.depth || 1; opts.bevelSize = opts.bevelSize || 0; opts.bevelSegments = opts.bevelSegments == null ? 2 : opts.bevelSegments; opts.smoothBevel = opts.smoothBevel || false; opts.simplify = opts.simplify || 0; if (opts.smoothSide == null) { opts.smoothSide = 'auto' } if (opts.smoothSideThreshold == null) { opts.smoothSideThreshold = 0.9 } // Normalize bevel options. if (typeof opts.depth === 'number') { opts.bevelSize = Math.min(!(opts.bevelSegments > 0) ? 0 : opts.bevelSize, opts.depth / 2); } if (!(opts.bevelSize > 0)) { opts.bevelSegments = 0; } opts.bevelSegments = Math.round(opts.bevelSegments); const boundingRect = opts.boundingRect; opts.translate = opts.translate || [0, 0]; opts.scale = opts.scale || [1, 1]; if (opts.fitRect) { let targetX = opts.fitRect.x == null ? (boundingRect.x || 0) : opts.fitRect.x; let targetY = opts.fitRect.y == null ? (boundingRect.y || 0) : opts.fitRect.y; let targetWidth = opts.fitRect.width; let targetHeight = opts.fitRect.height; if (targetWidth == null) { if (targetHeight != null) { targetWidth = targetHeight / boundingRect.height * boundingRect.width; } else { targetWidth = boundingRect.width; targetHeight = boundingRect.height; } } else if (targetHeight == null) { targetHeight = targetWidth / boundingRect.width * boundingRect.height; } opts.scale = [ targetWidth / boundingRect.width, targetHeight / boundingRect.height ]; opts.translate = [ (targetX - boundingRect.x) * opts.scale[0], (targetY - boundingRect.y) * opts.scale[1] ]; } } function generateNormal(indices, position) { function v3Set(p, a, b, c) { p[0] = a; p[1] = b; p[2] = c; } const p1 = []; const p2 = []; const p3 = []; const v21 = []; const v32 = []; const n = []; const len = indices.length; const normals = new Float32Array(position.length); for (let f = 0; f < len;) { const i1 = indices[f++] * 3; const i2 = indices[f++] * 3; const i3 = indices[f++] * 3; v3Set(p1, position[i1], position[i1 + 1], position[i1 + 2]); v3Set(p2, position[i2], position[i2 + 1], position[i2 + 2]); v3Set(p3, position[i3], position[i3 + 1], position[i3 + 2]); v3Sub(v21, p1, p2); v3Sub(v32, p2, p3); v3Cross(n, v21, v32); // Already be weighted by the triangle area for (let i = 0; i < 3; i++) { normals[i1 + i] = normals[i1 + i] + n[i]; normals[i2 + i] = normals[i2 + i] + n[i]; normals[i3 + i] = normals[i3 + i] + n[i]; } } for (var i = 0; i < normals.length;) { v3Set(n, normals[i], normals[i+1], normals[i+2]); v3Normalize(n, n); normals[i++] = n[0]; normals[i++] = n[1]; normals[i++] = n[2]; } return normals; } // 0,0----1,0 // 0,1----1,1 const quadToTriangle = [ [0, 0], [1, 0], [1, 1], [0, 0], [1, 1], [0, 1] ]; // Add side vertices and indices. Include bevel. function addExtrudeSide( out, {vertices, topVertices, splittedMap, depth, rect}, start, end, cursors, opts ) { const ringVertexCount = end - start; const splitBevel = opts.smoothBevel ? 1 : 2; const bevelSize = Math.min(depth / 2, opts.bevelSize); const bevelSegments = opts.bevelSegments; const vertexOffset = cursors.vertex; const size = Math.max(rect.width, rect.height, depth); const isDuplicateVertex = splittedMap ? (idx) => { const nextIdx = (idx + 1) % ringVertexCount; return splittedMap[idx + start] === splittedMap[nextIdx + start]; } : (idx) => false; // Side vertices if (bevelSize > 0) { const v0 = [0, 0, 1]; const v1 = []; const v2 = [0, 0, -1]; const v = []; let ringCount = 0; let vLen = new Float32Array(ringVertexCount); for (let k = 0; k < 2; k++) { const z = (k === 0 ? (depth - bevelSize) : bevelSize); for (let s = 0; s <= bevelSegments * splitBevel; s++) { let uLen = 0; let prevX; let prevY; for (let i = 0; i < ringVertexCount; i++) { const idx = (i % ringVertexCount + start) * 2; const rawIdx = splittedMap ? splittedMap[idx / 2] * 2 : idx; v1[0] = vertices[idx] - topVertices[rawIdx]; v1[1] = vertices[idx + 1] - topVertices[rawIdx + 1]; v1[2] = 0; const l = Math.sqrt(v1[0] * v1[0] + v1[1] * v1[1]); v1[0] /= l; v1[1] /= l; const t = (Math.floor(s / splitBevel) + (s % splitBevel)) / bevelSegments; k === 0 ? slerp(v, v0, v1, t) : slerp(v, v1, v2, t); const t2 = k === 0 ? t : 1 - t; const a = bevelSize * Math.sin(t2 * Math.PI / 2); const b = l * Math.cos(t2 * Math.PI / 2); // ellipse radius const r = bevelSize * l / Math.sqrt(a * a + b * b); const x = v[0] * r + topVertices[rawIdx]; const y = v[1] * r + topVertices[rawIdx + 1]; const zz = v[2] * r + z; out.position[cursors.vertex * 3] = x; out.position[cursors.vertex * 3 + 1] = y; out.position[cursors.vertex * 3 + 2] = zz; // TODO Cache and optimize if (i > 0) { uLen += Math.sqrt((prevX - x) * (prevX - x) + (prevY - y) * (prevY - y)); } if (s > 0 || k > 0) { let tmp = (cursors.vertex - ringVertexCount) * 3; let prevX2 = out.position[tmp]; let prevY2 = out.position[tmp + 1]; let prevZ2 = out.position[tmp + 2]; vLen[i] += Math.sqrt( (prevX2 - x) * (prevX2 - x) + (prevY2 - y) * (prevY2 - y) + (prevZ2 - zz) * (prevZ2 - zz) ); } out.uv[cursors.vertex * 2] = uLen / size; out.uv[cursors.vertex * 2 + 1] = vLen[i] / size; prevX = x; prevY = y; cursors.vertex++; // Just ignore this face if vertex are duplicted in `splitVertices` if (isDuplicateVertex(i)) { continue; } if ((splitBevel > 1 && (s % splitBevel)) || (splitBevel === 1 && s >= 1)) { for (let f = 0; f < 6; f++) { const m = (quadToTriangle[f][0] + i) % ringVertexCount; const n = quadToTriangle[f][1] + ringCount; out.indices[cursors.index++] = (n - 1) * ringVertexCount + m + vertexOffset; } } } ringCount++; } } } else { for (let k = 0; k < 2; k++) { const z = k === 0 ? depth : 0; let uLen = 0; let prevX; let prevY; for (let i = 0; i < ringVertexCount; i++) { const idx = (i + start) * 2; const x = vertices[idx]; const y = vertices[idx + 1]; const vtx3 = cursors.vertex * 3; const vtx2 = cursors.vertex * 2; out.position[vtx3] = x; out.position[vtx3 + 1] = y; out.position[vtx3 + 2] = z; if (i > 0) { uLen += Math.sqrt((prevX - x) * (prevX - x) + (prevY - y) * (prevY - y)); } out.uv[vtx2] = uLen / size; out.uv[vtx2 + 1] = z / size; prevX = x; prevY = y; cursors.vertex++; } } } // Connect the side const sideStartRingN = bevelSize > 0 ? (bevelSegments * splitBevel + 1) : 1; for (let i = 0; i < ringVertexCount; i++) { // Just ignore this face if vertex are duplicted in `splitVertices` if (isDuplicateVertex(i)) { continue; } for (let f = 0; f < 6; f++) { const m = (quadToTriangle[f][0] + i) % ringVertexCount; const n = quadToTriangle[f][1] + sideStartRingN; out.indices[cursors.index++] = (n - 1) * ringVertexCount + m + vertexOffset; } } } function addTopAndBottom({indices, topVertices, rect, depth}, out, cursors, opts) { if (topVertices.length <= 4) { return; } const vertexOffset = cursors.vertex; // Top indices const indicesLen = indices.length; for (let i = 0; i < indicesLen; i++) { out.indices[cursors.index++] = vertexOffset + indices[i]; } const size = Math.max(rect.width, rect.height); // Top and bottom vertices for (let k = 0; k < (opts.excludeBottom ? 1 : 2); k++) { for (let i = 0; i < topVertices.length; i += 2) { const x = topVertices[i]; const y = topVertices[i + 1]; const vtx3 = cursors.vertex * 3; const vtx2 = cursors.vertex * 2; out.position[vtx3] = x; out.position[vtx3 + 1] = y; out.position[vtx3 + 2] = (1 - k) * depth; out.uv[vtx2] = (x - rect.x) / size; out.uv[vtx2 + 1] = (y - rect.y) / size; cursors.vertex++; } } // Bottom indices if (!opts.excludeBottom) { const vertexCount = topVertices.length / 2; for (let i = 0; i < indicesLen; i += 3) { for (let k = 0; k < 3; k++) { out.indices[cursors.index++] = vertexOffset + vertexCount + indices[i + 2 - k]; } } } } /** * Split vertices for sharp side. */ function splitVertices(vertices, holes, smoothSide, smoothSideThreshold) { const isAutoSmooth = smoothSide == null || smoothSide === 'auto'; if (smoothSide === true) { return {vertices, holes}; } const newVertices = []; const newHoles = holes && []; const count = vertices.length / 2; const v1 = []; const v2 = []; // Map of splitted index to raw index const splittedMap = []; let start = 0; let end = 0; const polysCount = (holes ? holes.length : 0) + 1; for (let h = 0; h < polysCount; h++) { if (h === 0) { end = holes && holes.length ? holes[0] : count; } else { start = holes[h - 1]; end = holes[h] || count; } for (let i = start; i < end; i++) { const x2 = vertices[i * 2]; const y2 = vertices[i * 2 + 1]; const nextIdx = i === end - 1 ? start : i + 1; const x3 = vertices[nextIdx * 2]; const y3 = vertices[nextIdx * 2 + 1]; if (isAutoSmooth) { const prevIdx = i === start ? end - 1 : i - 1; const x1 = vertices[prevIdx * 2]; const y1 = vertices[prevIdx * 2 + 1]; v1[0] = x1 - x2; v1[1] = y1 - y2; v2[0] = x3 - x2; v2[1] = y3 - y2; v2Normalize(v1, v1); v2Normalize(v2, v2); const angleCos = v2Dot(v1, v2) * 0.5 + 0.5; if ((1 - angleCos) > smoothSideThreshold) { newVertices.push(x2, y2); splittedMap.push(i); } else { newVertices.push(x2, y2, x2, y2); splittedMap.push(i, i); } } else { newVertices.push(x2, y2, x2, y2); splittedMap.push(i, i); } } if (h < polysCount - 1 && newHoles) { newHoles.push(newVertices.length / 2); } } return { vertices: new Float32Array(newVertices), splittedMap, holes: newHoles }; } function innerExtrudeTriangulatedPolygon(preparedData, opts) { let indexCount = 0; let vertexCount = 0; for (let p = 0; p < preparedData.length; p++) { let {indices, vertices, splittedMap, topVertices, holes, depth} = preparedData[p]; const bevelSize = Math.min(depth / 2, opts.bevelSize); const bevelSegments = !(bevelSize > 0) ? 0 : opts.bevelSegments; holes = holes || []; indexCount += indices.length * (opts.excludeBottom ? 1 : 2); vertexCount += topVertices.length / 2 * (opts.excludeBottom ? 1 : 2); const ringCount = 2 + bevelSegments * 2; let start = 0; let end = 0; for (let h = 0; h < holes.length + 1; h++) { if (h === 0) { end = holes.length ? holes[0] : vertices.length / 2; } else { start = holes[h - 1]; end = holes[h] || vertices.length / 2; } const faceEnd = splittedMap ? splittedMap[end - 1] + 1 : end; const faceStart = splittedMap ? splittedMap[start] : start; indexCount += (faceEnd - faceStart) * 6 * (ringCount - 1); const sideRingVertexCount = end - start; vertexCount += sideRingVertexCount * ringCount // Double the bevel vertex number if not smooth + (!opts.smoothBevel ? bevelSegments * sideRingVertexCount * 2 : 0); } } const data = { position: new Float32Array(vertexCount * 3), indices: new (vertexCount > 0xffff ? Uint32Array : Uint16Array)(indexCount), uv: new Float32Array(vertexCount * 2) }; const cursors = { vertex: 0, index: 0 }; for (let d = 0; d < preparedData.length; d++) { addTopAndBottom(preparedData[d], data, cursors, opts); } for (let d = 0; d < preparedData.length; d++) { const {holes, vertices} = preparedData[d]; const vertexCount = vertices.length / 2; let start = 0; let end = (holes && holes.length) ? holes[0] : vertexCount; // Add exterior addExtrudeSide(data, preparedData[d], start, end, cursors, opts); // Add holes if (holes) { for (let h = 0; h < holes.length; h++) { start = holes[h]; end = holes[h + 1] || vertexCount; addExtrudeSide(data, preparedData[d], start, end, cursors, opts); } } } // Wrap uv for (let i = 0; i < data.uv.length; i++) { const val = data.uv[i]; if (val > 0 && Math.round(val) === val) { data.uv[i] = 1; } else { data.uv[i] = val % 1; } } data.normal = generateNormal(data.indices, data.position); // PENDING data.boundingRect = preparedData[0] && preparedData[0].rect; return data; } function convertPolylineToTriangulatedPolygon(polyline, polylineIdx, opts) { const lineWidth = opts.lineWidth; const pointCount = polyline.length; const points = new Float32Array(pointCount * 2); const translate = opts.translate || [0, 0]; const scale = opts.scale || [1, 1]; for (let i = 0, k = 0; i < pointCount; i++) { points[k++] = polyline[i][0] * scale[0] + translate[0]; points[k++] = polyline[i][1] * scale[1] + translate[1]; } if (area(points, 0, pointCount) < 0) { reversePoints(points, 2, 0, pointCount); } const insidePoints = []; const outsidePoints = []; const miterLimit = opts.miterLimit; const outsideIndicesMap = innerOffsetPolygon( points, outsidePoints, 0, pointCount, 0, -lineWidth / 2, miterLimit, false, true ); reversePoints(points, 2, 0, pointCount); const insideIndicesMap = innerOffsetPolygon( points, insidePoints, 0, pointCount, 0, -lineWidth / 2, miterLimit, false, true ); const polygonVertexCount = (insidePoints.length + outsidePoints.length) / 2; const polygonVertices = new Float32Array(polygonVertexCount * 2); let offset = 0; const outsidePointCount = outsidePoints.length / 2; for (let i = 0; i < outsidePoints.length; i++) { polygonVertices[offset++] = outsidePoints[i]; } for (let i = 0; i < insidePoints.length; i++) { polygonVertices[offset++] = insidePoints[i]; } // Built indices const indices = new (polygonVertexCount > 0xffff ? Uint32Array : Uint16Array)( ((pointCount - 1) * 2 + (polygonVertexCount - pointCount * 2)) * 3 ); let off = 0; for (let i = 0; i < pointCount - 1; i++) { const i2 = i + 1; indices[off++] = outsidePointCount - 1 - outsideIndicesMap[i]; indices[off++] = outsidePointCount - 1 - outsideIndicesMap[i] - 1; indices[off++] = insideIndicesMap[i] + 1 + outsidePointCount; indices[off++] = outsidePointCount - 1 - outsideIndicesMap[i]; indices[off++] = insideIndicesMap[i] + 1 + outsidePointCount; indices[off++] = insideIndicesMap[i] + outsidePointCount; if (insideIndicesMap[i2] - insideIndicesMap[i] === 2) { indices[off++] = insideIndicesMap[i] + 2 + outsidePointCount; indices[off++] = insideIndicesMap[i] + 1 + outsidePointCount; indices[off++] = outsidePointCount - outsideIndicesMap[i2] - 1; } else if (outsideIndicesMap[i2] - outsideIndicesMap[i] === 2) { indices[off++] = insideIndicesMap[i2] + outsidePointCount; indices[off++] = outsidePointCount - 1 - (outsideIndicesMap[i] + 1); indices[off++] = outsidePointCount - 1 - (outsideIndicesMap[i] + 2); } } const topVertices = opts.bevelSize > 0 ? offsetPolygon(polygonVertices, [], opts.bevelSize, null, true) : polygonVertices; const boundingRect = opts.boundingRect; const res = splitVertices(polygonVertices, null, opts.smoothSide, opts.smoothSideThreshold); return { vertices: res.vertices, rawVertices: vertices, splittedMap: res.splittedMap, indices, topVertices, rect: { x: boundingRect.x * scale[0] + translate[0], y: boundingRect.y * scale[1] + translate[1], width: boundingRect.width * scale[0], height: boundingRect.height * scale[1], }, depth: typeof opts.depth === 'function' ? opts.depth(polylineIdx) : opts.depth, holes: [] }; } function removeClosePointsOfPolygon(polygon, epsilon) { const newPolygon = []; for (let k = 0; k < polygon.length; k++) { const points = polygon[k]; const newPoints = []; const len = points.length; let x1 = points[len - 1][0]; let y1 = points[len - 1][1]; let dist = 0; for (let i = 0; i < len; i++) { let x2 = points[i][0]; let y2 = points[i][1]; const dx = x2 - x1; const dy = y2 - y1; dist += Math.sqrt(dx * dx + dy * dy); if (dist > epsilon) { newPoints.push(points[i]); dist = 0; } x1 = x2; y1 = y2; } if (newPoints.length >= 3) { newPolygon.push(newPoints); } } return newPolygon.length > 0 ? newPolygon : null; } function simplifyPolygon(polygon, tolerance) { const newPolygon = []; for (let k = 0; k < polygon.length; k++) { let points = polygon[k]; points = doSimplify(points, tolerance, true); if (points.length >= 3) { newPolygon.push(points); } } return newPolygon.length > 0 ? newPolygon : null; } /** * * @param {Array} polygons Polygons array that match GeoJSON MultiPolygon geometry. * @param {Object} [opts] * @param {number|Function} [opts.depth] * @param {number} [opts.bevelSize = 0] * @param {number} [opts.bevelSegments = 2] * @param {number} [opts.simplify = 0] * @param {boolean} [opts.smoothSide = 'auto'] * @param {boolean} [opts.smoothSideThreshold = 0.9] // Will not smooth sharp side. * @param {boolean} [opts.smoothBevel = false] * @param {boolean} [opts.excludeBottom = false] * @param {Object} [opts.fitRect] translate and scale will be ignored if fitRect is set * @param {Array} [opts.translate] * @param {Array} [opts.scale] * * @return {Object} {indices, position, uv, normal, boundingRect} */ export function extrudePolygon(polygons, opts) { opts = Object.assign({}, opts); const min = [Infinity, Infinity]; const max = [-Infinity, -Infinity]; for (let i = 0; i < polygons.length; i++) { updateBoundingRect(polygons[i][0], min, max); } opts.boundingRect = opts.boundingRect || { x: min[0], y: min[1], width: max[0] - min[0], height: max[1] - min[1] }; normalizeOpts(opts); const preparedData = []; const translate = opts.translate || [0, 0]; const scale = opts.scale || [1, 1]; const boundingRect = opts.boundingRect; const transformdRect = { x: boundingRect.x * scale[0] + translate[0], y: boundingRect.y * scale[1] + translate[1], width: boundingRect.width * scale[0], height: boundingRect.height * scale[1], }; const epsilon = Math.min( boundingRect.width, boundingRect.height ) / 1e5; for (let i = 0; i < polygons.length; i++) { let newPolygon = removeClosePointsOfPolygon(polygons[i], epsilon); if (!newPolygon) { continue; } const simplifyTolerance = opts.simplify / Math.max(scale[0], scale[1]); if (simplifyTolerance > 0) { newPolygon = simplifyPolygon(newPolygon, simplifyTolerance); } if (!newPolygon) { continue; } const {vertices, holes, dimensions} = earcut.flatten(newPolygon); for (let k = 0; k < vertices.length;) { vertices[k] = vertices[k++] * scale[0] + translate[0]; vertices[k] = vertices[k++] * scale[1] + translate[1]; } convertToClockwise(vertices, holes); if (dimensions !== 2) { throw new Error('Only 2D polygon points are supported'); } const topVertices = opts.bevelSize > 0 ? offsetPolygon(vertices, holes, opts.bevelSize, null, true) : vertices; const indices = triangulate(topVertices, holes, dimensions); const res = splitVertices(vertices, holes, opts.smoothSide, opts.smoothSideThreshold) preparedData.push({ indices, vertices: res.vertices, rawVertices: vertices, topVertices, holes: res.holes, splittedMap: res.splittedMap, rect: transformdRect, depth: typeof opts.depth === 'function' ? opts.depth(i) : opts.depth }); } return innerExtrudeTriangulatedPolygon(preparedData, opts); }; /** * * @param {Array} polylines Polylines array that match GeoJSON MultiLineString geometry. * @param {Object} [opts] * @param {number} [opts.depth] * @param {number} [opts.bevelSize = 0] * @param {number} [opts.bevelSegments = 2] * @param {number} [opts.simplify = 0] * @param {boolean} [opts.smoothSide = 'auto'] * @param {boolean} [opts.smoothSideThreshold = 0.9] // Will not smooth sharp side. * @param {boolean} [opts.smoothBevel = false] * @param {boolean} [opts.excludeBottom = false] * @param {boolean} [opts.lineWidth = 1] * @param {boolean} [opts.miterLimit = 2] * @param {Object} [opts.fitRect] translate and scale will be ignored if fitRect is set * @param {Array} [opts.translate] * @param {Array} [opts.scale] * @param {Object} [opts.boundingRect] * @return {Object} {indices, position, uv, normal, boundingRect} */ export function extrudePolyline(polylines, opts) { opts = Object.assign({}, opts); const min = [Infinity, Infinity]; const max = [-Infinity, -Infinity]; for (let i = 0; i < polylines.length; i++) { updateBoundingRect(polylines[i], min, max); } opts.boundingRect = opts.boundingRect || { x: min[0], y: min[1], width: max[0] - min[0], height: max[1] - min[1] }; normalizeOpts(opts); const scale = opts.scale || [1, 1]; if (opts.lineWidth == null) { opts.lineWidth = 1; } if (opts.miterLimit == null) { opts.miterLimit = 2; } const preparedData = []; // Extrude polyline to polygon for (let i = 0; i < polylines.length; i++) { let newPolyline = polylines[i]; const simplifyTolerance = opts.simplify / Math.max(scale[0], scale[1]); if (simplifyTolerance > 0) { newPolyline = doSimplify(newPolyline, simplifyTolerance, true); } preparedData.push(convertPolylineToTriangulatedPolygon(newPolyline, i, opts)); } return innerExtrudeTriangulatedPolygon(preparedData, opts); } function updateBoundingRect(points, min, max) { for (let i = 0; i < points.length; i++) { min[0] = Math.min(points[i][0], min[0]); min[1] = Math.min(points[i][1], min[1]); max[0] = Math.max(points[i][0], max[0]); max[1] = Math.max(points[i][1], max[1]); } } /** * * @param {Object} geojson * @param {Object} [opts] * @param {number} opts.depth * @param {number} [opts.bevelSize = 0] * @param {number} [opts.bevelSegments = 2] * @param {number} [opts.simplify = 0] * @param {boolean} [opts.smoothSide = 'auto'] * @param {boolean} [opts.smoothSideThreshold = 0.9] // Will not smooth sharp side. * @param {boolean} [opts.smoothBevel = false] * @param {boolean} [opts.excludeBottom = false] * @param {boolean} [opts.lineWidth = 1] * @param {boolean} [opts.miterLimit = 2] * @param {Object} [opts.fitRect] translate and scale will be ignored if fitRect is set * @param {Array} [opts.translate] * @param {Array} [opts.scale] * @param {Object} [opts.boundingRect] * @return {Object} {polyline: {indices, position, uv, normal}, polygon: {indices, position, uv, normal}} */ // TODO Not merge feature export function extrudeGeoJSON(geojson, opts) { opts = Object.assign({}, opts); const polylines = []; const polygons = []; const polylineFeatureIndices = []; const polygonFeatureIndices = []; const min = [Infinity, Infinity]; const max = [-Infinity, -Infinity]; if (geojson.type === 'LineString' || geojson.type === 'MultiLineString' || geojson.type === 'Polygon' || geojson.type === 'MultiPolygon') { geojson = { features: [{ geometry: geojson }] } } for (let i = 0; i < geojson.features.length; i++) { const feature = geojson.features[i]; const geometry = feature.geometry; if (geometry && geometry.coordinates) { switch (geometry.type) { case 'LineString': polylines.push(geometry.coordinates); polylineFeatureIndices.push(i); updateBoundingRect(geometry.coordinates, min, max); break; case 'MultiLineString': for (let k = 0; k < geometry.coordinates.length; k++) { polylines.push(geometry.coordinates[k]); polylineFeatureIndices.push(i); updateBoundingRect(geometry.coordinates[k], min, max); } break; case 'Polygon': polygons.push(geometry.coordinates); polygonFeatureIndices.push(i); updateBoundingRect(geometry.coordinates[0], min, max); break; case 'MultiPolygon': for (let k = 0; k < geometry.coordinates.length; k++) { polygons.push(geometry.coordinates[k]); polygonFeatureIndices.push(i); updateBoundingRect(geometry.coordinates[k][0], min, max); } break; } } } opts.boundingRect = opts.boundingRect || { x: min[0], y: min[1], width: max[0] - min[0], height: max[1] - min[1] }; const originalDepth = opts.depth; return { polyline: extrudePolyline(polylines, Object.assign(opts, { depth: function (idx) { if (typeof originalDepth === 'function') { return originalDepth( geojson.features[polylineFeatureIndices[idx]] ); } return originalDepth; } })), polygon: extrudePolygon(polygons, Object.assign(opts, { depth: function (idx) { if (typeof originalDepth === 'function') { return originalDepth( geojson.features[polygonFeatureIndices[idx]] ); } return originalDepth; } })) }; } ================================================ FILE: src/math.js ================================================ export function dot(v1, v2) { return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; } export function v2Dot(v1, v2) { return v1[0] * v2[0] + v1[1] * v2[1]; } export function normalize(out, v) { const x = v[0]; const y = v[1]; const z = v[2]; const d = Math.sqrt(x * x + y * y + z * z); out[0] = x / d; out[1] = y / d; out[2] = z / d; return out; } export function v2Normalize(out, v) { const x = v[0]; const y = v[1]; const d = Math.sqrt(x * x + y * y); out[0] = x / d; out[1] = y / d; return out; } export function scale(out, v, s) { out[0] = v[0] * s; out[1] = v[1] * s; out[2] = v[2] * s; return out; } export function mul(out, v1, v2) { out[0] = v1[0] * v2[0]; out[1] = v1[1] * v2[1]; out[2] = v1[2] * v2[2]; return out; } export function scaleAndAdd(out, v1, v2, s) { out[0] = v1[0] + v2[0] * s; out[1] = v1[1] + v2[1] * s; out[2] = v1[2] + v2[2] * s; return out; } export function add(out, v1, v2) { out[0] = v1[0] + v2[0]; out[1] = v1[1] + v2[1]; out[2] = v1[2] + v2[2]; return out; } export function v2Add(out, v1, v2) { out[0] = v1[0] + v2[0]; out[1] = v1[1] + v2[1]; return out; } export function sub(out, v1, v2) { out[0] = v1[0] - v2[0]; out[1] = v1[1] - v2[1]; out[2] = v1[2] - v2[2]; return out; } export function v2Sub(out, v1, v2) { out[0] = v1[0] - v2[0]; out[1] = v1[1] - v2[1]; return out; } export function v3Sub(out, v1, v2) { out[0] = v1[0] - v2[0]; out[1] = v1[1] - v2[1]; out[2] = v1[2] - v2[2]; return out; } export function v3Normalize(out, v) { const x = v[0]; const y = v[1]; const z = v[2]; const d = Math.sqrt(x * x + y * y + z * z); out[0] = x / d; out[1] = y / d; out[2] = z / d; return out; } export function v3Cross(out, v1, v2) { var ax = v1[0], ay = v1[1], az = v1[2], bx = v2[0], by = v2[1], bz = v2[2]; out[0] = ay * bz - az * by; out[1] = az * bx - ax * bz; out[2] = ax * by - ay * bx; return out; } const rel = []; // start and end must be normalized export function slerp(out, start, end, t) { // https://keithmaggio.wordpress.com/2011/02/15/math-magician-lerp-slerp-and-nlerp/ const cosT = dot(start, end); const theta = Math.acos(cosT) * t; scaleAndAdd(rel, end, start, -cosT); normalize(rel, rel);// start and rel Orthonormal basis scale(out, start, Math.cos(theta)); scaleAndAdd(out, out, rel, Math.sin(theta)); return out; } export function lineIntersection(x1, y1, x2, y2, x3, y3, x4, y4, out, writeOffset) { const dx1 = x2 - x1; const dx2 = x4 - x3; const dy1 = y2 - y1; const dy2 = y4 - y3; const cross = dy2 * dx1 - dx2 * dy1; const tmp1 = y1 - y3; const tmp2 = x1 - x3; const t1 = (dx2 * tmp1 - dy2 * tmp2) / cross; // const t2 = (dx1 * tmp1 - dy1 * tmp2) / cross; if (out) { writeOffset = writeOffset || 0; out[writeOffset] = x1 + t1 * (x2 - x1); out[writeOffset + 1] = y1 + t1 * (y2 - y1); } return t1; } export function area(points, start, end) { // Signed polygon area const n = end - start; if (n < 3) { return 0; } let area = 0; for (let i = (end - 1) * 2, j = start * 2; j < end * 2;) { const x0 = points[i]; const y0 = points[i + 1]; const x1 = points[j]; const y1 = points[j + 1]; i = j; j += 2; area += x0 * y1 - x1 * y0; } return area; } export function triangleArea(x0, y0, x1, y1, x2, y2) { return (x1 - x0) * (y2 - y1) - (y1 - y0) * (x2 - x1); } ================================================ FILE: src/simplify.js ================================================ /* (c) 2017, Vladimir Agafonkin Simplify.js, a high-performance JS polyline simplification library mourner.github.io/simplify-js */ // to suit your point format, run search/replace for '.x' and '.y'; // for 3D version, see 3d branch (configurability would draw significant performance overhead) // square distance between 2 points function getSqDist(p1, p2) { var dx = p1[0] - p2[0], dy = p1[1] - p2[1]; return dx * dx + dy * dy; } // square distance from a point to a segment function getSqSegDist(p, p1, p2) { var x = p1[0], y = p1[1], dx = p2[0] - x, dy = p2[1] - y; if (dx !== 0 || dy !== 0) { var t = ((p[0] - x) * dx + (p[1] - y) * dy) / (dx * dx + dy * dy); if (t > 1) { x = p2[0]; y = p2[1]; } else if (t > 0) { x += dx * t; y += dy * t; } } dx = p[0] - x; dy = p[1] - y; return dx * dx + dy * dy; } // rest of the code doesn't care about point format // basic distance-based simplification function simplifyRadialDist(points, sqTolerance) { var prevPoint = points[0], newPoints = [prevPoint], point; for (var i = 1, len = points.length; i < len; i++) { point = points[i]; if (getSqDist(point, prevPoint) > sqTolerance) { newPoints.push(point); prevPoint = point; } } if (prevPoint !== point) newPoints.push(point); return newPoints; } function simplifyDPStep(points, first, last, sqTolerance, simplified) { var maxSqDist = sqTolerance, index; for (var i = first + 1; i < last; i++) { var sqDist = getSqSegDist(points[i], points[first], points[last]); if (sqDist > maxSqDist) { index = i; maxSqDist = sqDist; } } if (maxSqDist > sqTolerance) { if (index - first > 1) simplifyDPStep(points, first, index, sqTolerance, simplified); simplified.push(points[index]); if (last - index > 1) simplifyDPStep(points, index, last, sqTolerance, simplified); } } // simplification using Ramer-Douglas-Peucker algorithm function simplifyDouglasPeucker(points, sqTolerance) { var last = points.length - 1; var simplified = [points[0]]; simplifyDPStep(points, 0, last, sqTolerance, simplified); simplified.push(points[last]); return simplified; } // both algorithms combined for awesome performance function simplify(points, tolerance, highestQuality) { if (points.length <= 2) return points; var sqTolerance = tolerance !== undefined ? tolerance * tolerance : 1; points = highestQuality ? points : simplifyRadialDist(points, sqTolerance); points = simplifyDouglasPeucker(points, sqTolerance); return points; } export default simplify; ================================================ FILE: test/asset/buildings-ny.geojson ================================================ { "type": "FeatureCollection", "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, "features": [ { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00942675, 40.70343591 ], [ -74.00930593, 40.70351579 ], [ -74.00937519, 40.70357599 ], [ -74.00890672, 40.70388592 ], [ -74.00867082, 40.70368087 ], [ -74.00853347, 40.70356156 ], [ -74.00812177, 40.70320389 ], [ -74.00819148, 40.70315779 ], [ -74.008209, 40.70317297 ], [ -74.0086109, 40.70290711 ], [ -74.00862959, 40.70292338 ], [ -74.0089033, 40.70274237 ], [ -74.0089298, 40.70276539 ], [ -74.00922849, 40.70256776 ], [ -74.01000401, 40.70324169 ], [ -74.00954937, 40.70354242 ], [ -74.00942675, 40.70343591 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01350187, 40.70067477 ], [ -74.01350843, 40.70071931 ], [ -74.01355101, 40.70100508 ], [ -74.01354481, 40.701052 ], [ -74.01352747, 40.70123676 ], [ -74.01336263, 40.70145258 ], [ -74.01284601, 40.70141158 ], [ -74.01252989, 40.70090728 ], [ -74.0124609, 40.70092342 ], [ -74.01243261, 40.7008532 ], [ -74.01239003, 40.70074792 ], [ -74.0123567, 40.70067716 ], [ -74.01239209, 40.70067062 ], [ -74.01262314, 40.70061852 ], [ -74.0128116, 40.70057459 ], [ -74.01289991, 40.70056056 ], [ -74.01313742, 40.70054299 ], [ -74.01326813, 40.70053196 ], [ -74.01350151, 40.70051568 ], [ -74.013544, 40.70051146 ], [ -74.01355343, 40.70057228 ], [ -74.01356844, 40.70066871 ], [ -74.01350187, 40.70067477 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00942675, 40.70343591 ], [ -74.00930593, 40.70351579 ], [ -74.00937519, 40.70357599 ], [ -74.00890672, 40.70388592 ], [ -74.00867082, 40.70368087 ], [ -74.00853347, 40.70356156 ], [ -74.00812177, 40.70320389 ], [ -74.00819148, 40.70315779 ], [ -74.008209, 40.70317297 ], [ -74.0086109, 40.70290711 ], [ -74.00862959, 40.70292338 ], [ -74.0089033, 40.70274237 ], [ -74.0089298, 40.70276539 ], [ -74.00877377, 40.70286849 ], [ -74.00942675, 40.70343591 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01426319, 40.70367031 ], [ -74.014234, 40.70380161 ], [ -74.01422124, 40.70380011 ], [ -74.01411749, 40.70432047 ], [ -74.01413231, 40.70432217 ], [ -74.01410644, 40.70445251 ], [ -74.01408092, 40.70444959 ], [ -74.01407841, 40.70446218 ], [ -74.013726, 40.70445646 ], [ -74.01339308, 40.70445531 ], [ -74.01339551, 40.70444339 ], [ -74.01336811, 40.70444359 ], [ -74.01334709, 40.70431366 ], [ -74.01336119, 40.70431189 ], [ -74.01327774, 40.7037854 ], [ -74.01325977, 40.70378561 ], [ -74.01324091, 40.70364988 ], [ -74.01355038, 40.70365642 ], [ -74.01354697, 40.70368829 ], [ -74.01395094, 40.70369388 ], [ -74.01395741, 40.70366378 ], [ -74.01426319, 40.70367031 ] ], [ [ -74.01369249, 40.70422097 ], [ -74.01369132, 40.70419911 ], [ -74.01367372, 40.70418549 ], [ -74.01365638, 40.70416929 ], [ -74.01364147, 40.70415178 ], [ -74.01362907, 40.70413319 ], [ -74.01362045, 40.7041163 ], [ -74.01361299, 40.70409621 ], [ -74.01360832, 40.70407558 ], [ -74.01360652, 40.70405481 ], [ -74.01359305, 40.7040559 ], [ -74.01361641, 40.7042205 ], [ -74.01369249, 40.70422097 ] ], [ [ -74.01391995, 40.70405801 ], [ -74.01390009, 40.7040576 ], [ -74.01389884, 40.70406979 ], [ -74.01389443, 40.70409056 ], [ -74.01388725, 40.70411086 ], [ -74.01387512, 40.70413408 ], [ -74.01386191, 40.7041526 ], [ -74.01384637, 40.70416997 ], [ -74.0138285, 40.70418611 ], [ -74.01380847, 40.70420061 ], [ -74.0138073, 40.70423418 ], [ -74.01388779, 40.70423541 ], [ -74.01391995, 40.70405801 ] ], [ [ -74.01364812, 40.70387857 ], [ -74.01364722, 40.70381762 ], [ -74.01354265, 40.70381571 ], [ -74.01356799, 40.70399318 ], [ -74.01359314, 40.70399331 ], [ -74.01359529, 40.70397629 ], [ -74.01360077, 40.7039545 ], [ -74.01360931, 40.70393332 ], [ -74.01361829, 40.7039167 ], [ -74.01363195, 40.70389709 ], [ -74.01364812, 40.70387857 ] ], [ [ -74.01395202, 40.70382688 ], [ -74.0138435, 40.70382048 ], [ -74.013847, 40.70388408 ], [ -74.01385769, 40.7038975 ], [ -74.01387144, 40.7039184 ], [ -74.01388213, 40.70394026 ], [ -74.01388743, 40.70395477 ], [ -74.013893, 40.70397772 ], [ -74.01389542, 40.70400101 ], [ -74.01392048, 40.70400169 ], [ -74.01395202, 40.70382688 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01289739, 40.70490238 ], [ -74.01268018, 40.70492199 ], [ -74.0126341, 40.70462937 ], [ -74.01216293, 40.70467207 ], [ -74.01215494, 40.70462181 ], [ -74.01214802, 40.70457332 ], [ -74.0121146, 40.7043614 ], [ -74.01219024, 40.70435459 ], [ -74.01236559, 40.70433872 ], [ -74.01235113, 40.70424631 ], [ -74.0123425, 40.70419026 ], [ -74.01233541, 40.70410718 ], [ -74.01287071, 40.70411406 ], [ -74.01287512, 40.70414266 ], [ -74.0130784, 40.70412461 ], [ -74.01320111, 40.70491416 ], [ -74.01290395, 40.70494079 ], [ -74.01289739, 40.70490238 ] ] ] } }, { "type": "Feature", "properties": { "height": 195.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01156897, 40.70207436 ], [ -74.01150554, 40.70185609 ], [ -74.01235122, 40.70171471 ], [ -74.01241473, 40.70193311 ], [ -74.01249153, 40.70192017 ], [ -74.01260212, 40.70230039 ], [ -74.01159933, 40.70246799 ], [ -74.01148875, 40.70208777 ], [ -74.01156897, 40.70207436 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01137322, 40.70143249 ], [ -74.01122392, 40.70105336 ], [ -74.01114469, 40.70107127 ], [ -74.01108558, 40.70092138 ], [ -74.01112475, 40.70091259 ], [ -74.01112852, 40.70092226 ], [ -74.0114194, 40.70085641 ], [ -74.0114141, 40.70084278 ], [ -74.01146934, 40.70083032 ], [ -74.01147464, 40.70084367 ], [ -74.01178582, 40.70077332 ], [ -74.01178231, 40.7007644 ], [ -74.01183073, 40.70075336 ], [ -74.01183514, 40.7007644 ], [ -74.01215197, 40.70069268 ], [ -74.01214838, 40.70068342 ], [ -74.01218997, 40.70067396 ], [ -74.01220021, 40.7006999 ], [ -74.01219195, 40.70070181 ], [ -74.01224558, 40.70083822 ], [ -74.01222698, 40.70084278 ], [ -74.01224917, 40.7008989 ], [ -74.01217659, 40.70091538 ], [ -74.01216221, 40.70091872 ], [ -74.01225222, 40.70114727 ], [ -74.01227351, 40.70114251 ], [ -74.01227863, 40.70115552 ], [ -74.01230469, 40.70122158 ], [ -74.01137322, 40.70143249 ] ] ] } }, { "type": "Feature", "properties": { "height": 209.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00942675, 40.70343591 ], [ -74.00877377, 40.70286849 ], [ -74.0089298, 40.70276539 ], [ -74.00922849, 40.70256776 ], [ -74.01000401, 40.70324169 ], [ -74.00954937, 40.70354242 ], [ -74.00942675, 40.70343591 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01289739, 40.70490238 ], [ -74.01289218, 40.70486949 ], [ -74.01275142, 40.70488222 ], [ -74.01271063, 40.70462297 ], [ -74.01270264, 40.70457216 ], [ -74.01215494, 40.70462181 ], [ -74.01214802, 40.70457332 ], [ -74.0121146, 40.7043614 ], [ -74.01219024, 40.70435459 ], [ -74.01236559, 40.70433872 ], [ -74.01235113, 40.70424631 ], [ -74.0123425, 40.70419026 ], [ -74.01287512, 40.70414266 ], [ -74.0130784, 40.70412461 ], [ -74.01320111, 40.70491416 ], [ -74.01290395, 40.70494079 ], [ -74.01289739, 40.70490238 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01450152, 40.70556042 ], [ -74.014431, 40.70572052 ], [ -74.01424038, 40.70615288 ], [ -74.01396289, 40.70605849 ], [ -74.0137605, 40.70598958 ], [ -74.01343135, 40.70587755 ], [ -74.01350367, 40.7057878 ], [ -74.01351687, 40.70579441 ], [ -74.01374073, 40.70551677 ], [ -74.01372699, 40.70551078 ], [ -74.01381502, 40.70540161 ], [ -74.01391905, 40.70542572 ], [ -74.0140776, 40.70546229 ], [ -74.01416357, 40.70548217 ], [ -74.01432212, 40.70551888 ], [ -74.01450152, 40.70556042 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01228914, 40.70555068 ], [ -74.0122409, 40.70564977 ], [ -74.01220147, 40.70564568 ], [ -74.0121323, 40.70563839 ], [ -74.01200132, 40.70562471 ], [ -74.01179318, 40.7056275 ], [ -74.01164748, 40.70562968 ], [ -74.01157723, 40.70562988 ], [ -74.01156861, 40.70563002 ], [ -74.01163975, 40.70504546 ], [ -74.01232014, 40.70507147 ], [ -74.01248408, 40.70507848 ], [ -74.01248049, 40.7051442 ], [ -74.01228914, 40.70555068 ] ] ] } }, { "type": "Feature", "properties": { "height": 94.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01021547, 40.70258941 ], [ -74.01092442, 40.70246846 ], [ -74.0111384, 40.70243761 ], [ -74.01115367, 40.70253098 ], [ -74.01114694, 40.70253262 ], [ -74.01114469, 40.7025254 ], [ -74.01113095, 40.70252778 ], [ -74.01113328, 40.70253616 ], [ -74.0111216, 40.7025382 ], [ -74.01112852, 40.70256149 ], [ -74.01117532, 40.70255345 ], [ -74.01125743, 40.7028326 ], [ -74.01029084, 40.70299741 ], [ -74.01027153, 40.7029319 ], [ -74.01020892, 40.70271921 ], [ -74.0102462, 40.70271288 ], [ -74.01023622, 40.70267897 ], [ -74.01021853, 40.70268196 ], [ -74.01022077, 40.70269007 ], [ -74.01021359, 40.70269129 ], [ -74.01017352, 40.70259936 ], [ -74.01020883, 40.70259336 ], [ -74.01020802, 40.70259057 ], [ -74.01021547, 40.70258941 ] ] ] } }, { "type": "Feature", "properties": { "height": 195.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01156897, 40.70207436 ], [ -74.01159717, 40.70206789 ], [ -74.0123858, 40.70193611 ], [ -74.01241473, 40.70193311 ], [ -74.01249153, 40.70192017 ], [ -74.01260212, 40.70230039 ], [ -74.01159933, 40.70246799 ], [ -74.01148875, 40.70208777 ], [ -74.01156897, 40.70207436 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00749609, 40.7042207 ], [ -74.00690967, 40.70462181 ], [ -74.00650328, 40.7042775 ], [ -74.0070852, 40.70387952 ], [ -74.0070897, 40.70387645 ], [ -74.00749609, 40.7042207 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01307445, 40.70478777 ], [ -74.01308451, 40.70485212 ], [ -74.01289218, 40.70486949 ], [ -74.01288212, 40.7048052 ], [ -74.01279561, 40.7048131 ], [ -74.01276489, 40.70461806 ], [ -74.01271063, 40.70462297 ], [ -74.01270264, 40.70457216 ], [ -74.01269491, 40.70452381 ], [ -74.01214802, 40.70457332 ], [ -74.0121146, 40.7043614 ], [ -74.01219024, 40.70435459 ], [ -74.01236559, 40.70433872 ], [ -74.01235113, 40.70424631 ], [ -74.01294357, 40.70419258 ], [ -74.01295273, 40.70425046 ], [ -74.01301507, 40.70424481 ], [ -74.01310032, 40.70478552 ], [ -74.01307445, 40.70478777 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00814441, 40.70383811 ], [ -74.0081056, 40.70386447 ], [ -74.00806679, 40.70389076 ], [ -74.0080279, 40.70391718 ], [ -74.00798963, 40.70394326 ], [ -74.00789459, 40.70400782 ], [ -74.00785668, 40.70403356 ], [ -74.00781787, 40.70405998 ], [ -74.00777897, 40.70408641 ], [ -74.00774008, 40.70411276 ], [ -74.00770181, 40.70413878 ], [ -74.00766596, 40.70410847 ], [ -74.0076312, 40.70407912 ], [ -74.00759644, 40.7040497 ], [ -74.00756158, 40.70402021 ], [ -74.00752673, 40.70399066 ], [ -74.00743501, 40.70391316 ], [ -74.00740024, 40.70388381 ], [ -74.00736539, 40.70385432 ], [ -74.00733062, 40.7038249 ], [ -74.00729568, 40.70379542 ], [ -74.00726118, 40.7037662 ], [ -74.00730098, 40.7037391 ], [ -74.00733988, 40.70371281 ], [ -74.00737868, 40.70368632 ], [ -74.00741749, 40.70365996 ], [ -74.00745648, 40.70363347 ], [ -74.00754972, 40.70357021 ], [ -74.00758853, 40.70354378 ], [ -74.00762743, 40.70351736 ], [ -74.00766632, 40.70349087 ], [ -74.00770513, 40.70346458 ], [ -74.0077434, 40.70343857 ], [ -74.00777951, 40.70346908 ], [ -74.00781419, 40.7034985 ], [ -74.00784913, 40.70352798 ], [ -74.00788381, 40.7035574 ], [ -74.00791875, 40.70358689 ], [ -74.0080102, 40.70366419 ], [ -74.00804496, 40.70369367 ], [ -74.00807982, 40.70372309 ], [ -74.00811458, 40.70375251 ], [ -74.00813201, 40.70376729 ], [ -74.00814953, 40.70378207 ], [ -74.00818402, 40.70381121 ], [ -74.00814441, 40.70383811 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01441761, 40.70571698 ], [ -74.01423175, 40.70613558 ], [ -74.01397151, 40.706048 ], [ -74.01401975, 40.7059893 ], [ -74.01399954, 40.70594586 ], [ -74.01387692, 40.7058939 ], [ -74.01382931, 40.70590309 ], [ -74.01376894, 40.70597936 ], [ -74.01353753, 40.70589887 ], [ -74.01358631, 40.70582907 ], [ -74.01351687, 40.70579441 ], [ -74.01374073, 40.70551677 ], [ -74.01382275, 40.70555266 ], [ -74.01391905, 40.70542572 ], [ -74.0140776, 40.70546229 ], [ -74.01416357, 40.70548217 ], [ -74.01400915, 40.70567871 ], [ -74.01402523, 40.70572032 ], [ -74.01414785, 40.70577411 ], [ -74.01419779, 40.70576546 ], [ -74.014264, 40.70567748 ], [ -74.01441761, 40.70571698 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00574447, 40.70538282 ], [ -74.00563047, 40.70546311 ], [ -74.00549438, 40.70555906 ], [ -74.00540338, 40.70555661 ], [ -74.00527537, 40.70545221 ], [ -74.00517215, 40.70536797 ], [ -74.00504585, 40.70526508 ], [ -74.0050489, 40.70519439 ], [ -74.00518392, 40.70509912 ], [ -74.00529783, 40.70501876 ], [ -74.00532289, 40.70501951 ], [ -74.00541191, 40.70495672 ], [ -74.00555394, 40.70495979 ], [ -74.0056346, 40.7050287 ], [ -74.00565284, 40.70502891 ], [ -74.00575615, 40.70511321 ], [ -74.00588245, 40.70521611 ], [ -74.00587931, 40.70528762 ], [ -74.00574447, 40.70538282 ] ] ] } }, { "type": "Feature", "properties": { "height": 135.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01145542, 40.70416888 ], [ -74.01139882, 40.70421375 ], [ -74.01128644, 40.70421607 ], [ -74.01114631, 40.70424181 ], [ -74.01104543, 40.70428002 ], [ -74.01097033, 40.70426149 ], [ -74.01072392, 40.70388469 ], [ -74.01074934, 40.70382701 ], [ -74.01085013, 40.70378881 ], [ -74.01126812, 40.70371022 ], [ -74.01138059, 40.70370777 ], [ -74.01144024, 40.70374952 ], [ -74.01145542, 40.70416888 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00978114, 40.70583309 ], [ -74.00951784, 40.70626238 ], [ -74.00890905, 40.70597316 ], [ -74.00904344, 40.7057515 ], [ -74.00912231, 40.7056211 ], [ -74.00978114, 40.70583309 ] ] ] } }, { "type": "Feature", "properties": { "height": 154.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01092442, 40.70246846 ], [ -74.01021547, 40.70258941 ], [ -74.01020029, 40.70253759 ], [ -74.01017047, 40.70254256 ], [ -74.01016535, 40.70252492 ], [ -74.01008962, 40.7022677 ], [ -74.01011944, 40.70226266 ], [ -74.01010381, 40.70220981 ], [ -74.01081582, 40.70208839 ], [ -74.01083127, 40.7021413 ], [ -74.0108637, 40.70213572 ], [ -74.01094473, 40.70241058 ], [ -74.01090915, 40.70241671 ], [ -74.01092442, 40.70246846 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00978293, 40.70420919 ], [ -74.00947607, 40.7044073 ], [ -74.00916992, 40.7041349 ], [ -74.00948299, 40.70393257 ], [ -74.00974485, 40.70376361 ], [ -74.00979102, 40.70380468 ], [ -74.01004048, 40.70402668 ], [ -74.01005099, 40.70403601 ], [ -74.00978293, 40.70420919 ] ] ] } }, { "type": "Feature", "properties": { "height": 69.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01468342, 40.70514747 ], [ -74.01450152, 40.70556042 ], [ -74.01432212, 40.70551888 ], [ -74.01416357, 40.70548217 ], [ -74.0140776, 40.70546229 ], [ -74.01391905, 40.70542572 ], [ -74.01381502, 40.70540161 ], [ -74.01380101, 40.70539828 ], [ -74.0138806, 40.70529102 ], [ -74.0138983, 40.70529511 ], [ -74.0140202, 40.7051269 ], [ -74.01400205, 40.70512268 ], [ -74.01408542, 40.70500895 ], [ -74.01409458, 40.70501147 ], [ -74.01411048, 40.7050159 ], [ -74.01414974, 40.70502659 ], [ -74.0142534, 40.70505506 ], [ -74.01431691, 40.70507249 ], [ -74.01431961, 40.70507331 ], [ -74.01427128, 40.70513426 ], [ -74.01429113, 40.70514202 ], [ -74.01424972, 40.7052044 ], [ -74.01422088, 40.70519779 ], [ -74.01419447, 40.70523096 ], [ -74.01418261, 40.70522817 ], [ -74.01414857, 40.70527107 ], [ -74.01413042, 40.7053169 ], [ -74.01419241, 40.70533127 ], [ -74.01422385, 40.70525316 ], [ -74.01434772, 40.7052819 ], [ -74.01431556, 40.70536171 ], [ -74.01436892, 40.70537397 ], [ -74.01442139, 40.7052424 ], [ -74.01439506, 40.70523641 ], [ -74.01442031, 40.70517321 ], [ -74.01445022, 40.70518009 ], [ -74.01448184, 40.70510082 ], [ -74.01449109, 40.705103 ], [ -74.01454275, 40.70511492 ], [ -74.01462629, 40.70513419 ], [ -74.01466654, 40.70514352 ], [ -74.01468342, 40.70514747 ] ] ] } }, { "type": "Feature", "properties": { "height": 132.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01104103, 40.70498771 ], [ -74.01101533, 40.70482427 ], [ -74.01100473, 40.70475678 ], [ -74.01108522, 40.7047495 ], [ -74.01105315, 40.70469352 ], [ -74.01094194, 40.70449991 ], [ -74.01136244, 40.70435356 ], [ -74.0114467, 40.7044028 ], [ -74.0114406, 40.70490837 ], [ -74.01136047, 40.70497947 ], [ -74.01104273, 40.70499881 ], [ -74.01104103, 40.70498771 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01122168, 40.70591828 ], [ -74.0110739, 40.70619728 ], [ -74.01030198, 40.70590799 ], [ -74.01039945, 40.7057575 ], [ -74.01044347, 40.70577398 ], [ -74.01050437, 40.70568 ], [ -74.01062987, 40.70572699 ], [ -74.01056995, 40.70581967 ], [ -74.01067047, 40.70585747 ], [ -74.01069895, 40.70581361 ], [ -74.01071467, 40.70581947 ], [ -74.01076857, 40.70575259 ], [ -74.01077027, 40.70571187 ], [ -74.01074593, 40.7057148 ], [ -74.01068664, 40.70542177 ], [ -74.01079812, 40.7054087 ], [ -74.0108063, 40.70544908 ], [ -74.01084124, 40.7056213 ], [ -74.01084528, 40.70564146 ], [ -74.0108575, 40.70570166 ], [ -74.0108478, 40.70578167 ], [ -74.01087241, 40.70579161 ], [ -74.01084133, 40.70586496 ], [ -74.01085831, 40.70587129 ], [ -74.01083549, 40.70590656 ], [ -74.01097428, 40.70595859 ], [ -74.01101938, 40.70588886 ], [ -74.01122168, 40.70591828 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01321118, 40.70555988 ], [ -74.01312224, 40.7055327 ], [ -74.01299019, 40.705493 ], [ -74.01277325, 40.70542647 ], [ -74.01265341, 40.70539079 ], [ -74.01258074, 40.70536716 ], [ -74.01254498, 40.7053566 ], [ -74.01266078, 40.7051156 ], [ -74.0126968, 40.70509619 ], [ -74.01290763, 40.70510409 ], [ -74.01302954, 40.70510722 ], [ -74.01324863, 40.70511437 ], [ -74.01325043, 40.70516586 ], [ -74.01325322, 40.70528006 ], [ -74.01325717, 40.7053455 ], [ -74.01325519, 40.70540638 ], [ -74.01324504, 40.70546529 ], [ -74.01321118, 40.70555988 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00992352, 40.7053472 ], [ -74.00983378, 40.70567176 ], [ -74.00976605, 40.70570758 ], [ -74.0091277, 40.70549988 ], [ -74.00911818, 40.70535701 ], [ -74.00987959, 40.7052633 ], [ -74.00992352, 40.7053472 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01350187, 40.70067477 ], [ -74.01350843, 40.70071931 ], [ -74.0131809, 40.70074792 ], [ -74.01283864, 40.7007725 ], [ -74.01275483, 40.70078108 ], [ -74.01243261, 40.7008532 ], [ -74.01239003, 40.70074792 ], [ -74.0123567, 40.70067716 ], [ -74.01239209, 40.70067062 ], [ -74.01262314, 40.70061852 ], [ -74.0128116, 40.70057459 ], [ -74.01289991, 40.70056056 ], [ -74.01313742, 40.70054299 ], [ -74.01326813, 40.70053196 ], [ -74.01350151, 40.70051568 ], [ -74.013544, 40.70051146 ], [ -74.01355343, 40.70057228 ], [ -74.01356844, 40.70066871 ], [ -74.01350187, 40.70067477 ] ] ] } }, { "type": "Feature", "properties": { "height": 160.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00575615, 40.70511321 ], [ -74.00574447, 40.70538282 ], [ -74.00563047, 40.70546311 ], [ -74.00527537, 40.70545221 ], [ -74.00517215, 40.70536797 ], [ -74.00518392, 40.70509912 ], [ -74.00529783, 40.70501876 ], [ -74.00532289, 40.70501951 ], [ -74.0056346, 40.7050287 ], [ -74.00565284, 40.70502891 ], [ -74.00575615, 40.70511321 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0063608, 40.70466451 ], [ -74.00634607, 40.70467731 ], [ -74.00633565, 40.7046865 ], [ -74.00632559, 40.70469508 ], [ -74.00631427, 40.70470489 ], [ -74.00631113, 40.70470782 ], [ -74.00629064, 40.70472559 ], [ -74.00627699, 40.70473737 ], [ -74.00625453, 40.70475699 ], [ -74.00624474, 40.7047655 ], [ -74.00618572, 40.70481719 ], [ -74.0061965, 40.70482406 ], [ -74.00616138, 40.70485525 ], [ -74.00616757, 40.70485941 ], [ -74.00598414, 40.70500718 ], [ -74.00593392, 40.70497947 ], [ -74.00592817, 40.70498471 ], [ -74.00590805, 40.70500337 ], [ -74.00589251, 40.70501767 ], [ -74.00587401, 40.7050347 ], [ -74.00586035, 40.70504729 ], [ -74.005738, 40.70497232 ], [ -74.00571051, 40.7049555 ], [ -74.00553247, 40.70484627 ], [ -74.00567629, 40.70475072 ], [ -74.00573881, 40.70470979 ], [ -74.00587607, 40.7046199 ], [ -74.00593877, 40.70457877 ], [ -74.00608771, 40.70448146 ], [ -74.00621465, 40.70456576 ], [ -74.0063608, 40.70466451 ] ] ] } }, { "type": "Feature", "properties": { "height": 151.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0141421, 40.70322671 ], [ -74.01413132, 40.70353248 ], [ -74.01340027, 40.70351756 ], [ -74.01341114, 40.70321438 ], [ -74.01341123, 40.70321166 ], [ -74.0141421, 40.70322671 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0124609, 40.70092342 ], [ -74.01252989, 40.70090728 ], [ -74.01284601, 40.70141158 ], [ -74.01336263, 40.70145258 ], [ -74.01352747, 40.70123676 ], [ -74.01354481, 40.701052 ], [ -74.01367021, 40.70127688 ], [ -74.01367363, 40.70130262 ], [ -74.01366482, 40.7013223 ], [ -74.01350043, 40.70149372 ], [ -74.01333218, 40.70166138 ], [ -74.01330694, 40.70168549 ], [ -74.01328924, 40.70171137 ], [ -74.0132816, 40.70173997 ], [ -74.01328268, 40.70178288 ], [ -74.01329813, 40.70181639 ], [ -74.01332221, 40.70184322 ], [ -74.01335167, 40.70186549 ], [ -74.01371585, 40.70210848 ], [ -74.01367524, 40.70214382 ], [ -74.01329571, 40.70188966 ], [ -74.01326678, 40.70186549 ], [ -74.01324621, 40.70184049 ], [ -74.01322968, 40.70180842 ], [ -74.01322204, 40.70177621 ], [ -74.01321971, 40.70174576 ], [ -74.01322618, 40.70171716 ], [ -74.01324154, 40.70168679 ], [ -74.01326274, 40.70166002 ], [ -74.0133134, 40.70161051 ], [ -74.01332517, 40.70159042 ], [ -74.01332517, 40.70157067 ], [ -74.01331403, 40.70154786 ], [ -74.01329274, 40.70153267 ], [ -74.01326274, 40.7015247 ], [ -74.01303699, 40.70150822 ], [ -74.01300115, 40.7015104 ], [ -74.01296755, 40.70152157 ], [ -74.01294509, 40.70153451 ], [ -74.01292623, 40.70154929 ], [ -74.01291087, 40.70156761 ], [ -74.01290153, 40.70158722 ], [ -74.01290862, 40.70161092 ], [ -74.01292515, 40.70162788 ], [ -74.01294797, 40.7016355 ], [ -74.01297285, 40.7016368 ], [ -74.01299809, 40.70163006 ], [ -74.01301525, 40.70161936 ], [ -74.01303699, 40.7016069 ], [ -74.01307472, 40.70163768 ], [ -74.01304885, 40.7016556 ], [ -74.01302289, 40.70167078 ], [ -74.01298929, 40.7016797 ], [ -74.01295102, 40.70168059 ], [ -74.01291859, 40.70167426 ], [ -74.01288742, 40.70166138 ], [ -74.01286613, 40.7016449 ], [ -74.01285023, 40.70162481 ], [ -74.01284323, 40.70159839 ], [ -74.01284367, 40.70156216 ], [ -74.012839, 40.70152961 ], [ -74.01282409, 40.7014946 ], [ -74.01259502, 40.70114571 ], [ -74.01257059, 40.70115211 ], [ -74.0124609, 40.70092342 ] ] ] } }, { "type": "Feature", "properties": { "height": 94.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01361901, 40.70582301 ], [ -74.01354634, 40.70578869 ], [ -74.01375133, 40.70553951 ], [ -74.01382589, 40.70557472 ], [ -74.01392543, 40.7054486 ], [ -74.01397043, 40.7054706 ], [ -74.0139804, 40.70546461 ], [ -74.01399684, 40.7054642 ], [ -74.01401714, 40.70547087 ], [ -74.01403134, 40.70548129 ], [ -74.01403915, 40.70549212 ], [ -74.01403655, 40.70550301 ], [ -74.01408757, 40.70552801 ], [ -74.01405038, 40.7055769 ], [ -74.01402298, 40.70556512 ], [ -74.01390953, 40.70570002 ], [ -74.01413653, 40.70580306 ], [ -74.01421873, 40.7057861 ], [ -74.01425978, 40.70573189 ], [ -74.01427352, 40.70571861 ], [ -74.01428915, 40.70571337 ], [ -74.01431161, 40.70571262 ], [ -74.01433119, 40.70571711 ], [ -74.01434593, 40.70573421 ], [ -74.01434979, 40.70575198 ], [ -74.01419914, 40.70609309 ], [ -74.01405918, 40.70602928 ], [ -74.01411398, 40.70597078 ], [ -74.01384592, 40.70584991 ], [ -74.01376283, 40.70596111 ], [ -74.01356808, 40.70589506 ], [ -74.01361901, 40.70582301 ] ] ] } }, { "type": "Feature", "properties": { "height": 82.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01321118, 40.70555988 ], [ -74.01312314, 40.70577765 ], [ -74.01312943, 40.7057799 ], [ -74.01307849, 40.70585617 ], [ -74.01242389, 40.70560891 ], [ -74.01254498, 40.7053566 ], [ -74.01258074, 40.70536716 ], [ -74.01265341, 40.70539079 ], [ -74.01277325, 40.70542647 ], [ -74.01299019, 40.705493 ], [ -74.01312224, 40.7055327 ], [ -74.01321118, 40.70555988 ] ] ] } }, { "type": "Feature", "properties": { "height": 139.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01354292, 40.70285331 ], [ -74.0135431, 40.70300796 ], [ -74.01315494, 40.70302336 ], [ -74.01313581, 40.70274387 ], [ -74.0131208, 40.70252349 ], [ -74.01356044, 40.70250619 ], [ -74.01357769, 40.70275939 ], [ -74.01354274, 40.70276076 ], [ -74.01354292, 40.70285331 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00871502, 40.70486928 ], [ -74.00853913, 40.70470026 ], [ -74.00844382, 40.70460867 ], [ -74.00889091, 40.70431236 ], [ -74.00918924, 40.70460996 ], [ -74.00871502, 40.70486928 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01133747, 40.70545521 ], [ -74.01127692, 40.70545419 ], [ -74.01122482, 40.7054533 ], [ -74.01101174, 40.70544969 ], [ -74.01100608, 40.7053901 ], [ -74.01080863, 40.705401 ], [ -74.01080405, 40.70535326 ], [ -74.01078249, 40.70535449 ], [ -74.01069931, 40.70535898 ], [ -74.01066364, 40.70521346 ], [ -74.01066077, 40.70520127 ], [ -74.01064747, 40.7051476 ], [ -74.01141338, 40.70510538 ], [ -74.01133747, 40.70545521 ] ] ] } }, { "type": "Feature", "properties": { "height": 95.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00725337, 40.70491212 ], [ -74.00726684, 40.70490258 ], [ -74.00728023, 40.70489291 ], [ -74.00729361, 40.70488318 ], [ -74.007307, 40.70487357 ], [ -74.00735838, 40.70483768 ], [ -74.00739863, 40.70486976 ], [ -74.00746124, 40.70482481 ], [ -74.00742099, 40.70479267 ], [ -74.00736413, 40.7047465 ], [ -74.00731948, 40.70471068 ], [ -74.00730691, 40.70470046 ], [ -74.00729424, 40.70469032 ], [ -74.00728158, 40.7046801 ], [ -74.00726891, 40.70466989 ], [ -74.00766147, 40.70438782 ], [ -74.00794759, 40.7046184 ], [ -74.00738794, 40.70502046 ], [ -74.00725337, 40.70491212 ] ] ] } }, { "type": "Feature", "properties": { "height": 97.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00860929, 40.70416098 ], [ -74.00814351, 40.70447648 ], [ -74.00786674, 40.70423991 ], [ -74.0080111, 40.70414198 ], [ -74.00833242, 40.70392426 ], [ -74.00860929, 40.70416098 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00945604, 40.70559849 ], [ -74.00913588, 40.70549498 ], [ -74.00912734, 40.70538806 ], [ -74.00952772, 40.70533746 ], [ -74.00987843, 40.70529347 ], [ -74.00991014, 40.70535428 ], [ -74.00981914, 40.70567026 ], [ -74.00976784, 40.70569982 ], [ -74.00945604, 40.70559849 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01069931, 40.70535898 ], [ -74.01058172, 40.70536797 ], [ -74.0106313, 40.70554946 ], [ -74.0102921, 40.7055549 ], [ -74.0101755, 40.70556526 ], [ -74.01, 40.70558208 ], [ -74.01007677, 40.70536927 ], [ -74.0101075, 40.70529906 ], [ -74.01014217, 40.70521768 ], [ -74.01020317, 40.70525479 ], [ -74.01022113, 40.70526562 ], [ -74.01031312, 40.70525268 ], [ -74.01029614, 40.7052076 ], [ -74.0105562, 40.70518799 ], [ -74.01055881, 40.7052138 ], [ -74.01066364, 40.70521346 ], [ -74.01069931, 40.70535898 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01321118, 40.70555988 ], [ -74.01312224, 40.7055327 ], [ -74.01299019, 40.705493 ], [ -74.01277325, 40.70542647 ], [ -74.01265341, 40.70539079 ], [ -74.01258074, 40.70536716 ], [ -74.01268961, 40.70513419 ], [ -74.01270282, 40.70512588 ], [ -74.01289533, 40.70513528 ], [ -74.01289308, 40.70516388 ], [ -74.01289407, 40.70521257 ], [ -74.01306897, 40.70526392 ], [ -74.01304669, 40.70517158 ], [ -74.01304023, 40.70513971 ], [ -74.01324217, 40.70515632 ], [ -74.01325043, 40.70516586 ], [ -74.01325322, 40.70528006 ], [ -74.01325717, 40.7053455 ], [ -74.01325519, 40.70540638 ], [ -74.01324504, 40.70546529 ], [ -74.01321118, 40.70555988 ] ] ] } }, { "type": "Feature", "properties": { "height": 175.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0079916, 40.70367808 ], [ -74.00797157, 40.70392801 ], [ -74.00787725, 40.70399297 ], [ -74.00754739, 40.70397847 ], [ -74.00745423, 40.70389927 ], [ -74.00747292, 40.70364879 ], [ -74.00756742, 40.7035856 ], [ -74.00789908, 40.70359922 ], [ -74.0079916, 40.70367808 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01267021, 40.70398596 ], [ -74.01254427, 40.70398746 ], [ -74.01254301, 40.70397806 ], [ -74.01254103, 40.70396301 ], [ -74.0125378, 40.70393849 ], [ -74.01253295, 40.70390186 ], [ -74.01253061, 40.7038849 ], [ -74.01251444, 40.70376559 ], [ -74.01243413, 40.70377192 ], [ -74.01242308, 40.7036902 ], [ -74.01241958, 40.70366439 ], [ -74.01241688, 40.7036441 ], [ -74.01258828, 40.70364682 ], [ -74.01300914, 40.70365349 ], [ -74.01305343, 40.70398126 ], [ -74.01267021, 40.70398596 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00830009, 40.7050966 ], [ -74.00827412, 40.7051156 ], [ -74.00826882, 40.70511948 ], [ -74.00826343, 40.70512336 ], [ -74.00823738, 40.70514236 ], [ -74.00823208, 40.70514631 ], [ -74.00822669, 40.70515019 ], [ -74.00820073, 40.70516919 ], [ -74.00819552, 40.70517307 ], [ -74.00819004, 40.70517696 ], [ -74.00816408, 40.70519609 ], [ -74.00815887, 40.70519997 ], [ -74.00815339, 40.70520392 ], [ -74.00812743, 40.70522292 ], [ -74.00812213, 40.70522667 ], [ -74.00811674, 40.70523069 ], [ -74.00809069, 40.70524948 ], [ -74.00808548, 40.70525336 ], [ -74.00808, 40.70525738 ], [ -74.00805404, 40.70527638 ], [ -74.00804883, 40.70528026 ], [ -74.00804344, 40.70528428 ], [ -74.0080173, 40.70530328 ], [ -74.00801209, 40.70530716 ], [ -74.0080067, 40.70531111 ], [ -74.00798064, 40.70532991 ], [ -74.00797543, 40.70533386 ], [ -74.00796986, 40.70533781 ], [ -74.00794399, 40.7053568 ], [ -74.00793869, 40.70536069 ], [ -74.0079333, 40.7053647 ], [ -74.00790734, 40.70538357 ], [ -74.00790213, 40.70538752 ], [ -74.00789665, 40.7053914 ], [ -74.00789036, 40.70538616 ], [ -74.00786234, 40.7053852 ], [ -74.00785659, 40.70538929 ], [ -74.00785147, 40.70538527 ], [ -74.00784644, 40.70538118 ], [ -74.00782299, 40.7053628 ], [ -74.00781805, 40.70535878 ], [ -74.00781275, 40.70535469 ], [ -74.00778957, 40.70533617 ], [ -74.00778463, 40.70533222 ], [ -74.00777933, 40.70532807 ], [ -74.00775607, 40.70530982 ], [ -74.00775113, 40.70530566 ], [ -74.00774583, 40.70530171 ], [ -74.00772247, 40.70528319 ], [ -74.00771753, 40.70527917 ], [ -74.00771223, 40.70527509 ], [ -74.00768914, 40.70525656 ], [ -74.00768411, 40.70525261 ], [ -74.00767881, 40.70524846 ], [ -74.00765563, 40.70523007 ], [ -74.00765051, 40.70522605 ], [ -74.0076453, 40.70522197 ], [ -74.00765105, 40.70521781 ], [ -74.00765078, 40.70519657 ], [ -74.00764539, 40.70519228 ], [ -74.00765069, 40.70518846 ], [ -74.00765608, 40.70518451 ], [ -74.00768231, 40.70516558 ], [ -74.00768752, 40.70516177 ], [ -74.007693, 40.70515782 ], [ -74.00771915, 40.70513889 ], [ -74.00772445, 40.70513507 ], [ -74.00772984, 40.70513106 ], [ -74.00775589, 40.70511206 ], [ -74.00776119, 40.70510831 ], [ -74.00776658, 40.70510429 ], [ -74.00779281, 40.70508529 ], [ -74.0077982, 40.70508162 ], [ -74.00780359, 40.70507746 ], [ -74.00782955, 40.70505867 ], [ -74.00783494, 40.70505499 ], [ -74.00784033, 40.7050509 ], [ -74.00786647, 40.70503197 ], [ -74.00787177, 40.70502816 ], [ -74.00787725, 40.70502421 ], [ -74.00790321, 40.70500521 ], [ -74.0079086, 40.7050014 ], [ -74.0079139, 40.70499738 ], [ -74.00794013, 40.70497838 ], [ -74.00794543, 40.7049747 ], [ -74.00795091, 40.70497068 ], [ -74.00797678, 40.70495182 ], [ -74.00798208, 40.70494801 ], [ -74.00798765, 40.70494399 ], [ -74.00801388, 40.70492492 ], [ -74.00801918, 40.70492131 ], [ -74.00802457, 40.70491716 ], [ -74.00805071, 40.70489816 ], [ -74.00805601, 40.70489448 ], [ -74.00806149, 40.70489039 ], [ -74.00806688, 40.70489468 ], [ -74.00809401, 40.70489441 ], [ -74.00809967, 40.70489026 ], [ -74.00810479, 40.70489428 ], [ -74.00810991, 40.70489836 ], [ -74.00813318, 40.70491702 ], [ -74.0081383, 40.70492097 ], [ -74.00814342, 40.70492519 ], [ -74.0081666, 40.70494378 ], [ -74.00817172, 40.7049478 ], [ -74.00817693, 40.70495189 ], [ -74.0082001, 40.70497048 ], [ -74.00820522, 40.7049745 ], [ -74.00821043, 40.70497872 ], [ -74.00823361, 40.70499731 ], [ -74.00823873, 40.70500126 ], [ -74.00824394, 40.70500541 ], [ -74.00826712, 40.70502387 ], [ -74.00827224, 40.70502789 ], [ -74.00827727, 40.70503211 ], [ -74.00830071, 40.7050507 ], [ -74.00830583, 40.70505479 ], [ -74.00831087, 40.70505887 ], [ -74.00830395, 40.70506357 ], [ -74.0083053, 40.70508448 ], [ -74.00831078, 40.70508877 ], [ -74.00830548, 40.70509272 ], [ -74.00830009, 40.7050966 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00867082, 40.70368087 ], [ -74.00913929, 40.70337108 ], [ -74.00930593, 40.70351579 ], [ -74.00937519, 40.70357599 ], [ -74.00890672, 40.70388592 ], [ -74.00867082, 40.70368087 ] ] ] } }, { "type": "Feature", "properties": { "height": 128.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01307445, 40.70478777 ], [ -74.01288212, 40.7048052 ], [ -74.01279561, 40.7048131 ], [ -74.01276489, 40.70461806 ], [ -74.01271054, 40.70427239 ], [ -74.01301507, 40.70424481 ], [ -74.01310032, 40.70478552 ], [ -74.01307445, 40.70478777 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00626513, 40.70516129 ], [ -74.00623225, 40.70514331 ], [ -74.00598414, 40.70500718 ], [ -74.00616757, 40.70485941 ], [ -74.00616138, 40.70485525 ], [ -74.0061965, 40.70482406 ], [ -74.00618572, 40.70481719 ], [ -74.00624474, 40.7047655 ], [ -74.00625453, 40.70475699 ], [ -74.00627699, 40.70473737 ], [ -74.00629064, 40.70472559 ], [ -74.00631113, 40.70470782 ], [ -74.00631427, 40.70470489 ], [ -74.00632559, 40.70469508 ], [ -74.00633565, 40.7046865 ], [ -74.00634607, 40.70467731 ], [ -74.0063608, 40.70466451 ], [ -74.00668411, 40.70487242 ], [ -74.00626513, 40.70516129 ] ] ] } }, { "type": "Feature", "properties": { "height": 136.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00644704, 40.7055897 ], [ -74.00592269, 40.70595246 ], [ -74.00571644, 40.70577977 ], [ -74.00601064, 40.70557629 ], [ -74.0062407, 40.70541707 ], [ -74.00644704, 40.7055897 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00899978, 40.70554517 ], [ -74.0088919, 40.70576397 ], [ -74.00882794, 40.7058939 ], [ -74.00878554, 40.7059052 ], [ -74.00848011, 40.70575906 ], [ -74.00849601, 40.70573748 ], [ -74.00852898, 40.70569301 ], [ -74.0085367, 40.70568252 ], [ -74.00854542, 40.70567081 ], [ -74.00858054, 40.70562328 ], [ -74.00863615, 40.70554809 ], [ -74.00868358, 40.70556839 ], [ -74.00870199, 40.70553468 ], [ -74.00869894, 40.70551922 ], [ -74.00869633, 40.70550601 ], [ -74.00869103, 40.70547952 ], [ -74.00868223, 40.70543498 ], [ -74.0086754, 40.7054008 ], [ -74.00898047, 40.70537199 ], [ -74.00899978, 40.70554517 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0121968, 40.70366677 ], [ -74.01219671, 40.70368257 ], [ -74.01219491, 40.70393196 ], [ -74.01219482, 40.70394762 ], [ -74.01219464, 40.7039799 ], [ -74.01205657, 40.70397629 ], [ -74.01198839, 40.70397452 ], [ -74.01192012, 40.70397282 ], [ -74.01185193, 40.70397098 ], [ -74.0117144, 40.70396737 ], [ -74.01172051, 40.703874 ], [ -74.01172383, 40.70382231 ], [ -74.01172725, 40.70377056 ], [ -74.01173048, 40.70371887 ], [ -74.01173659, 40.7036255 ], [ -74.01186442, 40.70362789 ], [ -74.0119326, 40.70362918 ], [ -74.01200088, 40.70363048 ], [ -74.01206915, 40.70363177 ], [ -74.01219698, 40.70363422 ], [ -74.0121968, 40.70366677 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01224917, 40.7008989 ], [ -74.01217659, 40.70091538 ], [ -74.01216221, 40.70091872 ], [ -74.01214541, 40.70092247 ], [ -74.01212367, 40.7008673 ], [ -74.01129219, 40.70105561 ], [ -74.01128285, 40.70103157 ], [ -74.01119572, 40.70105132 ], [ -74.0111508, 40.70093752 ], [ -74.01217227, 40.7007061 ], [ -74.01224917, 40.7008989 ] ] ] } }, { "type": "Feature", "properties": { "height": 89.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00978293, 40.70420919 ], [ -74.00960085, 40.70416248 ], [ -74.00949952, 40.70407122 ], [ -74.00948299, 40.70393257 ], [ -74.00974485, 40.70376361 ], [ -74.00979102, 40.70380468 ], [ -74.01004048, 40.70402668 ], [ -74.01005099, 40.70403601 ], [ -74.00978293, 40.70420919 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00824394, 40.70500541 ], [ -74.00823693, 40.70501011 ], [ -74.00823622, 40.70502761 ], [ -74.00823271, 40.7051173 ], [ -74.0082319, 40.70513807 ], [ -74.00823738, 40.70514236 ], [ -74.00823208, 40.70514631 ], [ -74.00822669, 40.70515019 ], [ -74.00820073, 40.70516919 ], [ -74.00819552, 40.70517307 ], [ -74.00819004, 40.70517696 ], [ -74.00816408, 40.70519609 ], [ -74.00815887, 40.70519997 ], [ -74.00815339, 40.70520392 ], [ -74.00812743, 40.70522292 ], [ -74.00812213, 40.70522667 ], [ -74.00811674, 40.70523069 ], [ -74.00809069, 40.70524948 ], [ -74.00808548, 40.70525336 ], [ -74.00808, 40.70525738 ], [ -74.00805404, 40.70527638 ], [ -74.00804883, 40.70528026 ], [ -74.00804344, 40.70528428 ], [ -74.0080173, 40.70530328 ], [ -74.00801209, 40.70530716 ], [ -74.0080067, 40.70531111 ], [ -74.00798064, 40.70532991 ], [ -74.00797543, 40.70533386 ], [ -74.00796986, 40.70533781 ], [ -74.00796367, 40.70533249 ], [ -74.00793905, 40.70533236 ], [ -74.00782039, 40.70533222 ], [ -74.00779532, 40.70533208 ], [ -74.00778957, 40.70533617 ], [ -74.00778463, 40.70533222 ], [ -74.00777933, 40.70532807 ], [ -74.00775607, 40.70530982 ], [ -74.00775113, 40.70530566 ], [ -74.00774583, 40.70530171 ], [ -74.00772247, 40.70528319 ], [ -74.00771753, 40.70527917 ], [ -74.00771223, 40.70527509 ], [ -74.00771789, 40.705271 ], [ -74.00771879, 40.70525282 ], [ -74.00772373, 40.70516191 ], [ -74.00772453, 40.70514318 ], [ -74.00771915, 40.70513889 ], [ -74.00772445, 40.70513507 ], [ -74.00772984, 40.70513106 ], [ -74.00775589, 40.70511206 ], [ -74.00776119, 40.70510831 ], [ -74.00776658, 40.70510429 ], [ -74.00779281, 40.70508529 ], [ -74.0077982, 40.70508162 ], [ -74.00780359, 40.70507746 ], [ -74.00782955, 40.70505867 ], [ -74.00783494, 40.70505499 ], [ -74.00784033, 40.7050509 ], [ -74.00786647, 40.70503197 ], [ -74.00787177, 40.70502816 ], [ -74.00787725, 40.70502421 ], [ -74.00790321, 40.70500521 ], [ -74.0079086, 40.7050014 ], [ -74.0079139, 40.70499738 ], [ -74.00794013, 40.70497838 ], [ -74.00794543, 40.7049747 ], [ -74.00795091, 40.70497068 ], [ -74.00797678, 40.70495182 ], [ -74.00798208, 40.70494801 ], [ -74.00798765, 40.70494399 ], [ -74.00799304, 40.70494828 ], [ -74.00801873, 40.70494821 ], [ -74.00813524, 40.70494787 ], [ -74.00816094, 40.70494787 ], [ -74.0081666, 40.70494378 ], [ -74.00817172, 40.7049478 ], [ -74.00817693, 40.70495189 ], [ -74.0082001, 40.70497048 ], [ -74.00820522, 40.7049745 ], [ -74.00821043, 40.70497872 ], [ -74.00823361, 40.70499731 ], [ -74.00823873, 40.70500126 ], [ -74.00824394, 40.70500541 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01468342, 40.70514747 ], [ -74.01466654, 40.70514352 ], [ -74.01462629, 40.70513419 ], [ -74.01454275, 40.70511492 ], [ -74.01449109, 40.705103 ], [ -74.01451328, 40.70504736 ], [ -74.01453269, 40.70505186 ], [ -74.01454122, 40.70503061 ], [ -74.01443702, 40.7050065 ], [ -74.01445642, 40.70495802 ], [ -74.0143311, 40.70492901 ], [ -74.01430739, 40.70498818 ], [ -74.01434692, 40.70499738 ], [ -74.01431691, 40.70507249 ], [ -74.0142534, 40.70505506 ], [ -74.01414974, 40.70502659 ], [ -74.01411048, 40.7050159 ], [ -74.01409458, 40.70501147 ], [ -74.01418522, 40.7047847 ], [ -74.01424208, 40.70477027 ], [ -74.01475879, 40.70487657 ], [ -74.01478673, 40.70491307 ], [ -74.01468342, 40.70514747 ] ] ] } }, { "type": "Feature", "properties": { "height": 111.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00711179, 40.70519936 ], [ -74.00674932, 40.70545582 ], [ -74.0064872, 40.70524117 ], [ -74.00675939, 40.70504866 ], [ -74.00684967, 40.70498478 ], [ -74.00711179, 40.70519936 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0123858, 40.70193611 ], [ -74.01159717, 40.70206789 ], [ -74.01154767, 40.70189777 ], [ -74.0123364, 40.70176599 ], [ -74.0123858, 40.70193611 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00824394, 40.70500541 ], [ -74.00823693, 40.70501011 ], [ -74.00823622, 40.70502761 ], [ -74.00823271, 40.7051173 ], [ -74.0082319, 40.70513807 ], [ -74.00823738, 40.70514236 ], [ -74.00823208, 40.70514631 ], [ -74.00822669, 40.70515019 ], [ -74.00822049, 40.70514488 ], [ -74.0081957, 40.70514406 ], [ -74.00819525, 40.7051649 ], [ -74.00820073, 40.70516919 ], [ -74.00819552, 40.70517307 ], [ -74.00819004, 40.70517696 ], [ -74.00818384, 40.70517178 ], [ -74.00815905, 40.70517089 ], [ -74.0081586, 40.7051918 ], [ -74.00816408, 40.70519609 ], [ -74.00815887, 40.70519997 ], [ -74.00815339, 40.70520392 ], [ -74.00814719, 40.70519861 ], [ -74.00812231, 40.70519779 ], [ -74.00812195, 40.70521856 ], [ -74.00812743, 40.70522292 ], [ -74.00812213, 40.70522667 ], [ -74.00811674, 40.70523069 ], [ -74.00811045, 40.70522537 ], [ -74.00808557, 40.70522456 ], [ -74.00808521, 40.70524519 ], [ -74.00809069, 40.70524948 ], [ -74.00808548, 40.70525336 ], [ -74.00808, 40.70525738 ], [ -74.0080738, 40.70525207 ], [ -74.00804901, 40.70525132 ], [ -74.00804865, 40.70527209 ], [ -74.00805404, 40.70527638 ], [ -74.00804883, 40.70528026 ], [ -74.00804344, 40.70528428 ], [ -74.00803715, 40.70527897 ], [ -74.00801227, 40.70527822 ], [ -74.00801191, 40.70529899 ], [ -74.0080173, 40.70530328 ], [ -74.00801209, 40.70530716 ], [ -74.0080067, 40.70531111 ], [ -74.00800041, 40.7053058 ], [ -74.00797552, 40.70530498 ], [ -74.00797508, 40.70532568 ], [ -74.00798064, 40.70532991 ], [ -74.00797543, 40.70533386 ], [ -74.00796986, 40.70533781 ], [ -74.00796367, 40.70533249 ], [ -74.00793905, 40.70533236 ], [ -74.00782039, 40.70533222 ], [ -74.00779532, 40.70533208 ], [ -74.00778957, 40.70533617 ], [ -74.00778463, 40.70533222 ], [ -74.00777933, 40.70532807 ], [ -74.00778499, 40.70532398 ], [ -74.00778697, 40.705306 ], [ -74.00776173, 40.70530559 ], [ -74.00775607, 40.70530982 ], [ -74.00775113, 40.70530566 ], [ -74.00774583, 40.70530171 ], [ -74.00775139, 40.70529749 ], [ -74.00775355, 40.70527938 ], [ -74.00772822, 40.7052791 ], [ -74.00772247, 40.70528319 ], [ -74.00771753, 40.70527917 ], [ -74.00771223, 40.70527509 ], [ -74.00771789, 40.705271 ], [ -74.00771879, 40.70525282 ], [ -74.00772373, 40.70516191 ], [ -74.00772453, 40.70514318 ], [ -74.00771915, 40.70513889 ], [ -74.00772445, 40.70513507 ], [ -74.00772984, 40.70513106 ], [ -74.00773531, 40.70513541 ], [ -74.00776083, 40.70513712 ], [ -74.00776137, 40.70511642 ], [ -74.00775589, 40.70511206 ], [ -74.00776119, 40.70510831 ], [ -74.00776658, 40.70510429 ], [ -74.00777215, 40.70510858 ], [ -74.00779775, 40.70511029 ], [ -74.00779829, 40.70508958 ], [ -74.00779281, 40.70508529 ], [ -74.0077982, 40.70508162 ], [ -74.00780359, 40.70507746 ], [ -74.00780898, 40.70508182 ], [ -74.0078344, 40.70508346 ], [ -74.00783503, 40.70506296 ], [ -74.00782955, 40.70505867 ], [ -74.00783494, 40.70505499 ], [ -74.00784033, 40.7050509 ], [ -74.00784572, 40.70505526 ], [ -74.00787141, 40.70505696 ], [ -74.00787195, 40.70503626 ], [ -74.00786647, 40.70503197 ], [ -74.00787177, 40.70502816 ], [ -74.00787725, 40.70502421 ], [ -74.00788273, 40.7050285 ], [ -74.00790815, 40.7050302 ], [ -74.0079086, 40.7050095 ], [ -74.00790321, 40.70500521 ], [ -74.0079086, 40.7050014 ], [ -74.0079139, 40.70499738 ], [ -74.00791938, 40.70500167 ], [ -74.00794498, 40.70500337 ], [ -74.00794561, 40.70498267 ], [ -74.00794013, 40.70497838 ], [ -74.00794543, 40.7049747 ], [ -74.00795091, 40.70497068 ], [ -74.0079563, 40.70497497 ], [ -74.00798172, 40.70497661 ], [ -74.00798235, 40.70495611 ], [ -74.00797678, 40.70495182 ], [ -74.00798208, 40.70494801 ], [ -74.00798765, 40.70494399 ], [ -74.00799304, 40.70494828 ], [ -74.00801873, 40.70494821 ], [ -74.00813524, 40.70494787 ], [ -74.00816094, 40.70494787 ], [ -74.0081666, 40.70494378 ], [ -74.00817172, 40.7049478 ], [ -74.00817693, 40.70495189 ], [ -74.00816992, 40.70495659 ], [ -74.00816857, 40.70497409 ], [ -74.00819444, 40.70497456 ], [ -74.0082001, 40.70497048 ], [ -74.00820522, 40.7049745 ], [ -74.00821043, 40.70497872 ], [ -74.00820343, 40.70498328 ], [ -74.00820208, 40.70500092 ], [ -74.00822795, 40.7050014 ], [ -74.00823361, 40.70499731 ], [ -74.00823873, 40.70500126 ], [ -74.00824394, 40.70500541 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01288149, 40.70342658 ], [ -74.01275357, 40.7034558 ], [ -74.01276974, 40.70350401 ], [ -74.01274612, 40.70353616 ], [ -74.0124229, 40.70353691 ], [ -74.012377, 40.7035177 ], [ -74.01232041, 40.70337591 ], [ -74.01234484, 40.70333996 ], [ -74.0128602, 40.70322248 ], [ -74.01290512, 40.70324012 ], [ -74.01296028, 40.70338027 ], [ -74.01293665, 40.70341398 ], [ -74.01288149, 40.70342658 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00945604, 40.70559849 ], [ -74.00943187, 40.70556069 ], [ -74.00917109, 40.70547618 ], [ -74.00916588, 40.70541142 ], [ -74.00947311, 40.70537267 ], [ -74.00952772, 40.70533746 ], [ -74.00982237, 40.70538411 ], [ -74.00984797, 40.70541489 ], [ -74.00979039, 40.70562471 ], [ -74.00975329, 40.70564541 ], [ -74.00945604, 40.70559849 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01421441, 40.7030034 ], [ -74.01420965, 40.7030604 ], [ -74.01376939, 40.70304467 ], [ -74.01377855, 40.70271227 ], [ -74.01387647, 40.70271411 ], [ -74.0138771, 40.70270961 ], [ -74.01397672, 40.7027233 ], [ -74.01406125, 40.7027579 ], [ -74.0141262, 40.70280189 ], [ -74.0141774, 40.70286168 ], [ -74.01421253, 40.7029385 ], [ -74.01422034, 40.7030034 ], [ -74.01421441, 40.7030034 ] ] ] } }, { "type": "Feature", "properties": { "height": 157.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01421441, 40.7030034 ], [ -74.01420965, 40.7030604 ], [ -74.01376939, 40.70304467 ], [ -74.01377855, 40.70271227 ], [ -74.01387647, 40.70271411 ], [ -74.01397483, 40.70272759 ], [ -74.01405784, 40.70276157 ], [ -74.01412171, 40.70280489 ], [ -74.0141721, 40.70286366 ], [ -74.01420669, 40.70293945 ], [ -74.01421441, 40.7030034 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00949134, 40.70517736 ], [ -74.00906815, 40.70524798 ], [ -74.00906195, 40.70522776 ], [ -74.0089829, 40.70497061 ], [ -74.00938813, 40.70488052 ], [ -74.00939091, 40.70488849 ], [ -74.0094025, 40.70492186 ], [ -74.00942702, 40.70499227 ], [ -74.00945155, 40.70506296 ], [ -74.00948002, 40.70514488 ], [ -74.00949134, 40.70517736 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.012203, 40.7032278 ], [ -74.01172815, 40.7033497 ], [ -74.01166832, 40.70304678 ], [ -74.0120704, 40.70294361 ], [ -74.01212888, 40.70306892 ], [ -74.012203, 40.7032278 ] ], [ [ -74.01202522, 40.70315288 ], [ -74.01199378, 40.70308049 ], [ -74.0120148, 40.70307518 ], [ -74.01200689, 40.70305707 ], [ -74.01186478, 40.70309289 ], [ -74.01191203, 40.70320151 ], [ -74.01199665, 40.70318019 ], [ -74.01198875, 40.70316208 ], [ -74.01202522, 40.70315288 ] ] ] } }, { "type": "Feature", "properties": { "height": 82.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01039945, 40.7057575 ], [ -74.01030198, 40.70590799 ], [ -74.00994301, 40.70577336 ], [ -74.01, 40.70558208 ], [ -74.0101755, 40.70556526 ], [ -74.0102921, 40.7055549 ], [ -74.0106313, 40.70554946 ], [ -74.01065053, 40.70562859 ], [ -74.01019517, 40.70563458 ], [ -74.01018313, 40.70567197 ], [ -74.01026695, 40.70570336 ], [ -74.01028312, 40.7056783 ], [ -74.01040151, 40.7057227 ], [ -74.01038301, 40.7057513 ], [ -74.01039945, 40.7057575 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01195794, 40.70446246 ], [ -74.01195587, 40.7044835 ], [ -74.01195461, 40.70450298 ], [ -74.01181834, 40.70450427 ], [ -74.01178402, 40.70450461 ], [ -74.01175231, 40.70450488 ], [ -74.01171934, 40.70450515 ], [ -74.01167937, 40.70450556 ], [ -74.01168107, 40.70447826 ], [ -74.01168521, 40.70441519 ], [ -74.01168691, 40.70438768 ], [ -74.01169464, 40.70426667 ], [ -74.01169653, 40.70423698 ], [ -74.01170012, 40.70417916 ], [ -74.0117021, 40.7041479 ], [ -74.01174189, 40.70414858 ], [ -74.01177495, 40.7041492 ], [ -74.01180648, 40.70414981 ], [ -74.0118408, 40.70415049 ], [ -74.01204714, 40.70415417 ], [ -74.01204768, 40.7041859 ], [ -74.01204831, 40.70421559 ], [ -74.0120492, 40.7042619 ], [ -74.01205019, 40.7043159 ], [ -74.0120519, 40.70441356 ], [ -74.01205352, 40.70446607 ], [ -74.01195794, 40.70446246 ] ] ] } }, { "type": "Feature", "properties": { "height": 153.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01179552, 40.70559188 ], [ -74.01171261, 40.70558848 ], [ -74.01173551, 40.70527148 ], [ -74.01183154, 40.70527549 ], [ -74.01212044, 40.70528762 ], [ -74.01209744, 40.70560448 ], [ -74.01179552, 40.70559188 ] ] ] } }, { "type": "Feature", "properties": { "height": 81.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0121968, 40.70366677 ], [ -74.01219671, 40.70368257 ], [ -74.01219491, 40.70393196 ], [ -74.01219482, 40.70394762 ], [ -74.01205801, 40.70394442 ], [ -74.01198983, 40.70394278 ], [ -74.01192164, 40.70394101 ], [ -74.01185328, 40.70393897 ], [ -74.01175752, 40.70393631 ], [ -74.01176228, 40.7038755 ], [ -74.0117657, 40.70382381 ], [ -74.01176911, 40.70377206 ], [ -74.01177243, 40.70372037 ], [ -74.01177701, 40.70365772 ], [ -74.01186334, 40.70365969 ], [ -74.01193161, 40.70366098 ], [ -74.0119998, 40.70366221 ], [ -74.01206807, 40.7036635 ], [ -74.0121968, 40.70366677 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0122409, 40.70564977 ], [ -74.01219473, 40.70574721 ], [ -74.01199647, 40.70572651 ], [ -74.01193287, 40.70571977 ], [ -74.01194177, 40.70586836 ], [ -74.01171647, 40.7058766 ], [ -74.01161819, 40.70586046 ], [ -74.0115863, 40.70585522 ], [ -74.01154462, 40.70584841 ], [ -74.0115545, 40.70578167 ], [ -74.01156537, 40.70570908 ], [ -74.01157723, 40.70562988 ], [ -74.01164748, 40.70562968 ], [ -74.01179318, 40.7056275 ], [ -74.01200132, 40.70562471 ], [ -74.0121323, 40.70563839 ], [ -74.01220147, 40.70564568 ], [ -74.0122409, 40.70564977 ] ] ] } }, { "type": "Feature", "properties": { "height": 86.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01312224, 40.7055327 ], [ -74.01299019, 40.705493 ], [ -74.01277325, 40.70542647 ], [ -74.01265341, 40.70539079 ], [ -74.01276301, 40.70517437 ], [ -74.01288482, 40.70521019 ], [ -74.01289407, 40.70521257 ], [ -74.01306897, 40.70526392 ], [ -74.0131032, 40.705274 ], [ -74.01323372, 40.705312 ], [ -74.01312224, 40.7055327 ] ] ] } }, { "type": "Feature", "properties": { "height": 41.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00755359, 40.70585161 ], [ -74.00741821, 40.70598672 ], [ -74.00708952, 40.70580081 ], [ -74.0070976, 40.70579236 ], [ -74.00707631, 40.70578038 ], [ -74.00692647, 40.70569621 ], [ -74.00706679, 40.70559052 ], [ -74.0070738, 40.7055959 ], [ -74.00709544, 40.70557956 ], [ -74.00711305, 40.70558997 ], [ -74.00712374, 40.70559651 ], [ -74.00716174, 40.70561946 ], [ -74.00726657, 40.70568116 ], [ -74.00731248, 40.7057086 ], [ -74.00731922, 40.70571262 ], [ -74.00735623, 40.70573462 ], [ -74.00747274, 40.70580367 ], [ -74.00753544, 40.70584078 ], [ -74.00755359, 40.70585161 ] ] ] } }, { "type": "Feature", "properties": { "height": 96.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00949134, 40.70517736 ], [ -74.00948002, 40.70514488 ], [ -74.00945155, 40.70506296 ], [ -74.00942702, 40.70499227 ], [ -74.0094025, 40.70492186 ], [ -74.00939091, 40.70488849 ], [ -74.0096861, 40.7048227 ], [ -74.00985453, 40.70509278 ], [ -74.00949134, 40.70517736 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01205513, 40.70114258 ], [ -74.01151327, 40.70126441 ], [ -74.01144599, 40.70109238 ], [ -74.01198785, 40.70097048 ], [ -74.01205513, 40.70114258 ] ] ] } }, { "type": "Feature", "properties": { "height": 11.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01522744, 40.70139762 ], [ -74.01519573, 40.70142541 ], [ -74.01517893, 40.701447 ], [ -74.0151536, 40.70149256 ], [ -74.0151307, 40.70153989 ], [ -74.01511983, 40.70155201 ], [ -74.01510734, 40.70155998 ], [ -74.015098, 40.70156407 ], [ -74.01507491, 40.70156917 ], [ -74.01505703, 40.70157026 ], [ -74.01504518, 40.70156958 ], [ -74.01503763, 40.70156849 ], [ -74.01502433, 40.7015625 ], [ -74.01501149, 40.70157891 ], [ -74.01494322, 40.70154806 ], [ -74.01493639, 40.70155691 ], [ -74.01488537, 40.7015339 ], [ -74.01489219, 40.70152518 ], [ -74.01483749, 40.70150059 ], [ -74.01484809, 40.7014869 ], [ -74.01480281, 40.70146647 ], [ -74.01490549, 40.70133442 ], [ -74.01488222, 40.70132387 ], [ -74.01495013, 40.70123656 ], [ -74.01494214, 40.70123302 ], [ -74.01499191, 40.70116886 ], [ -74.01505614, 40.70119788 ], [ -74.01510545, 40.70113447 ], [ -74.01515648, 40.70115749 ], [ -74.01507725, 40.70125951 ], [ -74.01502173, 40.70123452 ], [ -74.0150034, 40.70125801 ], [ -74.01507239, 40.70128907 ], [ -74.01507653, 40.70128389 ], [ -74.01510842, 40.70128239 ], [ -74.01513393, 40.70128852 ], [ -74.01515369, 40.70130296 ], [ -74.01516232, 40.7013225 ], [ -74.01515818, 40.70132782 ], [ -74.01519421, 40.70134389 ], [ -74.01517193, 40.70137256 ], [ -74.01522744, 40.70139762 ] ] ] } }, { "type": "Feature", "properties": { "height": 93.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01219671, 40.70368257 ], [ -74.01219491, 40.70393196 ], [ -74.01205873, 40.70392842 ], [ -74.011854, 40.7039231 ], [ -74.01178995, 40.70392126 ], [ -74.01180055, 40.70367447 ], [ -74.0118628, 40.70367556 ], [ -74.01206762, 40.70367951 ], [ -74.01219671, 40.70368257 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00913929, 40.70337108 ], [ -74.00867082, 40.70368087 ], [ -74.00853347, 40.70356156 ], [ -74.00900194, 40.70325177 ], [ -74.00913929, 40.70337108 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01130809, 40.7056292 ], [ -74.01130118, 40.70567156 ], [ -74.01128959, 40.70571296 ], [ -74.01127872, 40.70575532 ], [ -74.01126947, 40.7057861 ], [ -74.01125976, 40.7058181 ], [ -74.01124539, 40.70585678 ], [ -74.01123111, 40.70589526 ], [ -74.01122168, 40.70591828 ], [ -74.01101938, 40.70588886 ], [ -74.0109556, 40.7058796 ], [ -74.01095748, 40.70584419 ], [ -74.01092011, 40.70583949 ], [ -74.01092371, 40.70570969 ], [ -74.01092559, 40.70564289 ], [ -74.01084528, 40.70564146 ], [ -74.01084124, 40.7056213 ], [ -74.01130809, 40.7056292 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01105315, 40.70469352 ], [ -74.01099395, 40.70471837 ], [ -74.01100473, 40.70475678 ], [ -74.01072563, 40.70480227 ], [ -74.01069679, 40.70475208 ], [ -74.01056402, 40.70479628 ], [ -74.01050392, 40.70471177 ], [ -74.01067649, 40.7046088 ], [ -74.01094194, 40.70449991 ], [ -74.01105315, 40.70469352 ] ] ] } }, { "type": "Feature", "properties": { "height": 73.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0128691, 40.70304998 ], [ -74.01260445, 40.70312251 ], [ -74.01257885, 40.70307069 ], [ -74.01257535, 40.70307171 ], [ -74.01248381, 40.70289648 ], [ -74.01248659, 40.70289546 ], [ -74.01246063, 40.70284268 ], [ -74.01278555, 40.70275899 ], [ -74.0128691, 40.70304998 ] ] ] } }, { "type": "Feature", "properties": { "height": 122.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01122482, 40.7054533 ], [ -74.01101174, 40.70544969 ], [ -74.01100608, 40.7053901 ], [ -74.01080863, 40.705401 ], [ -74.01080405, 40.70535326 ], [ -74.01078249, 40.70535449 ], [ -74.01077144, 40.70523389 ], [ -74.01127037, 40.70521121 ], [ -74.01122482, 40.7054533 ] ] ] } }, { "type": "Feature", "properties": { "height": 83.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01307849, 40.70585617 ], [ -74.01297294, 40.70597977 ], [ -74.01237188, 40.70571711 ], [ -74.01242389, 40.70560891 ], [ -74.01307849, 40.70585617 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0098044, 40.70543498 ], [ -74.00975994, 40.70560537 ], [ -74.00972948, 40.70562239 ], [ -74.00949341, 40.70558507 ], [ -74.0094811, 40.7055831 ], [ -74.00945891, 40.70554837 ], [ -74.00920864, 40.70546828 ], [ -74.0092055, 40.70543525 ], [ -74.00948954, 40.7053995 ], [ -74.00953814, 40.70536818 ], [ -74.00954982, 40.70537008 ], [ -74.00978374, 40.70540761 ], [ -74.0098044, 40.70543498 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01232014, 40.70507147 ], [ -74.01231951, 40.70510388 ], [ -74.01188787, 40.70508597 ], [ -74.01188427, 40.70515339 ], [ -74.01184097, 40.70515196 ], [ -74.01183154, 40.70527549 ], [ -74.01173551, 40.70527148 ], [ -74.01167542, 40.70526868 ], [ -74.01164748, 40.70562968 ], [ -74.01157723, 40.70562988 ], [ -74.01156861, 40.70563002 ], [ -74.01163975, 40.70504546 ], [ -74.01232014, 40.70507147 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01472151, 40.70491811 ], [ -74.01464596, 40.70508938 ], [ -74.01462629, 40.70513419 ], [ -74.01454275, 40.70511492 ], [ -74.01449109, 40.705103 ], [ -74.01451328, 40.70504736 ], [ -74.01453269, 40.70505186 ], [ -74.01454122, 40.70503061 ], [ -74.01443702, 40.7050065 ], [ -74.01445642, 40.70495802 ], [ -74.0143311, 40.70492901 ], [ -74.01430739, 40.70498818 ], [ -74.01434692, 40.70499738 ], [ -74.01431691, 40.70507249 ], [ -74.0142534, 40.70505506 ], [ -74.01414974, 40.70502659 ], [ -74.01417174, 40.70497232 ], [ -74.01423328, 40.70482018 ], [ -74.01423912, 40.70481807 ], [ -74.01471945, 40.70491539 ], [ -74.01472151, 40.70491811 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00616757, 40.70485941 ], [ -74.00616138, 40.70485525 ], [ -74.0061965, 40.70482406 ], [ -74.00618572, 40.70481719 ], [ -74.00624474, 40.7047655 ], [ -74.00625453, 40.70475699 ], [ -74.00627699, 40.70473737 ], [ -74.00629064, 40.70472559 ], [ -74.00631113, 40.70470782 ], [ -74.00631427, 40.70470489 ], [ -74.00656598, 40.70486622 ], [ -74.00623414, 40.70509701 ], [ -74.00607765, 40.70500262 ], [ -74.00621321, 40.70489142 ], [ -74.00616757, 40.70485941 ] ] ] } }, { "type": "Feature", "properties": { "height": 104.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01303178, 40.70547959 ], [ -74.01275591, 40.70539228 ], [ -74.01267317, 40.70536879 ], [ -74.01276274, 40.70519997 ], [ -74.01284152, 40.7052249 ], [ -74.01312116, 40.70530696 ], [ -74.01320965, 40.70533426 ], [ -74.01312098, 40.70550628 ], [ -74.01303178, 40.70547959 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01133747, 40.70545521 ], [ -74.01130809, 40.7056292 ], [ -74.01084124, 40.7056213 ], [ -74.0108063, 40.70544908 ], [ -74.01101174, 40.70544969 ], [ -74.01122482, 40.7054533 ], [ -74.01127692, 40.70545419 ], [ -74.01133747, 40.70545521 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01485662, 40.70109048 ], [ -74.01482464, 40.70119202 ], [ -74.01403035, 40.70104716 ], [ -74.01406224, 40.70094576 ], [ -74.01485662, 40.70109048 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01450152, 40.70556042 ], [ -74.014431, 40.70572052 ], [ -74.01441761, 40.70571698 ], [ -74.014264, 40.70567748 ], [ -74.01419779, 40.70576546 ], [ -74.01414785, 40.70577411 ], [ -74.01402523, 40.70572032 ], [ -74.01400915, 40.70567871 ], [ -74.01416357, 40.70548217 ], [ -74.01432212, 40.70551888 ], [ -74.01450152, 40.70556042 ] ] ] } }, { "type": "Feature", "properties": { "height": 81.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00948002, 40.70514488 ], [ -74.00912213, 40.70521536 ], [ -74.00905907, 40.70500357 ], [ -74.0094025, 40.70492186 ], [ -74.00942702, 40.70499227 ], [ -74.00945155, 40.70506296 ], [ -74.00948002, 40.70514488 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01200132, 40.70562471 ], [ -74.01199647, 40.70572651 ], [ -74.01193287, 40.70571977 ], [ -74.01194177, 40.70586836 ], [ -74.01171647, 40.7058766 ], [ -74.01161819, 40.70586046 ], [ -74.0115863, 40.70585522 ], [ -74.01154462, 40.70584841 ], [ -74.0115545, 40.70578167 ], [ -74.01175959, 40.70578086 ], [ -74.01177719, 40.70575648 ], [ -74.01177719, 40.70572978 ], [ -74.01175887, 40.70570697 ], [ -74.01156537, 40.70570908 ], [ -74.01157723, 40.70562988 ], [ -74.01164748, 40.70562968 ], [ -74.01179318, 40.7056275 ], [ -74.01200132, 40.70562471 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00470341, 40.70563792 ], [ -74.00455788, 40.70573979 ], [ -74.0045524, 40.7057353 ], [ -74.00453498, 40.70574749 ], [ -74.00464008, 40.70583438 ], [ -74.00459615, 40.70586516 ], [ -74.0044791, 40.70576846 ], [ -74.00442933, 40.7058034 ], [ -74.00424877, 40.70565406 ], [ -74.00434822, 40.70559127 ], [ -74.00451755, 40.70548422 ], [ -74.00470341, 40.70563792 ] ] ] } }, { "type": "Feature", "properties": { "height": 143.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00820001, 40.70509919 ], [ -74.00791174, 40.70530982 ], [ -74.00784168, 40.70531009 ], [ -74.00775382, 40.7052409 ], [ -74.00775777, 40.70518887 ], [ -74.00804631, 40.70497811 ], [ -74.00811153, 40.70497926 ], [ -74.00819992, 40.70504879 ], [ -74.00820001, 40.70509919 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01104103, 40.70498771 ], [ -74.01067739, 40.7050208 ], [ -74.0105995, 40.7048795 ], [ -74.01056591, 40.70489707 ], [ -74.01043942, 40.70475467 ], [ -74.01050392, 40.70471177 ], [ -74.01056402, 40.70479628 ], [ -74.01060417, 40.7048526 ], [ -74.01062987, 40.70485028 ], [ -74.01062897, 40.70484477 ], [ -74.01072042, 40.70483646 ], [ -74.01072275, 40.7048509 ], [ -74.01101533, 40.70482427 ], [ -74.01104103, 40.70498771 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01069931, 40.70535898 ], [ -74.01058172, 40.70536797 ], [ -74.0106313, 40.70554946 ], [ -74.0102921, 40.7055549 ], [ -74.01029363, 40.70549899 ], [ -74.01026551, 40.7054787 ], [ -74.01028132, 40.70540992 ], [ -74.01032067, 40.7054104 ], [ -74.01043763, 40.70538697 ], [ -74.01044922, 40.70535789 ], [ -74.01056698, 40.7053517 ], [ -74.01056483, 40.70533208 ], [ -74.01061603, 40.7053344 ], [ -74.0106092, 40.70528721 ], [ -74.01059124, 40.70522728 ], [ -74.01054524, 40.70522748 ], [ -74.01040834, 40.70523321 ], [ -74.01031312, 40.70525268 ], [ -74.01029614, 40.7052076 ], [ -74.0105562, 40.70518799 ], [ -74.01055881, 40.7052138 ], [ -74.01066364, 40.70521346 ], [ -74.01069931, 40.70535898 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0124229, 40.70353691 ], [ -74.01174512, 40.70353908 ], [ -74.0117462, 40.70347882 ], [ -74.01234484, 40.70333996 ], [ -74.01232041, 40.70337591 ], [ -74.012377, 40.7035177 ], [ -74.0124229, 40.70353691 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01023649, 40.70474241 ], [ -74.01002701, 40.70497967 ], [ -74.00997311, 40.70498458 ], [ -74.00983845, 40.70476856 ], [ -74.01005243, 40.70463236 ], [ -74.01005063, 40.70462651 ], [ -74.01005189, 40.70462058 ], [ -74.01005369, 40.70461786 ], [ -74.01005917, 40.7046135 ], [ -74.01006653, 40.70461119 ], [ -74.01007049, 40.70461091 ], [ -74.01007821, 40.704612 ], [ -74.01008477, 40.70461541 ], [ -74.01008908, 40.70462052 ], [ -74.01009025, 40.70462338 ], [ -74.01009007, 40.70462937 ], [ -74.01008881, 40.7046323 ], [ -74.01023649, 40.70474241 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0135475, 40.70056996 ], [ -74.01333272, 40.70059148 ], [ -74.01294321, 40.70063071 ], [ -74.01284143, 40.70064072 ], [ -74.01239254, 40.70074397 ], [ -74.01236137, 40.70067968 ], [ -74.01281223, 40.70057902 ], [ -74.01289982, 40.70056431 ], [ -74.01353951, 40.70051541 ], [ -74.0135475, 40.70056996 ] ] ] } }, { "type": "Feature", "properties": { "height": 150.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01044922, 40.70535789 ], [ -74.01043763, 40.70538697 ], [ -74.01032067, 40.7054104 ], [ -74.01028132, 40.70540992 ], [ -74.01026551, 40.7054787 ], [ -74.01024242, 40.70553161 ], [ -74.0101755, 40.70556526 ], [ -74.01012663, 40.70552801 ], [ -74.01012358, 40.7054644 ], [ -74.01016068, 40.70532487 ], [ -74.01020317, 40.70525479 ], [ -74.01022113, 40.70526562 ], [ -74.01031312, 40.70525268 ], [ -74.01040834, 40.70523321 ], [ -74.01054524, 40.70522748 ], [ -74.01056483, 40.70533208 ], [ -74.01056698, 40.7053517 ], [ -74.01044922, 40.70535789 ] ] ] } }, { "type": "Feature", "properties": { "height": 104.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00889684, 40.70556321 ], [ -74.00881437, 40.70573938 ], [ -74.00878814, 40.70578596 ], [ -74.00874547, 40.70579577 ], [ -74.00852898, 40.70569301 ], [ -74.0085367, 40.70568252 ], [ -74.00854542, 40.70567081 ], [ -74.00858054, 40.70562328 ], [ -74.00863615, 40.70554809 ], [ -74.00868358, 40.70556839 ], [ -74.00870199, 40.70553468 ], [ -74.00869894, 40.70551922 ], [ -74.00869633, 40.70550601 ], [ -74.00869103, 40.70547952 ], [ -74.00888264, 40.70546277 ], [ -74.00889684, 40.70556321 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01095452, 40.70353711 ], [ -74.01070658, 40.70359207 ], [ -74.01061927, 40.70332089 ], [ -74.01086244, 40.70325946 ], [ -74.01089155, 40.70334697 ], [ -74.01090358, 40.70338368 ], [ -74.01095452, 40.70353711 ] ] ] } }, { "type": "Feature", "properties": { "height": 41.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01014783, 40.70395722 ], [ -74.00985552, 40.70367202 ], [ -74.00999557, 40.70358117 ], [ -74.01011423, 40.70368536 ], [ -74.01031393, 40.70386086 ], [ -74.01028491, 40.70387966 ], [ -74.01028015, 40.70387509 ], [ -74.01015484, 40.70396396 ], [ -74.01014783, 40.70395722 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00753544, 40.70584078 ], [ -74.00741102, 40.70596057 ], [ -74.00711224, 40.70578406 ], [ -74.00713398, 40.70576111 ], [ -74.00704298, 40.70570806 ], [ -74.00712221, 40.705629 ], [ -74.00713973, 40.70564098 ], [ -74.00716174, 40.70561946 ], [ -74.00726657, 40.70568116 ], [ -74.00731248, 40.7057086 ], [ -74.00731922, 40.70571262 ], [ -74.00735623, 40.70573462 ], [ -74.00747274, 40.70580367 ], [ -74.00753544, 40.70584078 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00870199, 40.70553468 ], [ -74.00860569, 40.70553441 ], [ -74.00861423, 40.70554476 ], [ -74.00855233, 40.70560707 ], [ -74.00858054, 40.70562328 ], [ -74.00854542, 40.70567081 ], [ -74.0085367, 40.70568252 ], [ -74.00852898, 40.70569301 ], [ -74.00849601, 40.70573748 ], [ -74.00848011, 40.70575906 ], [ -74.0084758, 40.70576492 ], [ -74.00831617, 40.70567292 ], [ -74.00847274, 40.70542409 ], [ -74.0086754, 40.7054008 ], [ -74.00868223, 40.70543498 ], [ -74.00869103, 40.70547952 ], [ -74.00869633, 40.70550601 ], [ -74.00869894, 40.70551922 ], [ -74.00870199, 40.70553468 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00505735, 40.70561217 ], [ -74.00491155, 40.70571269 ], [ -74.00457819, 40.70544751 ], [ -74.00472497, 40.70535776 ], [ -74.00505735, 40.70561217 ] ] ] } }, { "type": "Feature", "properties": { "height": 120.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01312116, 40.70530696 ], [ -74.01303178, 40.70547959 ], [ -74.01299019, 40.705493 ], [ -74.01277325, 40.70542647 ], [ -74.01275591, 40.70539228 ], [ -74.01284152, 40.7052249 ], [ -74.01288482, 40.70521019 ], [ -74.01289407, 40.70521257 ], [ -74.01306897, 40.70526392 ], [ -74.0131032, 40.705274 ], [ -74.01312116, 40.70530696 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00875778, 40.70528462 ], [ -74.00834671, 40.70532916 ], [ -74.0083344, 40.70532807 ], [ -74.00832281, 40.70532487 ], [ -74.00831751, 40.70532248 ], [ -74.00830808, 40.70531649 ], [ -74.00830413, 40.70531288 ], [ -74.00829811, 40.70530471 ], [ -74.00829604, 40.70530021 ], [ -74.00829398, 40.70529102 ], [ -74.00829497, 40.70528156 ], [ -74.00829883, 40.7052727 ], [ -74.00830521, 40.7052646 ], [ -74.00830934, 40.70526106 ], [ -74.00846115, 40.70516068 ], [ -74.00865519, 40.70506139 ], [ -74.00875778, 40.70528462 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01354292, 40.70285331 ], [ -74.01354274, 40.70276076 ], [ -74.01357769, 40.70275939 ], [ -74.01356044, 40.70250619 ], [ -74.01356044, 40.70246131 ], [ -74.01363401, 40.70246118 ], [ -74.01367363, 40.70246622 ], [ -74.01373822, 40.70249577 ], [ -74.01372429, 40.70252676 ], [ -74.01384395, 40.7025683 ], [ -74.01376023, 40.70272248 ], [ -74.01364821, 40.70270907 ], [ -74.01364839, 40.70285869 ], [ -74.01363545, 40.70285869 ], [ -74.01354292, 40.70285331 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01137322, 40.70143249 ], [ -74.01143592, 40.70134641 ], [ -74.01227863, 40.70115552 ], [ -74.01230469, 40.70122158 ], [ -74.01137322, 40.70143249 ] ] ] } }, { "type": "Feature", "properties": { "height": 96.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01214802, 40.70541517 ], [ -74.0121323, 40.70563839 ], [ -74.01200132, 40.70562471 ], [ -74.01179318, 40.7056275 ], [ -74.01179552, 40.70559188 ], [ -74.01209744, 40.70560448 ], [ -74.01212044, 40.70528762 ], [ -74.01183154, 40.70527549 ], [ -74.01184097, 40.70515196 ], [ -74.01188427, 40.70515339 ], [ -74.01193027, 40.70515496 ], [ -74.01216608, 40.70516265 ], [ -74.01214802, 40.70541517 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01133747, 40.70545521 ], [ -74.01127692, 40.70545419 ], [ -74.01134358, 40.70517266 ], [ -74.01066077, 40.70520127 ], [ -74.01064747, 40.7051476 ], [ -74.01141338, 40.70510538 ], [ -74.01133747, 40.70545521 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00838093, 40.70363116 ], [ -74.00828437, 40.7036949 ], [ -74.00788165, 40.70334159 ], [ -74.00797813, 40.70327792 ], [ -74.00838093, 40.70363116 ] ] ] } }, { "type": "Feature", "properties": { "height": 120.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01195794, 40.70446246 ], [ -74.01195587, 40.7044835 ], [ -74.0118363, 40.70448118 ], [ -74.01184133, 40.70440151 ], [ -74.0118505, 40.70425748 ], [ -74.01185535, 40.70418209 ], [ -74.01204768, 40.7041859 ], [ -74.01204831, 40.70421559 ], [ -74.0120492, 40.7042619 ], [ -74.01205019, 40.7043159 ], [ -74.0120519, 40.70441356 ], [ -74.01205352, 40.70446607 ], [ -74.01195794, 40.70446246 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00491155, 40.70571269 ], [ -74.00505735, 40.70561217 ], [ -74.00532639, 40.70581817 ], [ -74.00517601, 40.70592318 ], [ -74.00491155, 40.70571269 ] ] ] } }, { "type": "Feature", "properties": { "height": 139.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01310625, 40.7053092 ], [ -74.01302325, 40.70546699 ], [ -74.01298201, 40.70547829 ], [ -74.01278771, 40.70541939 ], [ -74.01277064, 40.70538908 ], [ -74.01285014, 40.70523368 ], [ -74.01289039, 40.7052219 ], [ -74.01309152, 40.70528176 ], [ -74.01310625, 40.7053092 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0085367, 40.70568252 ], [ -74.00854542, 40.70567081 ], [ -74.00858054, 40.70562328 ], [ -74.00863615, 40.70554809 ], [ -74.00868358, 40.70556839 ], [ -74.00870199, 40.70553468 ], [ -74.00869894, 40.70551922 ], [ -74.00869633, 40.70550601 ], [ -74.00886513, 40.70548851 ], [ -74.00887501, 40.70555572 ], [ -74.00877251, 40.7057626 ], [ -74.00873011, 40.70577248 ], [ -74.0085367, 40.70568252 ] ] ] } }, { "type": "Feature", "properties": { "height": 158.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01068152, 40.7024067 ], [ -74.01041391, 40.70245157 ], [ -74.01035525, 40.70225047 ], [ -74.01062268, 40.70220559 ], [ -74.01068152, 40.7024067 ] ] ] } }, { "type": "Feature", "properties": { "height": 214.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00979497, 40.70547707 ], [ -74.00979075, 40.70550308 ], [ -74.0097841, 40.70550662 ], [ -74.00977835, 40.70552739 ], [ -74.00978249, 40.70553257 ], [ -74.00977269, 40.7055577 ], [ -74.00976353, 40.70556049 ], [ -74.00974161, 40.70558337 ], [ -74.00969804, 40.7056068 ], [ -74.00966849, 40.70560829 ], [ -74.00966238, 40.70561388 ], [ -74.00962232, 40.70561129 ], [ -74.00959339, 40.70560727 ], [ -74.00955521, 40.70559706 ], [ -74.0095527, 40.70559011 ], [ -74.00952682, 40.70557956 ], [ -74.00949979, 40.70554428 ], [ -74.00949449, 40.70551929 ], [ -74.00948793, 40.70551432 ], [ -74.00949215, 40.70548817 ], [ -74.00950023, 40.70545882 ], [ -74.00950994, 40.70543362 ], [ -74.0095191, 40.70543076 ], [ -74.00954165, 40.7054074 ], [ -74.00958522, 40.70538411 ], [ -74.00961477, 40.70538261 ], [ -74.00962088, 40.70537696 ], [ -74.00966112, 40.70537969 ], [ -74.00969005, 40.70538391 ], [ -74.00972814, 40.70539405 ], [ -74.00973065, 40.70540107 ], [ -74.0097567, 40.70541176 ], [ -74.00978329, 40.70544697 ], [ -74.0097885, 40.70547196 ], [ -74.00979497, 40.70547707 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01289739, 40.70490238 ], [ -74.01268018, 40.70492199 ], [ -74.0126341, 40.70462937 ], [ -74.01216293, 40.70467207 ], [ -74.01215494, 40.70462181 ], [ -74.01270264, 40.70457216 ], [ -74.01271063, 40.70462297 ], [ -74.01275142, 40.70488222 ], [ -74.01289218, 40.70486949 ], [ -74.01289739, 40.70490238 ] ] ] } }, { "type": "Feature", "properties": { "height": 102.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01361901, 40.70582301 ], [ -74.01354634, 40.70578869 ], [ -74.01375133, 40.70553951 ], [ -74.01382589, 40.70557472 ], [ -74.01391123, 40.70561497 ], [ -74.01370624, 40.70586428 ], [ -74.01361901, 40.70582301 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00847274, 40.70542409 ], [ -74.00831617, 40.70567292 ], [ -74.00805134, 40.70552031 ], [ -74.00810479, 40.70546651 ], [ -74.00847274, 40.70542409 ] ] ] } }, { "type": "Feature", "properties": { "height": 94.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01433137, 40.70549579 ], [ -74.01432212, 40.70551888 ], [ -74.01416357, 40.70548217 ], [ -74.0140776, 40.70546229 ], [ -74.01412647, 40.7053408 ], [ -74.01418333, 40.70535388 ], [ -74.01419241, 40.70533127 ], [ -74.01422385, 40.70525316 ], [ -74.01434772, 40.7052819 ], [ -74.01431556, 40.70536171 ], [ -74.01430721, 40.70538248 ], [ -74.01437099, 40.70539726 ], [ -74.01442624, 40.70541006 ], [ -74.01438662, 40.70550846 ], [ -74.01433137, 40.70549579 ] ] ] } }, { "type": "Feature", "properties": { "height": 169.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00557891, 40.70514508 ], [ -74.00556759, 40.70533958 ], [ -74.00553489, 40.70536416 ], [ -74.00538559, 40.70535966 ], [ -74.00535128, 40.70533236 ], [ -74.00536268, 40.7051378 ], [ -74.00539871, 40.70511328 ], [ -74.00554792, 40.70511778 ], [ -74.00557891, 40.70514508 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01241473, 40.70193311 ], [ -74.0123858, 40.70193611 ], [ -74.0123364, 40.70176599 ], [ -74.01154767, 40.70189777 ], [ -74.01159717, 40.70206789 ], [ -74.01156897, 40.70207436 ], [ -74.01150554, 40.70185609 ], [ -74.01235122, 40.70171471 ], [ -74.01241473, 40.70193311 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01231789, 40.70513487 ], [ -74.01229741, 40.7054202 ], [ -74.01222141, 40.70541769 ], [ -74.01214802, 40.70541517 ], [ -74.01216608, 40.70516265 ], [ -74.01193027, 40.70515496 ], [ -74.01193054, 40.70512179 ], [ -74.01231789, 40.70513487 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01127692, 40.70545419 ], [ -74.01122482, 40.7054533 ], [ -74.01127037, 40.70521121 ], [ -74.01077144, 40.70523389 ], [ -74.01078249, 40.70535449 ], [ -74.01069931, 40.70535898 ], [ -74.01066364, 40.70521346 ], [ -74.01066077, 40.70520127 ], [ -74.01134358, 40.70517266 ], [ -74.01127692, 40.70545419 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00996233, 40.70455248 ], [ -74.00976712, 40.70470387 ], [ -74.00961549, 40.70454772 ], [ -74.00978195, 40.70441867 ], [ -74.00996233, 40.70455248 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01014783, 40.70395722 ], [ -74.01004048, 40.70402668 ], [ -74.00979102, 40.70380468 ], [ -74.00985552, 40.70367202 ], [ -74.01014783, 40.70395722 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01266931, 40.70396982 ], [ -74.01266877, 40.70396151 ], [ -74.01266751, 40.70393686 ], [ -74.01266707, 40.70393032 ], [ -74.01297501, 40.70392658 ], [ -74.01294572, 40.70370961 ], [ -74.01262017, 40.70370382 ], [ -74.01261901, 40.70372091 ], [ -74.01261793, 40.70373862 ], [ -74.01251633, 40.70373698 ], [ -74.01251498, 40.70375646 ], [ -74.01251444, 40.70376559 ], [ -74.01243413, 40.70377192 ], [ -74.01242308, 40.7036902 ], [ -74.0126208, 40.70369326 ], [ -74.01262251, 40.70366759 ], [ -74.0129874, 40.70367338 ], [ -74.01302693, 40.70396539 ], [ -74.01266931, 40.70396982 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00623225, 40.70514331 ], [ -74.00598414, 40.70500718 ], [ -74.00616757, 40.70485941 ], [ -74.00621321, 40.70489142 ], [ -74.00607765, 40.70500262 ], [ -74.00623414, 40.70509701 ], [ -74.00656598, 40.70486622 ], [ -74.00631427, 40.70470489 ], [ -74.00632559, 40.70469508 ], [ -74.00633565, 40.7046865 ], [ -74.00662338, 40.70487459 ], [ -74.00623225, 40.70514331 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00854542, 40.70567081 ], [ -74.00858054, 40.70562328 ], [ -74.00863615, 40.70554809 ], [ -74.00868358, 40.70556839 ], [ -74.00870199, 40.70553468 ], [ -74.00869894, 40.70551922 ], [ -74.0088495, 40.70550376 ], [ -74.00885695, 40.70555388 ], [ -74.00875895, 40.70575157 ], [ -74.00873262, 40.70575777 ], [ -74.00854542, 40.70567081 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00769022, 40.70548878 ], [ -74.00759078, 40.70558807 ], [ -74.00742755, 40.70548306 ], [ -74.00740473, 40.70549831 ], [ -74.00729712, 40.70542756 ], [ -74.00742638, 40.70533018 ], [ -74.00743914, 40.70532916 ], [ -74.00769022, 40.70548878 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01228914, 40.70555068 ], [ -74.01229741, 40.7054202 ], [ -74.01231789, 40.70513487 ], [ -74.01231951, 40.70510388 ], [ -74.01232014, 40.70507147 ], [ -74.01248408, 40.70507848 ], [ -74.01248049, 40.7051442 ], [ -74.01228914, 40.70555068 ] ] ] } }, { "type": "Feature", "properties": { "height": 220.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00977629, 40.7054819 ], [ -74.00977413, 40.70549552 ], [ -74.00976317, 40.70553447 ], [ -74.00975814, 40.70554762 ], [ -74.00975221, 40.70554939 ], [ -74.00972383, 40.70557901 ], [ -74.00972383, 40.70558718 ], [ -74.00970748, 40.70559501 ], [ -74.00970029, 40.70559311 ], [ -74.00965969, 40.70559529 ], [ -74.00965475, 40.70559992 ], [ -74.00963337, 40.70559849 ], [ -74.00963004, 40.70559372 ], [ -74.00959582, 40.70558868 ], [ -74.00959007, 40.70559209 ], [ -74.00956994, 40.70558671 ], [ -74.00956779, 40.70558099 ], [ -74.00953195, 40.70556641 ], [ -74.0095244, 40.7055658 ], [ -74.00951371, 40.70555368 ], [ -74.0095182, 40.70554619 ], [ -74.0095111, 40.70551289 ], [ -74.00950661, 40.70550941 ], [ -74.00950877, 40.70549586 ], [ -74.0095147, 40.70549266 ], [ -74.00952323, 40.7054614 ], [ -74.00951955, 40.70545677 ], [ -74.00952449, 40.7054437 ], [ -74.00953042, 40.70544179 ], [ -74.00955943, 40.70541176 ], [ -74.00955952, 40.70540359 ], [ -74.00957578, 40.70539589 ], [ -74.00958297, 40.70539766 ], [ -74.00962357, 40.70539569 ], [ -74.0096286, 40.70539106 ], [ -74.00964989, 40.70539249 ], [ -74.0096534, 40.70539739 ], [ -74.00968753, 40.70540236 ], [ -74.00969319, 40.70539896 ], [ -74.0097134, 40.70540441 ], [ -74.00971547, 40.70541019 ], [ -74.00975122, 40.7054249 ], [ -74.00975877, 40.70542552 ], [ -74.00976937, 40.70543771 ], [ -74.00976488, 40.7054452 ], [ -74.0097718, 40.7054785 ], [ -74.00977629, 40.7054819 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.012203, 40.7032278 ], [ -74.01212888, 40.70306892 ], [ -74.01221144, 40.70304658 ], [ -74.01222303, 40.7030715 ], [ -74.01230648, 40.70304889 ], [ -74.01230073, 40.7030365 ], [ -74.01239515, 40.70301096 ], [ -74.01247078, 40.7031554 ], [ -74.012203, 40.7032278 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01518594, 40.70134607 ], [ -74.01500861, 40.70155916 ], [ -74.01486408, 40.70149017 ], [ -74.0150414, 40.70127708 ], [ -74.01518594, 40.70134607 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00766282, 40.70574258 ], [ -74.00748837, 40.70565916 ], [ -74.00754748, 40.70560019 ], [ -74.00756733, 40.7056117 ], [ -74.00759078, 40.70558807 ], [ -74.00769022, 40.70548878 ], [ -74.00782892, 40.70557697 ], [ -74.00783449, 40.70558276 ], [ -74.00767082, 40.7057464 ], [ -74.00766282, 40.70574258 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00932857, 40.70156679 ], [ -74.00925877, 40.70159771 ], [ -74.00924421, 40.7015798 ], [ -74.00913372, 40.70162849 ], [ -74.00902053, 40.7014709 ], [ -74.0091189, 40.70142827 ], [ -74.00910066, 40.7013996 ], [ -74.00918591, 40.70136057 ], [ -74.00932857, 40.70156679 ] ] ] } }, { "type": "Feature", "properties": { "height": 146.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00817369, 40.70507297 ], [ -74.00787833, 40.70528877 ], [ -74.00778319, 40.70521386 ], [ -74.00807865, 40.70499819 ], [ -74.00817369, 40.70507297 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0131809, 40.70074792 ], [ -74.01283864, 40.7007725 ], [ -74.01282319, 40.70064917 ], [ -74.01316554, 40.70062458 ], [ -74.0131809, 40.70074792 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00735838, 40.70483768 ], [ -74.007307, 40.70487357 ], [ -74.00729361, 40.70488318 ], [ -74.00728023, 40.70489291 ], [ -74.00726684, 40.70490258 ], [ -74.00725337, 40.70491212 ], [ -74.00719713, 40.7048667 ], [ -74.00710182, 40.70478988 ], [ -74.00720953, 40.70471259 ], [ -74.00726891, 40.70466989 ], [ -74.00728158, 40.7046801 ], [ -74.00729424, 40.70469032 ], [ -74.00730691, 40.70470046 ], [ -74.00731948, 40.70471068 ], [ -74.00736413, 40.7047465 ], [ -74.00742099, 40.70479267 ], [ -74.00746124, 40.70482481 ], [ -74.00739863, 40.70486976 ], [ -74.00735838, 40.70483768 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00862698, 40.704894 ], [ -74.00851137, 40.70497586 ], [ -74.00844489, 40.70492152 ], [ -74.00846349, 40.7049083 ], [ -74.00838165, 40.70484136 ], [ -74.00840124, 40.7048274 ], [ -74.00832614, 40.70476598 ], [ -74.00833817, 40.70475746 ], [ -74.00831167, 40.70473588 ], [ -74.00833018, 40.7047228 ], [ -74.00831392, 40.70470952 ], [ -74.00838372, 40.70466008 ], [ -74.00846933, 40.70474241 ], [ -74.00862698, 40.704894 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01219024, 40.70435459 ], [ -74.01216967, 40.70410357 ], [ -74.01233541, 40.70410718 ], [ -74.0123425, 40.70419026 ], [ -74.01235113, 40.70424631 ], [ -74.01236559, 40.70433872 ], [ -74.01219024, 40.70435459 ] ] ] } }, { "type": "Feature", "properties": { "height": 165.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01404948, 40.7029148 ], [ -74.01404445, 40.70302206 ], [ -74.01381017, 40.70301566 ], [ -74.01381871, 40.70283642 ], [ -74.01395965, 40.7028386 ], [ -74.01398714, 40.70284466 ], [ -74.01401454, 40.70285726 ], [ -74.0140343, 40.70287537 ], [ -74.01404364, 40.70289369 ], [ -74.01404948, 40.7029148 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01239515, 40.70301096 ], [ -74.01230073, 40.7030365 ], [ -74.01230648, 40.70304889 ], [ -74.01222303, 40.7030715 ], [ -74.01221144, 40.70304658 ], [ -74.01212888, 40.70306892 ], [ -74.0120704, 40.70294361 ], [ -74.01232894, 40.7028753 ], [ -74.01239515, 40.70301096 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01017343, 40.70438898 ], [ -74.01002404, 40.70450468 ], [ -74.00984348, 40.704371 ], [ -74.0099811, 40.70426429 ], [ -74.0100995, 40.70435506 ], [ -74.01011441, 40.70434376 ], [ -74.01017343, 40.70438898 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0108478, 40.70578167 ], [ -74.01076857, 40.70575259 ], [ -74.01077027, 40.70571187 ], [ -74.01074593, 40.7057148 ], [ -74.01068664, 40.70542177 ], [ -74.01079812, 40.7054087 ], [ -74.0108063, 40.70544908 ], [ -74.01084124, 40.7056213 ], [ -74.01084528, 40.70564146 ], [ -74.0108575, 40.70570166 ], [ -74.0108478, 40.70578167 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00639754, 40.70335419 ], [ -74.00629675, 40.70342706 ], [ -74.00607451, 40.70322541 ], [ -74.00619372, 40.70314771 ], [ -74.00639754, 40.70335419 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01060723, 40.70450046 ], [ -74.01048353, 40.70429908 ], [ -74.01065601, 40.70423779 ], [ -74.01075779, 40.70441887 ], [ -74.01066158, 40.70444856 ], [ -74.01067802, 40.70447526 ], [ -74.01060723, 40.70450046 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00766282, 40.70574258 ], [ -74.00755359, 40.70585161 ], [ -74.00753544, 40.70584078 ], [ -74.00747274, 40.70580367 ], [ -74.00735623, 40.70573462 ], [ -74.00731922, 40.70571262 ], [ -74.00731248, 40.7057086 ], [ -74.00740554, 40.70561858 ], [ -74.00743734, 40.70563778 ], [ -74.00748235, 40.70566509 ], [ -74.00748837, 40.70565916 ], [ -74.00766282, 40.70574258 ] ] ] } }, { "type": "Feature", "properties": { "height": 31.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00626513, 40.70516129 ], [ -74.00617162, 40.70523382 ], [ -74.00586035, 40.70504729 ], [ -74.00587401, 40.7050347 ], [ -74.00589251, 40.70501767 ], [ -74.00590805, 40.70500337 ], [ -74.00592817, 40.70498471 ], [ -74.00593392, 40.70497947 ], [ -74.00598414, 40.70500718 ], [ -74.00623225, 40.70514331 ], [ -74.00626513, 40.70516129 ] ] ] } }, { "type": "Feature", "properties": { "height": 118.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00597318, 40.70492022 ], [ -74.00587427, 40.70485607 ], [ -74.00581741, 40.70481998 ], [ -74.0058449, 40.70480241 ], [ -74.00598171, 40.70471299 ], [ -74.00601019, 40.70469461 ], [ -74.00603462, 40.70471 ], [ -74.00615697, 40.70478736 ], [ -74.00597318, 40.70492022 ] ] ] } }, { "type": "Feature", "properties": { "height": 155.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01030683, 40.70531472 ], [ -74.01028132, 40.70540992 ], [ -74.01026551, 40.7054787 ], [ -74.01024242, 40.70553161 ], [ -74.0101755, 40.70556526 ], [ -74.01012663, 40.70552801 ], [ -74.01012358, 40.7054644 ], [ -74.01016068, 40.70532487 ], [ -74.01020317, 40.70525479 ], [ -74.01022113, 40.70526562 ], [ -74.0103089, 40.70530709 ], [ -74.01030683, 40.70531472 ] ] ] } }, { "type": "Feature", "properties": { "height": 87.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01293189, 40.70387618 ], [ -74.01259816, 40.70387087 ], [ -74.0125987, 40.70375816 ], [ -74.01261721, 40.7037585 ], [ -74.01291662, 40.7037632 ], [ -74.01293189, 40.70387618 ] ] ] } }, { "type": "Feature", "properties": { "height": 226.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00976389, 40.7054851 ], [ -74.00976299, 40.70549041 ], [ -74.0097576, 40.70549321 ], [ -74.00974691, 40.70553148 ], [ -74.00975042, 40.70553577 ], [ -74.00974844, 40.70554088 ], [ -74.00974449, 40.7055421 ], [ -74.00971197, 40.70557601 ], [ -74.00971197, 40.70558221 ], [ -74.00970604, 40.70558507 ], [ -74.00970182, 40.70558398 ], [ -74.00965385, 40.70558657 ], [ -74.00964953, 40.70559052 ], [ -74.00964091, 40.70558997 ], [ -74.00963777, 40.70558568 ], [ -74.00959267, 40.70557908 ], [ -74.00958782, 40.70558201 ], [ -74.00957965, 40.70557976 ], [ -74.00957794, 40.70557486 ], [ -74.00953554, 40.7055577 ], [ -74.00953114, 40.70555729 ], [ -74.00952718, 40.70555279 ], [ -74.00953042, 40.70554741 ], [ -74.00952224, 40.7055086 ], [ -74.00951901, 40.70550621 ], [ -74.00951991, 40.7055009 ], [ -74.0095253, 40.70549811 ], [ -74.00953581, 40.7054597 ], [ -74.0095323, 40.70545541 ], [ -74.00953419, 40.70545037 ], [ -74.00953787, 40.70544928 ], [ -74.00957129, 40.70541476 ], [ -74.00957129, 40.70540856 ], [ -74.0095774, 40.7054057 ], [ -74.00958162, 40.70540679 ], [ -74.0096295, 40.70540441 ], [ -74.00963381, 40.70540039 ], [ -74.00964262, 40.705401 ], [ -74.00964558, 40.70540536 ], [ -74.0096905, 40.70541196 ], [ -74.00969544, 40.7054091 ], [ -74.00970361, 40.70541128 ], [ -74.00970532, 40.70541625 ], [ -74.00974781, 40.70543369 ], [ -74.00975212, 40.70543396 ], [ -74.0097559, 40.70543839 ], [ -74.00975275, 40.70544377 ], [ -74.00976075, 40.70548272 ], [ -74.00976389, 40.7054851 ] ] ] } }, { "type": "Feature", "properties": { "height": 103.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00882605, 40.70527577 ], [ -74.00873469, 40.70503905 ], [ -74.00887384, 40.70500017 ], [ -74.00895343, 40.70525956 ], [ -74.00882605, 40.70527577 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00899978, 40.70554517 ], [ -74.00897005, 40.70555109 ], [ -74.00889684, 40.70556321 ], [ -74.00888264, 40.70546277 ], [ -74.00869103, 40.70547952 ], [ -74.00868223, 40.70543498 ], [ -74.0086754, 40.7054008 ], [ -74.00898047, 40.70537199 ], [ -74.00899978, 40.70554517 ] ] ] } }, { "type": "Feature", "properties": { "height": 143.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01306529, 40.70531717 ], [ -74.01300115, 40.70544057 ], [ -74.01297348, 40.70544956 ], [ -74.01281879, 40.70540338 ], [ -74.01280595, 40.70537989 ], [ -74.01286775, 40.70525827 ], [ -74.0128982, 40.705249 ], [ -74.01305352, 40.70529558 ], [ -74.01306529, 40.70531717 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01143592, 40.70134641 ], [ -74.01137322, 40.70143249 ], [ -74.01122392, 40.70105336 ], [ -74.01131618, 40.70103279 ], [ -74.01143592, 40.70134641 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00459615, 40.70586516 ], [ -74.0044791, 40.70576846 ], [ -74.00442933, 40.7058034 ], [ -74.00424877, 40.70565406 ], [ -74.00434822, 40.70559127 ], [ -74.00453498, 40.70574749 ], [ -74.00464008, 40.70583438 ], [ -74.00459615, 40.70586516 ] ] ] } }, { "type": "Feature", "properties": { "height": 133.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0124539, 40.70395886 ], [ -74.01220039, 40.70394932 ], [ -74.01221872, 40.7037901 ], [ -74.0122586, 40.70379269 ], [ -74.01226202, 40.70376286 ], [ -74.01234008, 40.70376811 ], [ -74.01234619, 40.70379936 ], [ -74.01235849, 40.70386672 ], [ -74.01244482, 40.7038725 ], [ -74.0124539, 40.70395886 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01188832, 40.70473771 ], [ -74.01188589, 40.70488658 ], [ -74.01164191, 40.70487391 ], [ -74.01165215, 40.70474487 ], [ -74.01188832, 40.70473771 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0094025, 40.70492186 ], [ -74.00905907, 40.70500357 ], [ -74.00912213, 40.70521536 ], [ -74.00906195, 40.70522776 ], [ -74.0089829, 40.70497061 ], [ -74.00938813, 40.70488052 ], [ -74.00939091, 40.70488849 ], [ -74.0094025, 40.70492186 ] ] ] } }, { "type": "Feature", "properties": { "height": 97.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01437099, 40.70539726 ], [ -74.01433137, 40.70549579 ], [ -74.01432212, 40.70551888 ], [ -74.01416357, 40.70548217 ], [ -74.0140776, 40.70546229 ], [ -74.01412647, 40.7053408 ], [ -74.01418333, 40.70535388 ], [ -74.01425259, 40.70536988 ], [ -74.01430721, 40.70538248 ], [ -74.01437099, 40.70539726 ] ] ] } }, { "type": "Feature", "properties": { "height": 64.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00634607, 40.70467731 ], [ -74.00633565, 40.7046865 ], [ -74.00632559, 40.70469508 ], [ -74.00608709, 40.70453437 ], [ -74.00597228, 40.70460976 ], [ -74.00592242, 40.70464238 ], [ -74.00591012, 40.70465041 ], [ -74.00577339, 40.70473976 ], [ -74.00576181, 40.70474732 ], [ -74.00571015, 40.70478109 ], [ -74.00561269, 40.70484477 ], [ -74.00574294, 40.70492519 ], [ -74.00572462, 40.70494229 ], [ -74.00556445, 40.70484341 ], [ -74.00568859, 40.7047623 ], [ -74.00567629, 40.70475072 ], [ -74.00573881, 40.70470979 ], [ -74.00575192, 40.70472089 ], [ -74.00588883, 40.70463162 ], [ -74.00587607, 40.7046199 ], [ -74.00593877, 40.70457877 ], [ -74.00595225, 40.70459042 ], [ -74.00608682, 40.70450298 ], [ -74.00634607, 40.70467731 ] ] ] } }, { "type": "Feature", "properties": { "height": 81.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00631113, 40.70470782 ], [ -74.00629064, 40.70472559 ], [ -74.00608601, 40.7045881 ], [ -74.0060066, 40.70464006 ], [ -74.00595584, 40.70467329 ], [ -74.00580789, 40.7047702 ], [ -74.00579693, 40.70477748 ], [ -74.00574483, 40.7048116 ], [ -74.00569785, 40.70484238 ], [ -74.00592817, 40.70498471 ], [ -74.00590805, 40.70500337 ], [ -74.00575821, 40.70491089 ], [ -74.00564709, 40.70484211 ], [ -74.005723, 40.70479247 ], [ -74.00571015, 40.70478109 ], [ -74.00576181, 40.70474732 ], [ -74.00577339, 40.70473976 ], [ -74.00578633, 40.7047512 ], [ -74.00592287, 40.70466158 ], [ -74.00591012, 40.70465041 ], [ -74.00592242, 40.70464238 ], [ -74.00597228, 40.70460976 ], [ -74.00598504, 40.70462106 ], [ -74.00608502, 40.70455568 ], [ -74.00631113, 40.70470782 ] ] ] } }, { "type": "Feature", "properties": { "height": 72.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01208945, 40.70473159 ], [ -74.01207463, 40.70489645 ], [ -74.01188589, 40.70488658 ], [ -74.01188832, 40.70473771 ], [ -74.01208945, 40.70473159 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0104158, 40.70462276 ], [ -74.01030692, 40.70469726 ], [ -74.01012861, 40.70454656 ], [ -74.0102338, 40.70446899 ], [ -74.0104158, 40.70462276 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01287512, 40.70414266 ], [ -74.0123425, 40.70419026 ], [ -74.01233541, 40.70410718 ], [ -74.01287071, 40.70411406 ], [ -74.01287512, 40.70414266 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01056591, 40.70489707 ], [ -74.01047652, 40.70494406 ], [ -74.01044571, 40.70491348 ], [ -74.01035992, 40.70496367 ], [ -74.01029282, 40.70488358 ], [ -74.01033935, 40.70483299 ], [ -74.01043942, 40.70475467 ], [ -74.01056591, 40.70489707 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0110563, 40.7035145 ], [ -74.01095452, 40.70353711 ], [ -74.01090358, 40.70338368 ], [ -74.01094284, 40.70337496 ], [ -74.01093071, 40.70333948 ], [ -74.01089155, 40.70334697 ], [ -74.01086244, 40.70325946 ], [ -74.01096602, 40.70323331 ], [ -74.01100869, 40.70335617 ], [ -74.01100177, 40.7033576 ], [ -74.01100707, 40.70337292 ], [ -74.01101165, 40.70338572 ], [ -74.0110563, 40.7035145 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01020317, 40.70525479 ], [ -74.01016068, 40.70532487 ], [ -74.01012358, 40.7054644 ], [ -74.01012663, 40.70552801 ], [ -74.0101755, 40.70556526 ], [ -74.01, 40.70558208 ], [ -74.01007677, 40.70536927 ], [ -74.0101075, 40.70529906 ], [ -74.01014217, 40.70521768 ], [ -74.01020317, 40.70525479 ] ] ] } }, { "type": "Feature", "properties": { "height": 122.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00613658, 40.70479158 ], [ -74.00597264, 40.70490687 ], [ -74.00583825, 40.7048208 ], [ -74.00601019, 40.70470741 ], [ -74.00613658, 40.70479158 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00626513, 40.70516129 ], [ -74.00623225, 40.70514331 ], [ -74.00662338, 40.70487459 ], [ -74.00633565, 40.7046865 ], [ -74.00634607, 40.70467731 ], [ -74.0063608, 40.70466451 ], [ -74.00668411, 40.70487242 ], [ -74.00626513, 40.70516129 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01199863, 40.70468446 ], [ -74.01166365, 40.70468998 ], [ -74.01167263, 40.70460567 ], [ -74.0117259, 40.70460492 ], [ -74.0119962, 40.70460036 ], [ -74.01199863, 40.70468446 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00627699, 40.70473737 ], [ -74.00625453, 40.70475699 ], [ -74.006087, 40.70464517 ], [ -74.00601019, 40.70469461 ], [ -74.00598171, 40.70471299 ], [ -74.0058449, 40.70480241 ], [ -74.00581741, 40.70481998 ], [ -74.00578238, 40.70484238 ], [ -74.00584041, 40.70487827 ], [ -74.00587427, 40.70485607 ], [ -74.00591218, 40.70488978 ], [ -74.00588613, 40.70490647 ], [ -74.00596572, 40.70495577 ], [ -74.0059403, 40.70497382 ], [ -74.00573369, 40.70484606 ], [ -74.00576252, 40.7048272 ], [ -74.00574483, 40.7048116 ], [ -74.00579693, 40.70477748 ], [ -74.00580789, 40.7047702 ], [ -74.00582577, 40.70478559 ], [ -74.00596258, 40.70469617 ], [ -74.00594461, 40.70468072 ], [ -74.00595584, 40.70467329 ], [ -74.0060066, 40.70464006 ], [ -74.00602438, 40.70465559 ], [ -74.00609059, 40.70461228 ], [ -74.00627699, 40.70473737 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01039118, 40.70505921 ], [ -74.01019823, 40.70508012 ], [ -74.01019257, 40.70508019 ], [ -74.0101817, 40.70507889 ], [ -74.01017155, 40.70507549 ], [ -74.01016696, 40.7050731 ], [ -74.01015933, 40.70506691 ], [ -74.01015403, 40.70505948 ], [ -74.01015241, 40.7050554 ], [ -74.01015151, 40.70505131 ], [ -74.01015178, 40.7050428 ], [ -74.01015304, 40.70503871 ], [ -74.01015762, 40.70503102 ], [ -74.01029282, 40.70488358 ], [ -74.01035992, 40.70496367 ], [ -74.01039118, 40.70505921 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01026335, 40.70431931 ], [ -74.01017343, 40.70438898 ], [ -74.01011441, 40.70434376 ], [ -74.0100995, 40.70435506 ], [ -74.0099811, 40.70426429 ], [ -74.01008351, 40.70418488 ], [ -74.01026335, 40.70431931 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01267021, 40.70398596 ], [ -74.01266958, 40.70397581 ], [ -74.01266931, 40.70396982 ], [ -74.01302693, 40.70396539 ], [ -74.0129874, 40.70367338 ], [ -74.01262251, 40.70366759 ], [ -74.0126208, 40.70369326 ], [ -74.01242308, 40.7036902 ], [ -74.01241958, 40.70366439 ], [ -74.01258703, 40.70366711 ], [ -74.01258828, 40.70364682 ], [ -74.01300914, 40.70365349 ], [ -74.01305343, 40.70398126 ], [ -74.01267021, 40.70398596 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01241769, 40.7049143 ], [ -74.01243413, 40.7047211 ], [ -74.01255235, 40.70471749 ], [ -74.01256654, 40.70492206 ], [ -74.01241769, 40.7049143 ] ] ] } }, { "type": "Feature", "properties": { "height": 153.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01044922, 40.70535789 ], [ -74.01043745, 40.70529742 ], [ -74.01030683, 40.70531472 ], [ -74.0103089, 40.70530709 ], [ -74.01022113, 40.70526562 ], [ -74.01031312, 40.70525268 ], [ -74.01040834, 40.70523321 ], [ -74.01054524, 40.70522748 ], [ -74.01056483, 40.70533208 ], [ -74.01056698, 40.7053517 ], [ -74.01044922, 40.70535789 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01179552, 40.70559188 ], [ -74.01179318, 40.7056275 ], [ -74.01164748, 40.70562968 ], [ -74.01167542, 40.70526868 ], [ -74.01173551, 40.70527148 ], [ -74.01171261, 40.70558848 ], [ -74.01179552, 40.70559188 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01125204, 40.70347112 ], [ -74.01121063, 40.70334377 ], [ -74.01119374, 40.70329201 ], [ -74.01118898, 40.7032773 ], [ -74.01121072, 40.70327152 ], [ -74.01123937, 40.70335991 ], [ -74.01143548, 40.70332286 ], [ -74.01144742, 40.70342767 ], [ -74.01125204, 40.70347112 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01134268, 40.70142357 ], [ -74.01119661, 40.70145612 ], [ -74.01113723, 40.70130139 ], [ -74.0112833, 40.70126891 ], [ -74.01134268, 40.70142357 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726657, 40.70568116 ], [ -74.00716174, 40.70561946 ], [ -74.00712374, 40.70559651 ], [ -74.00711305, 40.70558997 ], [ -74.00709544, 40.70557956 ], [ -74.00720477, 40.70549709 ], [ -74.00723073, 40.70551282 ], [ -74.00736503, 40.70559406 ], [ -74.00726657, 40.70568116 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00563047, 40.70546311 ], [ -74.00549438, 40.70555906 ], [ -74.00540338, 40.70555661 ], [ -74.00527537, 40.70545221 ], [ -74.00563047, 40.70546311 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0122409, 40.70564977 ], [ -74.01219473, 40.70574721 ], [ -74.01199647, 40.70572651 ], [ -74.01200132, 40.70562471 ], [ -74.0121323, 40.70563839 ], [ -74.01220147, 40.70564568 ], [ -74.0122409, 40.70564977 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00574447, 40.70538282 ], [ -74.00575615, 40.70511321 ], [ -74.00588245, 40.70521611 ], [ -74.00587931, 40.70528762 ], [ -74.00574447, 40.70538282 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00518392, 40.70509912 ], [ -74.00517215, 40.70536797 ], [ -74.00504585, 40.70526508 ], [ -74.0050489, 40.70519439 ], [ -74.00518392, 40.70509912 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00930332, 40.70501719 ], [ -74.00932749, 40.70508781 ], [ -74.00934258, 40.70513187 ], [ -74.009164, 40.70516701 ], [ -74.00912474, 40.7050524 ], [ -74.00930332, 40.70501719 ] ] ] } }, { "type": "Feature", "properties": { "height": 11.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0105209, 40.70417249 ], [ -74.01037268, 40.7039737 ], [ -74.01044508, 40.70392086 ], [ -74.01050482, 40.70399699 ], [ -74.01058612, 40.70414429 ], [ -74.0105209, 40.70417249 ] ] ] } }, { "type": "Feature", "properties": { "height": 97.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01431556, 40.70536171 ], [ -74.01430721, 40.70538248 ], [ -74.01428331, 40.70544179 ], [ -74.0142287, 40.70542919 ], [ -74.01415944, 40.70541319 ], [ -74.01418333, 40.70535388 ], [ -74.01419241, 40.70533127 ], [ -74.01422385, 40.70525316 ], [ -74.01434772, 40.7052819 ], [ -74.01431556, 40.70536171 ] ] ] } }, { "type": "Feature", "properties": { "height": 127.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0120519, 40.70441356 ], [ -74.0119309, 40.70441131 ], [ -74.01190332, 40.70441077 ], [ -74.01191293, 40.70425979 ], [ -74.01193862, 40.70425979 ], [ -74.0120492, 40.7042619 ], [ -74.01205019, 40.7043159 ], [ -74.0120519, 40.70441356 ] ] ] } }, { "type": "Feature", "properties": { "height": 1.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01004677, 40.70263041 ], [ -74.01004318, 40.70265459 ], [ -74.01003401, 40.70267788 ], [ -74.01001964, 40.70269967 ], [ -74.01000051, 40.70271921 ], [ -74.00997967, 40.70273692 ], [ -74.00994248, 40.7027045 ], [ -74.00995802, 40.70269048 ], [ -74.00997122, 40.70267706 ], [ -74.0099811, 40.70266208 ], [ -74.00998739, 40.70264601 ], [ -74.00998991, 40.70262932 ], [ -74.00998847, 40.7026125 ], [ -74.00998335, 40.70259615 ], [ -74.00997437, 40.7025809 ], [ -74.00996215, 40.70256687 ], [ -74.00994679, 40.70255482 ], [ -74.00992891, 40.70254487 ], [ -74.00990897, 40.70253752 ], [ -74.00988768, 40.70253289 ], [ -74.00986567, 40.70253112 ], [ -74.00984357, 40.70253228 ], [ -74.00982219, 40.70253636 ], [ -74.00980198, 40.70254331 ], [ -74.00978653, 40.70255032 ], [ -74.00977548, 40.70255727 ], [ -74.00973919, 40.70252478 ], [ -74.00975248, 40.70251648 ], [ -74.00977458, 40.70250551 ], [ -74.00980351, 40.7024957 ], [ -74.00983459, 40.70248971 ], [ -74.00986657, 40.70248801 ], [ -74.00989864, 40.70249046 ], [ -74.00992954, 40.70249727 ], [ -74.00995829, 40.70250796 ], [ -74.00998425, 40.70252226 ], [ -74.01000653, 40.7025399 ], [ -74.01002431, 40.70256006 ], [ -74.01003725, 40.7025824 ], [ -74.01004479, 40.7026061 ], [ -74.01004677, 40.70263041 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01143548, 40.70332286 ], [ -74.01123937, 40.70335991 ], [ -74.01121072, 40.70327152 ], [ -74.01129534, 40.70324897 ], [ -74.01142335, 40.70321506 ], [ -74.01143548, 40.70332286 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01205019, 40.7043159 ], [ -74.0120492, 40.7042619 ], [ -74.01204831, 40.70421559 ], [ -74.01204768, 40.7041859 ], [ -74.01204714, 40.70415417 ], [ -74.01204669, 40.70409989 ], [ -74.01214757, 40.70410112 ], [ -74.012142, 40.70431488 ], [ -74.01205019, 40.7043159 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01052943, 40.70504661 ], [ -74.01047652, 40.70494406 ], [ -74.01056591, 40.70489707 ], [ -74.0105995, 40.7048795 ], [ -74.01067739, 40.7050208 ], [ -74.01067927, 40.70503299 ], [ -74.01052943, 40.70504661 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726657, 40.70568116 ], [ -74.00716174, 40.70561946 ], [ -74.00712374, 40.70559651 ], [ -74.00723073, 40.70551282 ], [ -74.00736503, 40.70559406 ], [ -74.00726657, 40.70568116 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01266608, 40.70391207 ], [ -74.01266545, 40.70390029 ], [ -74.01266455, 40.70388326 ], [ -74.01253061, 40.7038849 ], [ -74.01251444, 40.70376559 ], [ -74.01251498, 40.70375646 ], [ -74.0125987, 40.70375816 ], [ -74.01259816, 40.70387087 ], [ -74.01293189, 40.70387618 ], [ -74.01293629, 40.7039088 ], [ -74.01266608, 40.70391207 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00755359, 40.70585161 ], [ -74.00741821, 40.70598672 ], [ -74.00708952, 40.70580081 ], [ -74.0070976, 40.70579236 ], [ -74.00707631, 40.70578038 ], [ -74.00709185, 40.70576206 ], [ -74.00699223, 40.70570561 ], [ -74.00709311, 40.70560911 ], [ -74.00712221, 40.705629 ], [ -74.00704298, 40.70570806 ], [ -74.00713398, 40.70576111 ], [ -74.00711224, 40.70578406 ], [ -74.00741102, 40.70596057 ], [ -74.00753544, 40.70584078 ], [ -74.00755359, 40.70585161 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00897005, 40.70555109 ], [ -74.00889684, 40.70556321 ], [ -74.00888264, 40.70546277 ], [ -74.00869103, 40.70547952 ], [ -74.00868223, 40.70543498 ], [ -74.00895163, 40.70540699 ], [ -74.00897005, 40.70555109 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0105209, 40.70417249 ], [ -74.0104555, 40.70420231 ], [ -74.0102974, 40.70402866 ], [ -74.01037268, 40.7039737 ], [ -74.0105209, 40.70417249 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01276974, 40.70350401 ], [ -74.01275357, 40.7034558 ], [ -74.01288149, 40.70342658 ], [ -74.01288904, 40.70344579 ], [ -74.01296917, 40.70343196 ], [ -74.01298642, 40.70352056 ], [ -74.01278079, 40.70353752 ], [ -74.01276974, 40.70350401 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00871502, 40.70486928 ], [ -74.00864513, 40.70491137 ], [ -74.00862698, 40.704894 ], [ -74.00846933, 40.70474241 ], [ -74.00853913, 40.70470026 ], [ -74.00871502, 40.70486928 ] ] ] } }, { "type": "Feature", "properties": { "height": 11.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01204714, 40.70415417 ], [ -74.0118408, 40.70415049 ], [ -74.01180648, 40.70414981 ], [ -74.01177495, 40.7041492 ], [ -74.01174189, 40.70414858 ], [ -74.0117021, 40.7041479 ], [ -74.01170524, 40.70409907 ], [ -74.01170569, 40.70409186 ], [ -74.01204669, 40.70409989 ], [ -74.01204714, 40.70415417 ] ] ] } }, { "type": "Feature", "properties": { "height": 97.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01433137, 40.70549579 ], [ -74.01421289, 40.70546842 ], [ -74.0142287, 40.70542919 ], [ -74.01425259, 40.70536988 ], [ -74.01430721, 40.70538248 ], [ -74.01437099, 40.70539726 ], [ -74.01442624, 40.70541006 ], [ -74.01438662, 40.70550846 ], [ -74.01433137, 40.70549579 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01306897, 40.70526392 ], [ -74.01289407, 40.70521257 ], [ -74.01289308, 40.70516388 ], [ -74.01290736, 40.7051632 ], [ -74.01290763, 40.70510409 ], [ -74.01302954, 40.70510722 ], [ -74.01302343, 40.7051698 ], [ -74.01304669, 40.70517158 ], [ -74.01306897, 40.70526392 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00882605, 40.70527577 ], [ -74.00875778, 40.70528462 ], [ -74.00865519, 40.70506139 ], [ -74.00873469, 40.70503905 ], [ -74.00882605, 40.70527577 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01254427, 40.70398746 ], [ -74.01245677, 40.70398691 ], [ -74.0124539, 40.70395886 ], [ -74.01244482, 40.7038725 ], [ -74.01243782, 40.70380617 ], [ -74.01243413, 40.70377192 ], [ -74.01251444, 40.70376559 ], [ -74.01253061, 40.7038849 ], [ -74.01253295, 40.70390186 ], [ -74.0125378, 40.70393849 ], [ -74.01254103, 40.70396301 ], [ -74.01254301, 40.70397806 ], [ -74.01254427, 40.70398746 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01032543, 40.7042711 ], [ -74.01026335, 40.70431931 ], [ -74.01008351, 40.70418488 ], [ -74.01015888, 40.70412979 ], [ -74.01032543, 40.7042711 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0104555, 40.70420231 ], [ -74.01038858, 40.70423371 ], [ -74.01022338, 40.7040828 ], [ -74.0102974, 40.70402866 ], [ -74.0104555, 40.70420231 ] ] ] } }, { "type": "Feature", "properties": { "height": 115.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00624474, 40.7047655 ], [ -74.00599501, 40.70493418 ], [ -74.00597318, 40.70492022 ], [ -74.00615697, 40.70478736 ], [ -74.00603462, 40.70471 ], [ -74.00609769, 40.7046673 ], [ -74.00624474, 40.7047655 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00629064, 40.70472559 ], [ -74.00627699, 40.70473737 ], [ -74.00609059, 40.70461228 ], [ -74.00602438, 40.70465559 ], [ -74.00596258, 40.70469617 ], [ -74.00582577, 40.70478559 ], [ -74.00576252, 40.7048272 ], [ -74.00573369, 40.70484606 ], [ -74.0059403, 40.70497382 ], [ -74.00593392, 40.70497947 ], [ -74.00592817, 40.70498471 ], [ -74.00569785, 40.70484238 ], [ -74.00574483, 40.7048116 ], [ -74.00579693, 40.70477748 ], [ -74.00580789, 40.7047702 ], [ -74.00594461, 40.70468072 ], [ -74.00595584, 40.70467329 ], [ -74.0060066, 40.70464006 ], [ -74.00608601, 40.7045881 ], [ -74.00629064, 40.70472559 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00899978, 40.70554517 ], [ -74.0088919, 40.70576397 ], [ -74.00886899, 40.70575668 ], [ -74.00881437, 40.70573938 ], [ -74.00889684, 40.70556321 ], [ -74.00897005, 40.70555109 ], [ -74.00899978, 40.70554517 ] ] ] } }, { "type": "Feature", "properties": { "height": 69.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01266707, 40.70393032 ], [ -74.01266608, 40.70391207 ], [ -74.01293629, 40.7039088 ], [ -74.01293189, 40.70387618 ], [ -74.01291662, 40.7037632 ], [ -74.01291159, 40.70372561 ], [ -74.01261901, 40.70372091 ], [ -74.01262017, 40.70370382 ], [ -74.01294572, 40.70370961 ], [ -74.01297501, 40.70392658 ], [ -74.01266707, 40.70393032 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01055989, 40.7045356 ], [ -74.01040888, 40.7043409 ], [ -74.01048353, 40.70429908 ], [ -74.01060723, 40.70450046 ], [ -74.01061298, 40.70450999 ], [ -74.01055989, 40.7045356 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01055989, 40.7045356 ], [ -74.01050518, 40.70456501 ], [ -74.01033971, 40.7043868 ], [ -74.01040888, 40.7043409 ], [ -74.01055989, 40.7045356 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01243413, 40.7047211 ], [ -74.01241769, 40.7049143 ], [ -74.01232732, 40.7049096 ], [ -74.01234313, 40.70472382 ], [ -74.01243413, 40.7047211 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01290763, 40.70510409 ], [ -74.01290736, 40.7051632 ], [ -74.01289308, 40.70516388 ], [ -74.01289533, 40.70513528 ], [ -74.01270282, 40.70512588 ], [ -74.01268961, 40.70513419 ], [ -74.01258074, 40.70536716 ], [ -74.01254498, 40.7053566 ], [ -74.01266078, 40.7051156 ], [ -74.0126968, 40.70509619 ], [ -74.01290763, 40.70510409 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01002404, 40.70450468 ], [ -74.00996233, 40.70455248 ], [ -74.00978195, 40.70441867 ], [ -74.00984348, 40.704371 ], [ -74.01002404, 40.70450468 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01183325, 40.70426912 ], [ -74.01182552, 40.7043902 ], [ -74.0117913, 40.70438959 ], [ -74.01175968, 40.70438898 ], [ -74.01172671, 40.70438836 ], [ -74.01168691, 40.70438768 ], [ -74.01169464, 40.70426667 ], [ -74.01173417, 40.70426742 ], [ -74.0117674, 40.70426789 ], [ -74.01179902, 40.70426851 ], [ -74.01183325, 40.70426912 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01234313, 40.70472382 ], [ -74.01232732, 40.7049096 ], [ -74.01223551, 40.70490476 ], [ -74.01225061, 40.70472668 ], [ -74.01234313, 40.70472382 ] ] ] } }, { "type": "Feature", "properties": { "height": 147.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01302729, 40.70532507 ], [ -74.01298157, 40.70540856 ], [ -74.01296144, 40.70541578 ], [ -74.01285724, 40.70538547 ], [ -74.0128461, 40.70536927 ], [ -74.01288877, 40.70528367 ], [ -74.01290817, 40.7052774 ], [ -74.01301858, 40.70530968 ], [ -74.01302729, 40.70532507 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01038858, 40.70423371 ], [ -74.01032543, 40.7042711 ], [ -74.01015888, 40.70412979 ], [ -74.01022338, 40.7040828 ], [ -74.01038858, 40.70423371 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01474711, 40.70488821 ], [ -74.01471945, 40.70491539 ], [ -74.01423912, 40.70481807 ], [ -74.01423678, 40.70478436 ], [ -74.01474711, 40.70488821 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01222141, 40.70541769 ], [ -74.01220147, 40.70564568 ], [ -74.0121323, 40.70563839 ], [ -74.01214802, 40.70541517 ], [ -74.01222141, 40.70541769 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01229741, 40.7054202 ], [ -74.01228914, 40.70555068 ], [ -74.0122409, 40.70564977 ], [ -74.01220147, 40.70564568 ], [ -74.01222141, 40.70541769 ], [ -74.01229741, 40.7054202 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01125204, 40.70347112 ], [ -74.01115682, 40.70349216 ], [ -74.01111693, 40.70336447 ], [ -74.01109762, 40.70336836 ], [ -74.01109456, 40.70335882 ], [ -74.01111397, 40.70335528 ], [ -74.01110229, 40.70331776 ], [ -74.01116095, 40.7033072 ], [ -74.01117442, 40.70335038 ], [ -74.01121063, 40.70334377 ], [ -74.01125204, 40.70347112 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01231951, 40.70510388 ], [ -74.01231789, 40.70513487 ], [ -74.01193054, 40.70512179 ], [ -74.01193027, 40.70515496 ], [ -74.01188427, 40.70515339 ], [ -74.01188787, 40.70508597 ], [ -74.01231951, 40.70510388 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01052943, 40.70504661 ], [ -74.01039118, 40.70505921 ], [ -74.01035992, 40.70496367 ], [ -74.01044571, 40.70491348 ], [ -74.01047652, 40.70494406 ], [ -74.01052943, 40.70504661 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0056346, 40.7050287 ], [ -74.00532289, 40.70501951 ], [ -74.00541191, 40.70495672 ], [ -74.00555394, 40.70495979 ], [ -74.0056346, 40.7050287 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01391905, 40.70542572 ], [ -74.01382275, 40.70555266 ], [ -74.01374073, 40.70551677 ], [ -74.01372699, 40.70551078 ], [ -74.01381502, 40.70540161 ], [ -74.01391905, 40.70542572 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01243782, 40.70380617 ], [ -74.01234619, 40.70379936 ], [ -74.0123249, 40.70364117 ], [ -74.01241688, 40.7036441 ], [ -74.01241958, 40.70366439 ], [ -74.01242308, 40.7036902 ], [ -74.01243413, 40.70377192 ], [ -74.01243782, 40.70380617 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01045469, 40.7037598 ], [ -74.01038975, 40.70380188 ], [ -74.01025742, 40.70368557 ], [ -74.01027377, 40.70367467 ], [ -74.01026308, 40.7036552 ], [ -74.01030459, 40.70362789 ], [ -74.01037789, 40.70369217 ], [ -74.01045469, 40.7037598 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01046053, 40.70459212 ], [ -74.0104158, 40.70462276 ], [ -74.0102338, 40.70446899 ], [ -74.01028725, 40.70442691 ], [ -74.01046053, 40.70459212 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01019239, 40.70363381 ], [ -74.01011423, 40.70368536 ], [ -74.00999557, 40.70358117 ], [ -74.01007444, 40.70353009 ], [ -74.01019239, 40.70363381 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01027521, 40.70359118 ], [ -74.01020712, 40.70363606 ], [ -74.0101993, 40.70362932 ], [ -74.01019239, 40.70363381 ], [ -74.01007444, 40.70353009 ], [ -74.01014783, 40.70348256 ], [ -74.01027521, 40.70359118 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01115682, 40.70349216 ], [ -74.0110563, 40.7035145 ], [ -74.01101165, 40.70338572 ], [ -74.01109762, 40.70336836 ], [ -74.01111693, 40.70336447 ], [ -74.01115682, 40.70349216 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01225061, 40.70472668 ], [ -74.01223551, 40.70490476 ], [ -74.01215548, 40.70490068 ], [ -74.01217012, 40.70472907 ], [ -74.01225061, 40.70472668 ] ] ] } }, { "type": "Feature", "properties": { "height": 159.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01044922, 40.70535789 ], [ -74.01043763, 40.70538697 ], [ -74.01032067, 40.7054104 ], [ -74.01028132, 40.70540992 ], [ -74.01030683, 40.70531472 ], [ -74.01043745, 40.70529742 ], [ -74.01044922, 40.70535789 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01050518, 40.70456501 ], [ -74.01046053, 40.70459212 ], [ -74.01028725, 40.70442691 ], [ -74.01033971, 40.7043868 ], [ -74.01050518, 40.70456501 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01298112, 40.70179691 ], [ -74.01289093, 40.7017918 ], [ -74.01288724, 40.70182967 ], [ -74.01286398, 40.70182837 ], [ -74.0128753, 40.70171267 ], [ -74.01287583, 40.7017079 ], [ -74.01290027, 40.70170926 ], [ -74.01290332, 40.70167848 ], [ -74.01299414, 40.70168372 ], [ -74.01298148, 40.70179337 ], [ -74.01300977, 40.70179487 ], [ -74.01300771, 40.70181918 ], [ -74.01297914, 40.70181761 ], [ -74.01298112, 40.70179691 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01217012, 40.70472907 ], [ -74.01215548, 40.70490068 ], [ -74.01207463, 40.70489645 ], [ -74.01208945, 40.70473159 ], [ -74.01217012, 40.70472907 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01142335, 40.70321506 ], [ -74.01129534, 40.70324897 ], [ -74.01126372, 40.70315806 ], [ -74.01141248, 40.70312047 ], [ -74.01142335, 40.70321506 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01252989, 40.70090728 ], [ -74.0124609, 40.70092342 ], [ -74.01243261, 40.7008532 ], [ -74.01239003, 40.70074792 ], [ -74.01245911, 40.70073191 ], [ -74.01252989, 40.70090728 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01262314, 40.70061852 ], [ -74.01239209, 40.70067062 ], [ -74.01237251, 40.70062056 ], [ -74.01260346, 40.70056846 ], [ -74.01262314, 40.70061852 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00624474, 40.7047655 ], [ -74.00618572, 40.70481719 ], [ -74.0061965, 40.70482406 ], [ -74.00616138, 40.70485525 ], [ -74.00616757, 40.70485941 ], [ -74.00598414, 40.70500718 ], [ -74.00593392, 40.70497947 ], [ -74.0059403, 40.70497382 ], [ -74.00596572, 40.70495577 ], [ -74.00599501, 40.70493418 ], [ -74.00624474, 40.7047655 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01034043, 40.70355618 ], [ -74.01028042, 40.70359568 ], [ -74.01027521, 40.70359118 ], [ -74.01014783, 40.70348256 ], [ -74.0102117, 40.70344109 ], [ -74.01034043, 40.70355618 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01313742, 40.70054299 ], [ -74.01289991, 40.70056056 ], [ -74.01289344, 40.70051017 ], [ -74.01313087, 40.7004926 ], [ -74.01313742, 40.70054299 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01350151, 40.70051568 ], [ -74.01326813, 40.70053196 ], [ -74.01326193, 40.70048088 ], [ -74.01349522, 40.70046461 ], [ -74.01350151, 40.70051568 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00949134, 40.70517736 ], [ -74.00906815, 40.70524798 ], [ -74.00906195, 40.70522776 ], [ -74.00912213, 40.70521536 ], [ -74.00948002, 40.70514488 ], [ -74.00949134, 40.70517736 ] ] ] } }, { "type": "Feature", "properties": { "height": 97.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01207597, 40.70377049 ], [ -74.01207193, 40.70385459 ], [ -74.01193153, 40.70385071 ], [ -74.01193557, 40.70376647 ], [ -74.01207597, 40.70377049 ] ] ] } }, { "type": "Feature", "properties": { "height": 3.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01475421, 40.70178588 ], [ -74.01473184, 40.70178826 ], [ -74.01473481, 40.70180488 ], [ -74.01467453, 40.70181121 ], [ -74.01467148, 40.70179466 ], [ -74.01464785, 40.70179718 ], [ -74.01463141, 40.70170701 ], [ -74.0146527, 40.70170477 ], [ -74.01464992, 40.70168917 ], [ -74.0147084, 40.70168297 ], [ -74.01471127, 40.70169857 ], [ -74.01473768, 40.70169578 ], [ -74.01475421, 40.70178588 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01291662, 40.7037632 ], [ -74.01261721, 40.7037585 ], [ -74.01261793, 40.70373862 ], [ -74.01261901, 40.70372091 ], [ -74.01291159, 40.70372561 ], [ -74.01291662, 40.7037632 ] ] ] } }, { "type": "Feature", "properties": { "height": 158.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01300914, 40.70532732 ], [ -74.01297124, 40.70539862 ], [ -74.01295893, 40.70540189 ], [ -74.01286928, 40.70537417 ], [ -74.0128629, 40.70536348 ], [ -74.01289901, 40.7052934 ], [ -74.01291401, 40.70528891 ], [ -74.01300429, 40.70531778 ], [ -74.01300914, 40.70532732 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01129534, 40.70324897 ], [ -74.01121072, 40.70327152 ], [ -74.01118898, 40.7032773 ], [ -74.01115879, 40.70318462 ], [ -74.01126372, 40.70315806 ], [ -74.01129534, 40.70324897 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00853913, 40.70470026 ], [ -74.00846933, 40.70474241 ], [ -74.00838372, 40.70466008 ], [ -74.00837393, 40.70465082 ], [ -74.00844382, 40.70460867 ], [ -74.00853913, 40.70470026 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01298148, 40.70179337 ], [ -74.01298112, 40.70179691 ], [ -74.01289093, 40.7017918 ], [ -74.01290027, 40.70170926 ], [ -74.01290332, 40.70167848 ], [ -74.01299414, 40.70168372 ], [ -74.01298148, 40.70179337 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01100707, 40.70337292 ], [ -74.01100177, 40.7033576 ], [ -74.01100869, 40.70335617 ], [ -74.01096602, 40.70323331 ], [ -74.01103034, 40.7032171 ], [ -74.01106528, 40.70331776 ], [ -74.01107938, 40.70335841 ], [ -74.01100707, 40.70337292 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01334538, 40.70208369 ], [ -74.01328708, 40.7021129 ], [ -74.01330101, 40.70212496 ], [ -74.01330208, 40.70217079 ], [ -74.01329265, 40.70217971 ], [ -74.01324738, 40.70213531 ], [ -74.01323067, 40.70214641 ], [ -74.0131703, 40.70214736 ], [ -74.01315853, 40.70214021 ], [ -74.0132171, 40.70210568 ], [ -74.01320408, 40.702092 ], [ -74.01320929, 40.70204637 ], [ -74.01321998, 40.70203826 ], [ -74.01325627, 40.70208341 ], [ -74.01327415, 40.70207327 ], [ -74.01333442, 40.70207586 ], [ -74.01334538, 40.70208369 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01476733, 40.70491457 ], [ -74.01466654, 40.70514352 ], [ -74.01462629, 40.70513419 ], [ -74.01464596, 40.70508938 ], [ -74.01472151, 40.70491811 ], [ -74.01476733, 40.70491457 ] ] ] } }, { "type": "Feature", "properties": { "height": 6.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01457877, 40.70404562 ], [ -74.014567, 40.7040732 ], [ -74.01457437, 40.70407497 ], [ -74.01454131, 40.70415246 ], [ -74.01451652, 40.7041464 ], [ -74.01451203, 40.70415696 ], [ -74.01447645, 40.70414817 ], [ -74.01448094, 40.70413762 ], [ -74.01445615, 40.70413149 ], [ -74.01448921, 40.70405399 ], [ -74.01449855, 40.70405631 ], [ -74.01451032, 40.70402866 ], [ -74.01457877, 40.70404562 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00709311, 40.70560911 ], [ -74.00699223, 40.70570561 ], [ -74.00709185, 40.70576206 ], [ -74.00707631, 40.70578038 ], [ -74.00692647, 40.70569621 ], [ -74.00706679, 40.70559052 ], [ -74.0070738, 40.7055959 ], [ -74.00709311, 40.70560911 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00883881, 40.70555218 ], [ -74.00874727, 40.70573237 ], [ -74.00870972, 40.70567769 ], [ -74.00872301, 40.70565079 ], [ -74.00876793, 40.70556512 ], [ -74.00883881, 40.70555218 ] ] ] } }, { "type": "Feature", "properties": { "height": 88.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00945155, 40.70506296 ], [ -74.00932749, 40.70508781 ], [ -74.00930332, 40.70501719 ], [ -74.00942702, 40.70499227 ], [ -74.00945155, 40.70506296 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01423328, 40.70482018 ], [ -74.01417174, 40.70497232 ], [ -74.01414974, 40.70502659 ], [ -74.01411048, 40.7050159 ], [ -74.0141995, 40.70479526 ], [ -74.01423328, 40.70482018 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00765051, 40.70406611 ], [ -74.0076312, 40.70407912 ], [ -74.00759644, 40.7040497 ], [ -74.00756158, 40.70402021 ], [ -74.00752673, 40.70399066 ], [ -74.00743501, 40.70391316 ], [ -74.00740024, 40.70388381 ], [ -74.00736539, 40.70385432 ], [ -74.00733062, 40.7038249 ], [ -74.00735093, 40.70381108 ], [ -74.0073856, 40.70384057 ], [ -74.00742028, 40.70387019 ], [ -74.00745423, 40.70389927 ], [ -74.00754739, 40.70397847 ], [ -74.00758098, 40.704007 ], [ -74.00761575, 40.70403656 ], [ -74.00765051, 40.70406611 ] ] ] } }, { "type": "Feature", "properties": { "height": 41.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00731922, 40.70571262 ], [ -74.00729595, 40.70573516 ], [ -74.00728265, 40.7057481 ], [ -74.00712518, 40.70565508 ], [ -74.00713973, 40.70564098 ], [ -74.00716174, 40.70561946 ], [ -74.00726657, 40.70568116 ], [ -74.00731248, 40.7057086 ], [ -74.00731922, 40.70571262 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00811458, 40.70375251 ], [ -74.00809464, 40.70376606 ], [ -74.00805988, 40.70373658 ], [ -74.0080252, 40.70370709 ], [ -74.0079916, 40.70367808 ], [ -74.00789908, 40.70359922 ], [ -74.00786485, 40.70357041 ], [ -74.00782982, 40.70354099 ], [ -74.00779514, 40.70351137 ], [ -74.00781419, 40.7034985 ], [ -74.00784913, 40.70352798 ], [ -74.00788381, 40.7035574 ], [ -74.00791875, 40.70358689 ], [ -74.0080102, 40.70366419 ], [ -74.00804496, 40.70369367 ], [ -74.00807982, 40.70372309 ], [ -74.00811458, 40.70375251 ] ] ] } }, { "type": "Feature", "properties": { "height": 57.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0063608, 40.70466451 ], [ -74.00634607, 40.70467731 ], [ -74.00608682, 40.70450298 ], [ -74.00595225, 40.70459042 ], [ -74.00593877, 40.70457877 ], [ -74.00608771, 40.70448146 ], [ -74.0063608, 40.70466451 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01325043, 40.70516586 ], [ -74.01324217, 40.70515632 ], [ -74.01304023, 40.70513971 ], [ -74.01304669, 40.70517158 ], [ -74.01302343, 40.7051698 ], [ -74.01302954, 40.70510722 ], [ -74.01324863, 40.70511437 ], [ -74.01325043, 40.70516586 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0081056, 40.70386447 ], [ -74.00806679, 40.70389076 ], [ -74.0080279, 40.70391718 ], [ -74.00798963, 40.70394326 ], [ -74.00789459, 40.70400782 ], [ -74.00785668, 40.70403356 ], [ -74.00781787, 40.70405998 ], [ -74.00777897, 40.70408641 ], [ -74.00776101, 40.70407102 ], [ -74.0077999, 40.70404459 ], [ -74.00783889, 40.70401831 ], [ -74.00787725, 40.70399297 ], [ -74.00797157, 40.70392801 ], [ -74.00801065, 40.70390247 ], [ -74.00804955, 40.70387618 ], [ -74.00808853, 40.7038499 ], [ -74.0081056, 40.70386447 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00768447, 40.70350646 ], [ -74.00764548, 40.70353268 ], [ -74.0076065, 40.70355897 ], [ -74.00756742, 40.7035856 ], [ -74.00747292, 40.70364879 ], [ -74.0074351, 40.70367426 ], [ -74.0073962, 40.7037011 ], [ -74.00735721, 40.70372738 ], [ -74.00733988, 40.70371281 ], [ -74.00737868, 40.70368632 ], [ -74.00741749, 40.70365996 ], [ -74.00754972, 40.70357021 ], [ -74.00758853, 40.70354378 ], [ -74.00762743, 40.70351736 ], [ -74.00766632, 40.70349087 ], [ -74.00768447, 40.70350646 ] ] ] } }, { "type": "Feature", "properties": { "height": 145.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00789908, 40.70359922 ], [ -74.00756742, 40.7035856 ], [ -74.0076065, 40.70355897 ], [ -74.00786485, 40.70357041 ], [ -74.00789908, 40.70359922 ] ] ] } }, { "type": "Feature", "properties": { "height": 145.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0080252, 40.70370709 ], [ -74.00801065, 40.70390247 ], [ -74.00797157, 40.70392801 ], [ -74.0079916, 40.70367808 ], [ -74.0080252, 40.70370709 ] ] ] } }, { "type": "Feature", "properties": { "height": 59.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01454185, 40.70489645 ], [ -74.01452191, 40.70495277 ], [ -74.01438788, 40.7049256 ], [ -74.01440782, 40.70486928 ], [ -74.01454185, 40.70489645 ] ] ] } }, { "type": "Feature", "properties": { "height": 145.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00747292, 40.70364879 ], [ -74.00745423, 40.70389927 ], [ -74.00742028, 40.70387019 ], [ -74.0074351, 40.70367426 ], [ -74.00747292, 40.70364879 ] ] ] } }, { "type": "Feature", "properties": { "height": 145.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00787725, 40.70399297 ], [ -74.00783889, 40.70401831 ], [ -74.00758098, 40.704007 ], [ -74.00754739, 40.70397847 ], [ -74.00787725, 40.70399297 ] ] ] } }, { "type": "Feature", "properties": { "height": 113.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01204768, 40.7041859 ], [ -74.01185535, 40.70418209 ], [ -74.0118505, 40.70425748 ], [ -74.01183397, 40.70425686 ], [ -74.0118408, 40.70415049 ], [ -74.01204714, 40.70415417 ], [ -74.01204768, 40.7041859 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01044391, 40.70364866 ], [ -74.01040403, 40.70367501 ], [ -74.01033216, 40.70361202 ], [ -74.01031321, 40.70362448 ], [ -74.01028042, 40.70359568 ], [ -74.01034043, 40.70355618 ], [ -74.01044391, 40.70364866 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01045469, 40.7037598 ], [ -74.01037789, 40.70369217 ], [ -74.01040403, 40.70367501 ], [ -74.01044391, 40.70364866 ], [ -74.01050374, 40.70370219 ], [ -74.01049224, 40.70373549 ], [ -74.01045469, 40.7037598 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00632559, 40.70469508 ], [ -74.00631427, 40.70470489 ], [ -74.00631113, 40.70470782 ], [ -74.00608502, 40.70455568 ], [ -74.00598504, 40.70462106 ], [ -74.00597228, 40.70460976 ], [ -74.00608709, 40.70453437 ], [ -74.00632559, 40.70469508 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01119374, 40.70329201 ], [ -74.01112987, 40.70330482 ], [ -74.01109394, 40.70320096 ], [ -74.01115879, 40.70318462 ], [ -74.01118898, 40.7032773 ], [ -74.01119374, 40.70329201 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01112987, 40.70330482 ], [ -74.01106528, 40.70331776 ], [ -74.01103034, 40.7032171 ], [ -74.01109394, 40.70320096 ], [ -74.01112987, 40.70330482 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00761575, 40.70403656 ], [ -74.00759644, 40.7040497 ], [ -74.00756158, 40.70402021 ], [ -74.00752673, 40.70399066 ], [ -74.00743501, 40.70391316 ], [ -74.00740024, 40.70388381 ], [ -74.00736539, 40.70385432 ], [ -74.0073856, 40.70384057 ], [ -74.00742028, 40.70387019 ], [ -74.00745423, 40.70389927 ], [ -74.00754739, 40.70397847 ], [ -74.00758098, 40.704007 ], [ -74.00761575, 40.70403656 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00807982, 40.70372309 ], [ -74.00805988, 40.70373658 ], [ -74.0080252, 40.70370709 ], [ -74.0079916, 40.70367808 ], [ -74.00789908, 40.70359922 ], [ -74.00786485, 40.70357041 ], [ -74.00782982, 40.70354099 ], [ -74.00784913, 40.70352798 ], [ -74.00788381, 40.7035574 ], [ -74.00791875, 40.70358689 ], [ -74.0080102, 40.70366419 ], [ -74.00804496, 40.70369367 ], [ -74.00807982, 40.70372309 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00764548, 40.70353268 ], [ -74.0076065, 40.70355897 ], [ -74.00756742, 40.7035856 ], [ -74.00747292, 40.70364879 ], [ -74.0074351, 40.70367426 ], [ -74.0073962, 40.7037011 ], [ -74.00737868, 40.70368632 ], [ -74.00741749, 40.70365996 ], [ -74.00754972, 40.70357021 ], [ -74.00758853, 40.70354378 ], [ -74.00762743, 40.70351736 ], [ -74.00764548, 40.70353268 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00806679, 40.70389076 ], [ -74.0080279, 40.70391718 ], [ -74.00798963, 40.70394326 ], [ -74.00789459, 40.70400782 ], [ -74.00785668, 40.70403356 ], [ -74.00781787, 40.70405998 ], [ -74.0077999, 40.70404459 ], [ -74.00783889, 40.70401831 ], [ -74.00787725, 40.70399297 ], [ -74.00797157, 40.70392801 ], [ -74.00801065, 40.70390247 ], [ -74.00804955, 40.70387618 ], [ -74.00806679, 40.70389076 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01350187, 40.70067477 ], [ -74.01348633, 40.70057861 ], [ -74.01355343, 40.70057228 ], [ -74.01356844, 40.70066871 ], [ -74.01350187, 40.70067477 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01205801, 40.70394442 ], [ -74.01205657, 40.70397629 ], [ -74.01198839, 40.70397452 ], [ -74.01192012, 40.70397282 ], [ -74.01185193, 40.70397098 ], [ -74.01185328, 40.70393897 ], [ -74.01192164, 40.70394101 ], [ -74.01198983, 40.70394278 ], [ -74.01205801, 40.70394442 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01177243, 40.70372037 ], [ -74.01176911, 40.70377206 ], [ -74.0117657, 40.70382381 ], [ -74.01176228, 40.7038755 ], [ -74.01172051, 40.703874 ], [ -74.01172383, 40.70382231 ], [ -74.01172725, 40.70377056 ], [ -74.01173048, 40.70371887 ], [ -74.01177243, 40.70372037 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01206915, 40.70363177 ], [ -74.01206807, 40.7036635 ], [ -74.0119998, 40.70366221 ], [ -74.01193161, 40.70366098 ], [ -74.01186334, 40.70365969 ], [ -74.01186442, 40.70362789 ], [ -74.0119326, 40.70362918 ], [ -74.01200088, 40.70363048 ], [ -74.01206915, 40.70363177 ] ] ] } }, { "type": "Feature", "properties": { "height": 57.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00572462, 40.70494229 ], [ -74.00571051, 40.7049555 ], [ -74.00553247, 40.70484627 ], [ -74.00567629, 40.70475072 ], [ -74.00568859, 40.7047623 ], [ -74.00556445, 40.70484341 ], [ -74.00572462, 40.70494229 ] ] ] } }, { "type": "Feature", "properties": { "height": 124.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01195794, 40.70446246 ], [ -74.01192784, 40.70446171 ], [ -74.0119309, 40.70441131 ], [ -74.0120519, 40.70441356 ], [ -74.01205352, 40.70446607 ], [ -74.01195794, 40.70446246 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00805988, 40.70373658 ], [ -74.00804955, 40.70387618 ], [ -74.00801065, 40.70390247 ], [ -74.0080252, 40.70370709 ], [ -74.00805988, 40.70373658 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0074351, 40.70367426 ], [ -74.00742028, 40.70387019 ], [ -74.0073856, 40.70384057 ], [ -74.0073962, 40.7037011 ], [ -74.0074351, 40.70367426 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00783889, 40.70401831 ], [ -74.0077999, 40.70404459 ], [ -74.00761575, 40.70403656 ], [ -74.00758098, 40.704007 ], [ -74.00783889, 40.70401831 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00786485, 40.70357041 ], [ -74.0076065, 40.70355897 ], [ -74.00764548, 40.70353268 ], [ -74.00782982, 40.70354099 ], [ -74.00786485, 40.70357041 ] ] ] } }, { "type": "Feature", "properties": { "height": 59.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0142534, 40.70505506 ], [ -74.01414974, 40.70502659 ], [ -74.01417174, 40.70497232 ], [ -74.01425771, 40.70499459 ], [ -74.01425008, 40.70501181 ], [ -74.01427218, 40.70501849 ], [ -74.0142534, 40.70505506 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01344132, 40.70204051 ], [ -74.01340629, 40.70207048 ], [ -74.01329562, 40.70199631 ], [ -74.01333074, 40.70196628 ], [ -74.01344132, 40.70204051 ] ] ] } }, { "type": "Feature", "properties": { "height": 83.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00736413, 40.7047465 ], [ -74.00730152, 40.70479158 ], [ -74.00726738, 40.70481617 ], [ -74.00723783, 40.7047926 ], [ -74.00727538, 40.70476557 ], [ -74.00726918, 40.70476066 ], [ -74.00726262, 40.70475528 ], [ -74.00726011, 40.70475331 ], [ -74.00731948, 40.70471068 ], [ -74.00736413, 40.7047465 ] ] ] } }, { "type": "Feature", "properties": { "height": 95.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00742099, 40.70479267 ], [ -74.00735838, 40.70483768 ], [ -74.00730152, 40.70479158 ], [ -74.00736413, 40.7047465 ], [ -74.00742099, 40.70479267 ] ] ] } }, { "type": "Feature", "properties": { "height": 150.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01056483, 40.70533208 ], [ -74.01054524, 40.70522748 ], [ -74.01059124, 40.70522728 ], [ -74.0106092, 40.70528721 ], [ -74.01061603, 40.7053344 ], [ -74.01056483, 40.70533208 ] ] ] } }, { "type": "Feature", "properties": { "height": 88.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00595584, 40.70467329 ], [ -74.00580789, 40.7047702 ], [ -74.00579693, 40.70477748 ], [ -74.00577519, 40.70475849 ], [ -74.00578633, 40.7047512 ], [ -74.00592287, 40.70466158 ], [ -74.0059341, 40.70465416 ], [ -74.00595584, 40.70467329 ] ] ] } }, { "type": "Feature", "properties": { "height": 71.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00592242, 40.70464238 ], [ -74.00591012, 40.70465041 ], [ -74.00577339, 40.70473976 ], [ -74.00576181, 40.70474732 ], [ -74.00574043, 40.70472839 ], [ -74.00575192, 40.70472089 ], [ -74.00588883, 40.70463162 ], [ -74.00590104, 40.70462358 ], [ -74.00592242, 40.70464238 ] ] ] } }, { "type": "Feature", "properties": { "height": 59.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01466115, 40.70498512 ], [ -74.0146359, 40.70505288 ], [ -74.01456404, 40.70503756 ], [ -74.01458919, 40.70496966 ], [ -74.01466115, 40.70498512 ] ] ] } }, { "type": "Feature", "properties": { "height": 124.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0120492, 40.7042619 ], [ -74.01193862, 40.70425979 ], [ -74.01194123, 40.70421362 ], [ -74.01204831, 40.70421559 ], [ -74.0120492, 40.7042619 ] ] ] } }, { "type": "Feature", "properties": { "height": 145.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00758098, 40.704007 ], [ -74.00756158, 40.70402021 ], [ -74.00752673, 40.70399066 ], [ -74.00743501, 40.70391316 ], [ -74.00740024, 40.70388381 ], [ -74.00742028, 40.70387019 ], [ -74.00745423, 40.70389927 ], [ -74.00754739, 40.70397847 ], [ -74.00758098, 40.704007 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01374055, 40.70192862 ], [ -74.01372115, 40.70194408 ], [ -74.01373588, 40.70195477 ], [ -74.01370175, 40.70198221 ], [ -74.01363222, 40.70193189 ], [ -74.01366644, 40.70190451 ], [ -74.01368072, 40.70191479 ], [ -74.01370022, 40.70189927 ], [ -74.01374055, 40.70192862 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01266751, 40.70393686 ], [ -74.0125378, 40.70393849 ], [ -74.01253295, 40.70390186 ], [ -74.01266545, 40.70390029 ], [ -74.01266608, 40.70391207 ], [ -74.01266707, 40.70393032 ], [ -74.01266751, 40.70393686 ] ] ] } }, { "type": "Feature", "properties": { "height": 145.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00804496, 40.70369367 ], [ -74.0080252, 40.70370709 ], [ -74.0079916, 40.70367808 ], [ -74.00789908, 40.70359922 ], [ -74.00786485, 40.70357041 ], [ -74.00788381, 40.7035574 ], [ -74.00791875, 40.70358689 ], [ -74.0080102, 40.70366419 ], [ -74.00804496, 40.70369367 ] ] ] } }, { "type": "Feature", "properties": { "height": 145.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0080279, 40.70391718 ], [ -74.00798963, 40.70394326 ], [ -74.00789459, 40.70400782 ], [ -74.00785668, 40.70403356 ], [ -74.00783889, 40.70401831 ], [ -74.00787725, 40.70399297 ], [ -74.00797157, 40.70392801 ], [ -74.00801065, 40.70390247 ], [ -74.0080279, 40.70391718 ] ] ] } }, { "type": "Feature", "properties": { "height": 145.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0076065, 40.70355897 ], [ -74.00756742, 40.7035856 ], [ -74.00747292, 40.70364879 ], [ -74.0074351, 40.70367426 ], [ -74.00741749, 40.70365996 ], [ -74.00754972, 40.70357021 ], [ -74.00758853, 40.70354378 ], [ -74.0076065, 40.70355897 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00575821, 40.70491089 ], [ -74.00574294, 40.70492519 ], [ -74.00561269, 40.70484477 ], [ -74.00571015, 40.70478109 ], [ -74.005723, 40.70479247 ], [ -74.00564709, 40.70484211 ], [ -74.00575821, 40.70491089 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01224917, 40.7008989 ], [ -74.01217659, 40.70091538 ], [ -74.0121544, 40.7008592 ], [ -74.01222698, 40.70084278 ], [ -74.01224917, 40.7008989 ] ] ] } }, { "type": "Feature", "properties": { "height": 108.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00625453, 40.70475699 ], [ -74.00624474, 40.7047655 ], [ -74.00609769, 40.7046673 ], [ -74.00603462, 40.70471 ], [ -74.00601019, 40.70469461 ], [ -74.006087, 40.70464517 ], [ -74.00625453, 40.70475699 ] ] ] } }, { "type": "Feature", "properties": { "height": 113.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01195587, 40.7044835 ], [ -74.01195461, 40.70450298 ], [ -74.01181834, 40.70450427 ], [ -74.0118249, 40.70440089 ], [ -74.01184133, 40.70440151 ], [ -74.0118363, 40.70448118 ], [ -74.01195587, 40.7044835 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0077999, 40.70404459 ], [ -74.00776101, 40.70407102 ], [ -74.00765051, 40.70406611 ], [ -74.00761575, 40.70403656 ], [ -74.0077999, 40.70404459 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00782982, 40.70354099 ], [ -74.00764548, 40.70353268 ], [ -74.00768447, 40.70350646 ], [ -74.00779514, 40.70351137 ], [ -74.00782982, 40.70354099 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00809464, 40.70376606 ], [ -74.00808853, 40.7038499 ], [ -74.00804955, 40.70387618 ], [ -74.00805988, 40.70373658 ], [ -74.00809464, 40.70376606 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00735721, 40.70372738 ], [ -74.00735093, 40.70381108 ], [ -74.00733062, 40.7038249 ], [ -74.00729568, 40.70379542 ], [ -74.00731625, 40.70378159 ], [ -74.00731832, 40.70375367 ], [ -74.00730098, 40.7037391 ], [ -74.00733988, 40.70371281 ], [ -74.00735721, 40.70372738 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00777897, 40.70408641 ], [ -74.00774008, 40.70411276 ], [ -74.00772202, 40.7040973 ], [ -74.00768519, 40.7040956 ], [ -74.00766596, 40.70410847 ], [ -74.0076312, 40.70407912 ], [ -74.00765051, 40.70406611 ], [ -74.00776101, 40.70407102 ], [ -74.00777897, 40.70408641 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00814953, 40.70378207 ], [ -74.00812941, 40.70379569 ], [ -74.00812743, 40.70382361 ], [ -74.00814441, 40.70383811 ], [ -74.0081056, 40.70386447 ], [ -74.00808853, 40.7038499 ], [ -74.00809464, 40.70376606 ], [ -74.00811458, 40.70375251 ], [ -74.00814953, 40.70378207 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00781419, 40.7034985 ], [ -74.00779514, 40.70351137 ], [ -74.00768447, 40.70350646 ], [ -74.00766632, 40.70349087 ], [ -74.00770513, 40.70346458 ], [ -74.00772355, 40.70348018 ], [ -74.00776038, 40.70348188 ], [ -74.00777951, 40.70346908 ], [ -74.00781419, 40.7034985 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0073962, 40.7037011 ], [ -74.0073856, 40.70384057 ], [ -74.00735093, 40.70381108 ], [ -74.00735721, 40.70372738 ], [ -74.0073962, 40.7037011 ] ] ] } }, { "type": "Feature", "properties": { "height": 59.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01464596, 40.70508938 ], [ -74.01462629, 40.70513419 ], [ -74.01454275, 40.70511492 ], [ -74.01456018, 40.70507161 ], [ -74.01464596, 40.70508938 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00598171, 40.70471299 ], [ -74.0058449, 40.70480241 ], [ -74.00582577, 40.70478559 ], [ -74.00596258, 40.70469617 ], [ -74.00598171, 40.70471299 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0118408, 40.70415049 ], [ -74.01183397, 40.70425686 ], [ -74.01183325, 40.70426912 ], [ -74.01179902, 40.70426851 ], [ -74.01180648, 40.70414981 ], [ -74.0118408, 40.70415049 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00723073, 40.70551282 ], [ -74.00712374, 40.70559651 ], [ -74.00711305, 40.70558997 ], [ -74.00709544, 40.70557956 ], [ -74.00720477, 40.70549709 ], [ -74.00723073, 40.70551282 ] ] ] } }, { "type": "Feature", "properties": { "height": 150.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0102921, 40.7055549 ], [ -74.0101755, 40.70556526 ], [ -74.01024242, 40.70553161 ], [ -74.01026551, 40.7054787 ], [ -74.01029363, 40.70549899 ], [ -74.0102921, 40.7055549 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01182552, 40.7043902 ], [ -74.0118249, 40.70440089 ], [ -74.01181834, 40.70450427 ], [ -74.01178402, 40.70450461 ], [ -74.0117913, 40.70438959 ], [ -74.01182552, 40.7043902 ] ] ] } }, { "type": "Feature", "properties": { "height": 72.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01177495, 40.7041492 ], [ -74.0117674, 40.70426789 ], [ -74.01173417, 40.70426742 ], [ -74.01173623, 40.70423786 ], [ -74.01173991, 40.70417991 ], [ -74.01174189, 40.70414858 ], [ -74.01177495, 40.7041492 ] ] ] } }, { "type": "Feature", "properties": { "height": 72.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01175968, 40.70438898 ], [ -74.01175231, 40.70450488 ], [ -74.01171934, 40.70450515 ], [ -74.01172087, 40.70447907 ], [ -74.01172491, 40.70441608 ], [ -74.01172671, 40.70438836 ], [ -74.01175968, 40.70438898 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01279454, 40.70163217 ], [ -74.01272977, 40.70164429 ], [ -74.01271162, 40.70158851 ], [ -74.0127763, 40.70157639 ], [ -74.01279454, 40.70163217 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00735838, 40.70483768 ], [ -74.00742099, 40.70479267 ], [ -74.00746124, 40.70482481 ], [ -74.00739863, 40.70486976 ], [ -74.00735838, 40.70483768 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0086639, 40.70562579 ], [ -74.00864675, 40.70564902 ], [ -74.00857147, 40.7056657 ], [ -74.00864207, 40.70556866 ], [ -74.0086639, 40.70562579 ] ] ] } }, { "type": "Feature", "properties": { "height": 86.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01180648, 40.70414981 ], [ -74.01179902, 40.70426851 ], [ -74.0117674, 40.70426789 ], [ -74.01177495, 40.7041492 ], [ -74.01180648, 40.70414981 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00735838, 40.70483768 ], [ -74.007307, 40.70487357 ], [ -74.0072822, 40.70485369 ], [ -74.00728957, 40.70484838 ], [ -74.00729703, 40.7048432 ], [ -74.00726532, 40.70481766 ], [ -74.00726738, 40.70481617 ], [ -74.00730152, 40.70479158 ], [ -74.00735838, 40.70483768 ] ] ] } }, { "type": "Feature", "properties": { "height": 86.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0117913, 40.70438959 ], [ -74.01178402, 40.70450461 ], [ -74.01175231, 40.70450488 ], [ -74.01175968, 40.70438898 ], [ -74.0117913, 40.70438959 ] ] ] } }, { "type": "Feature", "properties": { "height": 64.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00589251, 40.70501767 ], [ -74.00587401, 40.7050347 ], [ -74.00575192, 40.70495917 ], [ -74.00577025, 40.70494208 ], [ -74.00589251, 40.70501767 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01258828, 40.70364682 ], [ -74.01258703, 40.70366711 ], [ -74.01241958, 40.70366439 ], [ -74.01241688, 40.7036441 ], [ -74.01258828, 40.70364682 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00876793, 40.70556512 ], [ -74.00872301, 40.70565079 ], [ -74.00870046, 40.70559406 ], [ -74.00872229, 40.70555041 ], [ -74.00876793, 40.70556512 ] ] ] } }, { "type": "Feature", "properties": { "height": 108.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00599501, 40.70493418 ], [ -74.00596572, 40.70495577 ], [ -74.00588613, 40.70490647 ], [ -74.00591218, 40.70488978 ], [ -74.00587427, 40.70485607 ], [ -74.00597318, 40.70492022 ], [ -74.00599501, 40.70493418 ] ] ] } }, { "type": "Feature", "properties": { "height": 125.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00772373, 40.70516191 ], [ -74.00771879, 40.70525282 ], [ -74.0076948, 40.70525248 ], [ -74.00768914, 40.70525656 ], [ -74.00768411, 40.70525261 ], [ -74.00767881, 40.70524846 ], [ -74.00768447, 40.70524437 ], [ -74.00768528, 40.70522626 ], [ -74.0076869, 40.70518867 ], [ -74.0076877, 40.70516987 ], [ -74.00768231, 40.70516558 ], [ -74.00768752, 40.70516177 ], [ -74.007693, 40.70515782 ], [ -74.00769848, 40.70516218 ], [ -74.00772373, 40.70516191 ] ] ] } }, { "type": "Feature", "properties": { "height": 125.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00794399, 40.7053568 ], [ -74.00793869, 40.70536069 ], [ -74.0079333, 40.7053647 ], [ -74.00792711, 40.70535939 ], [ -74.00790222, 40.70535919 ], [ -74.00785407, 40.70535878 ], [ -74.00782874, 40.70535871 ], [ -74.00782299, 40.7053628 ], [ -74.00781805, 40.70535878 ], [ -74.00781275, 40.70535469 ], [ -74.00781841, 40.70535047 ], [ -74.00782039, 40.70533222 ], [ -74.00793905, 40.70533236 ], [ -74.00793851, 40.70535251 ], [ -74.00794399, 40.7053568 ] ] ] } }, { "type": "Feature", "properties": { "height": 89.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01205873, 40.70392842 ], [ -74.01205801, 40.70394442 ], [ -74.01198983, 40.70394278 ], [ -74.01192164, 40.70394101 ], [ -74.01185328, 40.70393897 ], [ -74.011854, 40.7039231 ], [ -74.01205873, 40.70392842 ] ] ] } }, { "type": "Feature", "properties": { "height": 125.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00827727, 40.70503211 ], [ -74.00827035, 40.70503681 ], [ -74.0082699, 40.70505438 ], [ -74.00826909, 40.70509047 ], [ -74.00826864, 40.70511131 ], [ -74.00827412, 40.7051156 ], [ -74.00826882, 40.70511948 ], [ -74.00826343, 40.70512336 ], [ -74.00825724, 40.70511812 ], [ -74.00823271, 40.7051173 ], [ -74.00823622, 40.70502761 ], [ -74.00826137, 40.70502802 ], [ -74.00826712, 40.70502387 ], [ -74.00827224, 40.70502789 ], [ -74.00827727, 40.70503211 ] ] ] } }, { "type": "Feature", "properties": { "height": 125.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00814342, 40.70492519 ], [ -74.00813641, 40.70492976 ], [ -74.00813524, 40.70494787 ], [ -74.00801873, 40.70494821 ], [ -74.00801927, 40.70492921 ], [ -74.00801388, 40.70492492 ], [ -74.00801918, 40.70492131 ], [ -74.00802457, 40.70491716 ], [ -74.00803014, 40.70492152 ], [ -74.00805556, 40.70492138 ], [ -74.00810174, 40.70492117 ], [ -74.00812752, 40.70492111 ], [ -74.00813318, 40.70491702 ], [ -74.0081383, 40.70492097 ], [ -74.00814342, 40.70492519 ] ] ] } }, { "type": "Feature", "properties": { "height": 89.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01206807, 40.7036635 ], [ -74.01206762, 40.70367951 ], [ -74.0118628, 40.70367556 ], [ -74.01186334, 40.70365969 ], [ -74.01193161, 40.70366098 ], [ -74.0119998, 40.70366221 ], [ -74.01206807, 40.7036635 ] ] ] } }, { "type": "Feature", "properties": { "height": 43.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01266877, 40.70396151 ], [ -74.01254103, 40.70396301 ], [ -74.0125378, 40.70393849 ], [ -74.01266751, 40.70393686 ], [ -74.01266877, 40.70396151 ] ] ] } }, { "type": "Feature", "properties": { "height": 150.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00799879, 40.70518669 ], [ -74.0079651, 40.70521128 ], [ -74.00790815, 40.7051664 ], [ -74.00794175, 40.70514188 ], [ -74.00799879, 40.70518669 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00590805, 40.70500337 ], [ -74.00589251, 40.70501767 ], [ -74.00577025, 40.70494208 ], [ -74.00578561, 40.70492771 ], [ -74.00590805, 40.70500337 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01290027, 40.70170926 ], [ -74.01289093, 40.7017918 ], [ -74.01288724, 40.70182967 ], [ -74.01286398, 40.70182837 ], [ -74.0128753, 40.70171267 ], [ -74.01287583, 40.7017079 ], [ -74.01290027, 40.70170926 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0098195, 40.70271247 ], [ -74.00980243, 40.70269769 ], [ -74.00976084, 40.70266187 ], [ -74.00974368, 40.70264716 ], [ -74.00970819, 40.70261659 ], [ -74.00972068, 40.70260821 ], [ -74.00975616, 40.70263879 ], [ -74.00977332, 40.70265356 ], [ -74.00981491, 40.70268939 ], [ -74.00983198, 40.7027041 ], [ -74.00986747, 40.70273467 ], [ -74.00985498, 40.70274312 ], [ -74.0098195, 40.70271247 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0098195, 40.70271247 ], [ -74.00980243, 40.70269769 ], [ -74.00976084, 40.70266187 ], [ -74.00974368, 40.70264716 ], [ -74.00970819, 40.70261659 ], [ -74.00972068, 40.70260821 ], [ -74.00975616, 40.70263879 ], [ -74.00977332, 40.70265356 ], [ -74.00981491, 40.70268939 ], [ -74.00983198, 40.7027041 ], [ -74.00986747, 40.70273467 ], [ -74.00985498, 40.70274312 ], [ -74.0098195, 40.70271247 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00872301, 40.70565079 ], [ -74.0086639, 40.70562579 ], [ -74.00864207, 40.70556866 ], [ -74.00870046, 40.70559406 ], [ -74.00872301, 40.70565079 ] ] ] } }, { "type": "Feature", "properties": { "height": 160.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00754739, 40.70397847 ], [ -74.00752673, 40.70399066 ], [ -74.00743501, 40.70391316 ], [ -74.00745423, 40.70389927 ], [ -74.00754739, 40.70397847 ] ] ] } }, { "type": "Feature", "properties": { "height": 57.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00588883, 40.70463162 ], [ -74.00575192, 40.70472089 ], [ -74.00573881, 40.70470979 ], [ -74.00587607, 40.7046199 ], [ -74.00588883, 40.70463162 ] ] ] } }, { "type": "Feature", "properties": { "height": 160.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0080102, 40.70366419 ], [ -74.0079916, 40.70367808 ], [ -74.00789908, 40.70359922 ], [ -74.00791875, 40.70358689 ], [ -74.0080102, 40.70366419 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00592287, 40.70466158 ], [ -74.00578633, 40.7047512 ], [ -74.00577339, 40.70473976 ], [ -74.00591012, 40.70465041 ], [ -74.00592287, 40.70466158 ] ] ] } }, { "type": "Feature", "properties": { "height": 57.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00587401, 40.7050347 ], [ -74.00586035, 40.70504729 ], [ -74.005738, 40.70497232 ], [ -74.00575192, 40.70495917 ], [ -74.00587401, 40.7050347 ] ] ] } }, { "type": "Feature", "properties": { "height": 153.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01421441, 40.7030034 ], [ -74.01420669, 40.70293945 ], [ -74.0141721, 40.70286366 ], [ -74.01412171, 40.70280489 ], [ -74.01405784, 40.70276157 ], [ -74.01397483, 40.70272759 ], [ -74.01387647, 40.70271411 ], [ -74.0138771, 40.70270961 ], [ -74.01397672, 40.7027233 ], [ -74.01406125, 40.7027579 ], [ -74.0141262, 40.70280189 ], [ -74.0141774, 40.70286168 ], [ -74.01421253, 40.7029385 ], [ -74.01422034, 40.7030034 ], [ -74.01421441, 40.7030034 ] ] ] } }, { "type": "Feature", "properties": { "height": 160.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00798963, 40.70394326 ], [ -74.00789459, 40.70400782 ], [ -74.00787725, 40.70399297 ], [ -74.00797157, 40.70392801 ], [ -74.00798963, 40.70394326 ] ] ] } }, { "type": "Feature", "properties": { "height": 148.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00812033, 40.70509796 ], [ -74.00806419, 40.70513896 ], [ -74.00803427, 40.70511546 ], [ -74.00809042, 40.70507447 ], [ -74.00812033, 40.70509796 ] ] ] } }, { "type": "Feature", "properties": { "height": 160.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00756742, 40.7035856 ], [ -74.00747292, 40.70364879 ], [ -74.00745648, 40.70363347 ], [ -74.00754972, 40.70357021 ], [ -74.00756742, 40.7035856 ] ] ] } }, { "type": "Feature", "properties": { "height": 108.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00587427, 40.70485607 ], [ -74.00584041, 40.70487827 ], [ -74.00578238, 40.70484238 ], [ -74.00581741, 40.70481998 ], [ -74.00587427, 40.70485607 ] ] ] } }, { "type": "Feature", "properties": { "height": 58.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01172491, 40.70441608 ], [ -74.01172087, 40.70447907 ], [ -74.01168107, 40.70447826 ], [ -74.01168521, 40.70441519 ], [ -74.01172491, 40.70441608 ] ] ] } }, { "type": "Feature", "properties": { "height": 117.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0118505, 40.70425748 ], [ -74.01184133, 40.70440151 ], [ -74.0118249, 40.70440089 ], [ -74.01182552, 40.7043902 ], [ -74.01183325, 40.70426912 ], [ -74.01183397, 40.70425686 ], [ -74.0118505, 40.70425748 ] ] ] } }, { "type": "Feature", "properties": { "height": 58.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01173991, 40.70417991 ], [ -74.01173623, 40.70423786 ], [ -74.01169653, 40.70423698 ], [ -74.01170012, 40.70417916 ], [ -74.01173991, 40.70417991 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01266545, 40.70390029 ], [ -74.01253295, 40.70390186 ], [ -74.01253061, 40.7038849 ], [ -74.01266455, 40.70388326 ], [ -74.01266545, 40.70390029 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00883377, 40.70551902 ], [ -74.00876793, 40.70556512 ], [ -74.00871888, 40.70553209 ], [ -74.00883377, 40.70551902 ] ] ] } }, { "type": "Feature", "properties": { "height": 3.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01364856, 40.70167119 ], [ -74.0136112, 40.70167698 ], [ -74.01359637, 40.70162188 ], [ -74.01363374, 40.70161596 ], [ -74.01364856, 40.70167119 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01198983, 40.70394278 ], [ -74.01198839, 40.70397452 ], [ -74.01192012, 40.70397282 ], [ -74.01192164, 40.70394101 ], [ -74.01198983, 40.70394278 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01200088, 40.70363048 ], [ -74.0119998, 40.70366221 ], [ -74.01193161, 40.70366098 ], [ -74.0119326, 40.70362918 ], [ -74.01200088, 40.70363048 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01176911, 40.70377206 ], [ -74.0117657, 40.70382381 ], [ -74.01172383, 40.70382231 ], [ -74.01172725, 40.70377056 ], [ -74.01176911, 40.70377206 ] ] ] } }, { "type": "Feature", "properties": { "height": 47.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00721654, 40.70471817 ], [ -74.00711539, 40.70479022 ], [ -74.00720459, 40.70486132 ], [ -74.00719713, 40.7048667 ], [ -74.00710182, 40.70478988 ], [ -74.00720953, 40.70471259 ], [ -74.00721654, 40.70471817 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00578561, 40.70492771 ], [ -74.00577025, 40.70494208 ], [ -74.00575192, 40.70495917 ], [ -74.005738, 40.70497232 ], [ -74.00571051, 40.7049555 ], [ -74.00572462, 40.70494229 ], [ -74.00574294, 40.70492519 ], [ -74.00575821, 40.70491089 ], [ -74.00578561, 40.70492771 ] ] ] } }, { "type": "Feature", "properties": { "height": 69.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01261793, 40.70373862 ], [ -74.01261721, 40.7037585 ], [ -74.0125987, 40.70375816 ], [ -74.01251498, 40.70375646 ], [ -74.01251633, 40.70373698 ], [ -74.01261793, 40.70373862 ] ] ] } }, { "type": "Feature", "properties": { "height": 86.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00733862, 40.70475631 ], [ -74.00729505, 40.7047877 ], [ -74.00727322, 40.7047702 ], [ -74.00728544, 40.70476148 ], [ -74.00727457, 40.7047529 ], [ -74.0073061, 40.70473029 ], [ -74.00733862, 40.70475631 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00872301, 40.70565079 ], [ -74.00870972, 40.70567769 ], [ -74.00864675, 40.70564902 ], [ -74.0086639, 40.70562579 ], [ -74.00872301, 40.70565079 ] ] ] } }, { "type": "Feature", "properties": { "height": 51.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0072231, 40.70472348 ], [ -74.00712904, 40.70479036 ], [ -74.00721151, 40.70485628 ], [ -74.00721052, 40.70485709 ], [ -74.00720459, 40.70486132 ], [ -74.00711539, 40.70479022 ], [ -74.00721654, 40.70471817 ], [ -74.00722211, 40.7047228 ], [ -74.0072231, 40.70472348 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01266958, 40.70397581 ], [ -74.01254301, 40.70397806 ], [ -74.01254103, 40.70396301 ], [ -74.01266877, 40.70396151 ], [ -74.01266931, 40.70396982 ], [ -74.01266958, 40.70397581 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00729568, 40.70379542 ], [ -74.00726118, 40.7037662 ], [ -74.00730098, 40.7037391 ], [ -74.00731832, 40.70375367 ], [ -74.00731625, 40.70378159 ], [ -74.00729568, 40.70379542 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00774008, 40.70411276 ], [ -74.00770181, 40.70413878 ], [ -74.00766596, 40.70410847 ], [ -74.00768519, 40.7040956 ], [ -74.00772202, 40.7040973 ], [ -74.00774008, 40.70411276 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00814441, 40.70383811 ], [ -74.00812743, 40.70382361 ], [ -74.00812941, 40.70379569 ], [ -74.00814953, 40.70378207 ], [ -74.00818402, 40.70381121 ], [ -74.00814441, 40.70383811 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00777951, 40.70346908 ], [ -74.00776038, 40.70348188 ], [ -74.00772355, 40.70348018 ], [ -74.00770513, 40.70346458 ], [ -74.0077434, 40.70343857 ], [ -74.00777951, 40.70346908 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00722974, 40.70472879 ], [ -74.00714261, 40.7047907 ], [ -74.00721851, 40.7048513 ], [ -74.00721151, 40.70485628 ], [ -74.00712904, 40.70479036 ], [ -74.0072231, 40.70472348 ], [ -74.00722974, 40.70472879 ] ] ] } }, { "type": "Feature", "properties": { "height": 58.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0072363, 40.70473411 ], [ -74.00715617, 40.70479097 ], [ -74.00722552, 40.70484627 ], [ -74.00722381, 40.70484749 ], [ -74.00721851, 40.7048513 ], [ -74.00714261, 40.7047907 ], [ -74.00722974, 40.70472879 ], [ -74.00723477, 40.70473288 ], [ -74.0072363, 40.70473411 ] ] ] } }, { "type": "Feature", "properties": { "height": 38.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00716174, 40.70561946 ], [ -74.00713973, 40.70564098 ], [ -74.00712221, 40.705629 ], [ -74.00709311, 40.70560911 ], [ -74.00711305, 40.70558997 ], [ -74.00712374, 40.70559651 ], [ -74.00716174, 40.70561946 ] ] ] } }, { "type": "Feature", "properties": { "height": 158.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01296198, 40.70534387 ], [ -74.01295525, 40.70535851 ], [ -74.0129362, 40.70536518 ], [ -74.01291662, 40.70535946 ], [ -74.01290844, 40.70534441 ], [ -74.01291698, 40.70532977 ], [ -74.0129353, 40.70532446 ], [ -74.01295264, 40.70532936 ], [ -74.01296198, 40.70534387 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00724295, 40.70473942 ], [ -74.00716983, 40.70479131 ], [ -74.00723253, 40.70484129 ], [ -74.00722552, 40.70484627 ], [ -74.00715617, 40.70479097 ], [ -74.0072363, 40.70473411 ], [ -74.00724295, 40.70473942 ] ] ] } }, { "type": "Feature", "properties": { "height": 115.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0076869, 40.70518867 ], [ -74.00768528, 40.70522626 ], [ -74.00766129, 40.70522599 ], [ -74.00765563, 40.70523007 ], [ -74.00765051, 40.70522605 ], [ -74.0076453, 40.70522197 ], [ -74.00765105, 40.70521781 ], [ -74.00765078, 40.70519657 ], [ -74.00764539, 40.70519228 ], [ -74.00765069, 40.70518846 ], [ -74.00765608, 40.70518451 ], [ -74.00766165, 40.7051888 ], [ -74.0076869, 40.70518867 ] ] ] } }, { "type": "Feature", "properties": { "height": 115.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00790734, 40.70538357 ], [ -74.00790213, 40.70538752 ], [ -74.00789665, 40.7053914 ], [ -74.00789036, 40.70538616 ], [ -74.00786234, 40.7053852 ], [ -74.00785659, 40.70538929 ], [ -74.00785147, 40.70538527 ], [ -74.00784644, 40.70538118 ], [ -74.00785201, 40.70537696 ], [ -74.00785407, 40.70535878 ], [ -74.00790222, 40.70535919 ], [ -74.00790177, 40.70537928 ], [ -74.00790734, 40.70538357 ] ] ] } }, { "type": "Feature", "properties": { "height": 115.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00830009, 40.7050966 ], [ -74.00829389, 40.70509135 ], [ -74.00826909, 40.70509047 ], [ -74.0082699, 40.70505438 ], [ -74.00829497, 40.70505492 ], [ -74.00830071, 40.7050507 ], [ -74.00830583, 40.70505479 ], [ -74.00831087, 40.70505887 ], [ -74.00830395, 40.70506357 ], [ -74.0083053, 40.70508448 ], [ -74.00831078, 40.70508877 ], [ -74.00830548, 40.70509272 ], [ -74.00830009, 40.7050966 ] ] ] } }, { "type": "Feature", "properties": { "height": 115.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00810991, 40.70489836 ], [ -74.00810291, 40.70490306 ], [ -74.00810174, 40.70492117 ], [ -74.00805556, 40.70492138 ], [ -74.00805619, 40.70490252 ], [ -74.00805071, 40.70489816 ], [ -74.00805601, 40.70489448 ], [ -74.00806149, 40.70489039 ], [ -74.00806688, 40.70489468 ], [ -74.00809401, 40.70489441 ], [ -74.00809967, 40.70489026 ], [ -74.00810479, 40.70489428 ], [ -74.00810991, 40.70489836 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00724951, 40.70474466 ], [ -74.00718339, 40.70479151 ], [ -74.00723944, 40.70483619 ], [ -74.0072372, 40.70483782 ], [ -74.00723253, 40.70484129 ], [ -74.00716983, 40.70479131 ], [ -74.00724295, 40.70473942 ], [ -74.00724744, 40.70474309 ], [ -74.00724951, 40.70474466 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01174189, 40.70414858 ], [ -74.01173991, 40.70417991 ], [ -74.01170012, 40.70417916 ], [ -74.0117021, 40.7041479 ], [ -74.01174189, 40.70414858 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01267021, 40.70398596 ], [ -74.01254427, 40.70398746 ], [ -74.01254301, 40.70397806 ], [ -74.01266958, 40.70397581 ], [ -74.01267021, 40.70398596 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00883881, 40.70555218 ], [ -74.00876793, 40.70556512 ], [ -74.00883377, 40.70551902 ], [ -74.00883881, 40.70555218 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726684, 40.70490258 ], [ -74.00725337, 40.70491212 ], [ -74.00719713, 40.7048667 ], [ -74.00720459, 40.70486132 ], [ -74.00721052, 40.70485709 ], [ -74.00726684, 40.70490258 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00728158, 40.7046801 ], [ -74.00722211, 40.7047228 ], [ -74.00721654, 40.70471817 ], [ -74.00720953, 40.70471259 ], [ -74.00726891, 40.70466989 ], [ -74.00728158, 40.7046801 ] ] ] } }, { "type": "Feature", "properties": { "height": 69.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00730691, 40.70470046 ], [ -74.00724744, 40.70474309 ], [ -74.00724295, 40.70473942 ], [ -74.0072363, 40.70473411 ], [ -74.00723477, 40.70473288 ], [ -74.00729424, 40.70469032 ], [ -74.00730691, 40.70470046 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00728023, 40.70489291 ], [ -74.00726684, 40.70490258 ], [ -74.00721052, 40.70485709 ], [ -74.00721151, 40.70485628 ], [ -74.00721851, 40.7048513 ], [ -74.00722381, 40.70484749 ], [ -74.00728023, 40.70489291 ] ] ] } }, { "type": "Feature", "properties": { "height": 69.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00725615, 40.70474997 ], [ -74.00719704, 40.70479179 ], [ -74.00724645, 40.70483122 ], [ -74.00723944, 40.70483619 ], [ -74.00718339, 40.70479151 ], [ -74.00724951, 40.70474466 ], [ -74.00725615, 40.70474997 ] ] ] } }, { "type": "Feature", "properties": { "height": 69.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00729361, 40.70488318 ], [ -74.00728023, 40.70489291 ], [ -74.00722381, 40.70484749 ], [ -74.00722552, 40.70484627 ], [ -74.00723253, 40.70484129 ], [ -74.0072372, 40.70483782 ], [ -74.00729361, 40.70488318 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00729424, 40.70469032 ], [ -74.00723477, 40.70473288 ], [ -74.00722974, 40.70472879 ], [ -74.0072231, 40.70472348 ], [ -74.00722211, 40.7047228 ], [ -74.00728158, 40.7046801 ], [ -74.00729424, 40.70469032 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00731948, 40.70471068 ], [ -74.00726011, 40.70475331 ], [ -74.00725615, 40.70474997 ], [ -74.00724951, 40.70474466 ], [ -74.00724744, 40.70474309 ], [ -74.00730691, 40.70470046 ], [ -74.00731948, 40.70471068 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.007307, 40.70487357 ], [ -74.00729361, 40.70488318 ], [ -74.0072372, 40.70483782 ], [ -74.00723944, 40.70483619 ], [ -74.00724645, 40.70483122 ], [ -74.00725058, 40.70482822 ], [ -74.0072822, 40.70485369 ], [ -74.007307, 40.70487357 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01173623, 40.70423786 ], [ -74.01173417, 40.70426742 ], [ -74.01169464, 40.70426667 ], [ -74.01169653, 40.70423698 ], [ -74.01173623, 40.70423786 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01172671, 40.70438836 ], [ -74.01172491, 40.70441608 ], [ -74.01168521, 40.70441519 ], [ -74.01168691, 40.70438768 ], [ -74.01172671, 40.70438836 ] ] ] } }, { "type": "Feature", "properties": { "height": 73.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726262, 40.70475528 ], [ -74.00721061, 40.70479206 ], [ -74.00725337, 40.70482618 ], [ -74.00725058, 40.70482822 ], [ -74.00724645, 40.70483122 ], [ -74.00719704, 40.70479179 ], [ -74.00725615, 40.70474997 ], [ -74.00726011, 40.70475331 ], [ -74.00726262, 40.70475528 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01172087, 40.70447907 ], [ -74.01171934, 40.70450515 ], [ -74.01167937, 40.70450556 ], [ -74.01168107, 40.70447826 ], [ -74.01172087, 40.70447907 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726918, 40.70476066 ], [ -74.00722417, 40.7047924 ], [ -74.00726038, 40.7048212 ], [ -74.00725804, 40.70482291 ], [ -74.00725337, 40.70482618 ], [ -74.00721061, 40.70479206 ], [ -74.00726262, 40.70475528 ], [ -74.00726918, 40.70476066 ] ] ] } }, { "type": "Feature", "properties": { "height": 3.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00981491, 40.70268939 ], [ -74.00980243, 40.70269769 ], [ -74.00976084, 40.70266187 ], [ -74.00977332, 40.70265356 ], [ -74.00981491, 40.70268939 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726738, 40.70481617 ], [ -74.00726532, 40.70481766 ], [ -74.00726038, 40.7048212 ], [ -74.00722417, 40.7047924 ], [ -74.00726918, 40.70476066 ], [ -74.00727538, 40.70476557 ], [ -74.00723783, 40.7047926 ], [ -74.00726738, 40.70481617 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01423912, 40.70481807 ], [ -74.01423328, 40.70482018 ], [ -74.0141995, 40.70479526 ], [ -74.01423678, 40.70478436 ], [ -74.01423912, 40.70481807 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01476733, 40.70491457 ], [ -74.01472151, 40.70491811 ], [ -74.01471945, 40.70491539 ], [ -74.01474711, 40.70488821 ], [ -74.01476733, 40.70491457 ] ] ] } }, { "type": "Feature", "properties": { "height": 3.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0098195, 40.70271247 ], [ -74.00983198, 40.7027041 ], [ -74.00986747, 40.70273467 ], [ -74.00985498, 40.70274312 ], [ -74.0098195, 40.70271247 ] ] ] } }, { "type": "Feature", "properties": { "height": 3.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00975616, 40.70263879 ], [ -74.00974368, 40.70264716 ], [ -74.00970819, 40.70261659 ], [ -74.00972068, 40.70260821 ], [ -74.00975616, 40.70263879 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00711305, 40.70558997 ], [ -74.00709311, 40.70560911 ], [ -74.0070738, 40.7055959 ], [ -74.00709544, 40.70557956 ], [ -74.00711305, 40.70558997 ] ] ] } }, { "type": "Feature", "properties": { "height": 109.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0079333, 40.7053647 ], [ -74.00790734, 40.70538357 ], [ -74.00790177, 40.70537928 ], [ -74.00790222, 40.70535919 ], [ -74.00792711, 40.70535939 ], [ -74.0079333, 40.7053647 ] ] ] } }, { "type": "Feature", "properties": { "height": 109.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00830009, 40.7050966 ], [ -74.00827412, 40.7051156 ], [ -74.00826864, 40.70511131 ], [ -74.00826909, 40.70509047 ], [ -74.00829389, 40.70509135 ], [ -74.00830009, 40.7050966 ] ] ] } }, { "type": "Feature", "properties": { "height": 119.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00826343, 40.70512336 ], [ -74.00823738, 40.70514236 ], [ -74.0082319, 40.70513807 ], [ -74.00823271, 40.7051173 ], [ -74.00825724, 40.70511812 ], [ -74.00826343, 40.70512336 ] ] ] } }, { "type": "Feature", "properties": { "height": 119.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00801873, 40.70494821 ], [ -74.00799304, 40.70494828 ], [ -74.00798765, 40.70494399 ], [ -74.00801388, 40.70492492 ], [ -74.00801927, 40.70492921 ], [ -74.00801873, 40.70494821 ] ] ] } }, { "type": "Feature", "properties": { "height": 119.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00796986, 40.70533781 ], [ -74.00794399, 40.7053568 ], [ -74.00793851, 40.70535251 ], [ -74.00793905, 40.70533236 ], [ -74.00796367, 40.70533249 ], [ -74.00796986, 40.70533781 ] ] ] } }, { "type": "Feature", "properties": { "height": 119.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00772373, 40.70516191 ], [ -74.00769848, 40.70516218 ], [ -74.007693, 40.70515782 ], [ -74.00771915, 40.70513889 ], [ -74.00772453, 40.70514318 ], [ -74.00772373, 40.70516191 ] ] ] } }, { "type": "Feature", "properties": { "height": 119.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00782039, 40.70533222 ], [ -74.00781841, 40.70535047 ], [ -74.00781275, 40.70535469 ], [ -74.00778957, 40.70533617 ], [ -74.00779532, 40.70533208 ], [ -74.00782039, 40.70533222 ] ] ] } }, { "type": "Feature", "properties": { "height": 109.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00813318, 40.70491702 ], [ -74.00812752, 40.70492111 ], [ -74.00810174, 40.70492117 ], [ -74.00810291, 40.70490306 ], [ -74.00810991, 40.70489836 ], [ -74.00813318, 40.70491702 ] ] ] } }, { "type": "Feature", "properties": { "height": 119.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0081666, 40.70494378 ], [ -74.00816094, 40.70494787 ], [ -74.00813524, 40.70494787 ], [ -74.00813641, 40.70492976 ], [ -74.00814342, 40.70492519 ], [ -74.0081666, 40.70494378 ] ] ] } }, { "type": "Feature", "properties": { "height": 109.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00830071, 40.7050507 ], [ -74.00829497, 40.70505492 ], [ -74.0082699, 40.70505438 ], [ -74.00827035, 40.70503681 ], [ -74.00827727, 40.70503211 ], [ -74.00830071, 40.7050507 ] ] ] } }, { "type": "Feature", "properties": { "height": 109.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00768528, 40.70522626 ], [ -74.00768447, 40.70524437 ], [ -74.00767881, 40.70524846 ], [ -74.00765563, 40.70523007 ], [ -74.00766129, 40.70522599 ], [ -74.00768528, 40.70522626 ] ] ] } }, { "type": "Feature", "properties": { "height": 119.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00771879, 40.70525282 ], [ -74.00771789, 40.705271 ], [ -74.00771223, 40.70527509 ], [ -74.00768914, 40.70525656 ], [ -74.0076948, 40.70525248 ], [ -74.00771879, 40.70525282 ] ] ] } }, { "type": "Feature", "properties": { "height": 109.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00805556, 40.70492138 ], [ -74.00803014, 40.70492152 ], [ -74.00802457, 40.70491716 ], [ -74.00805071, 40.70489816 ], [ -74.00805619, 40.70490252 ], [ -74.00805556, 40.70492138 ] ] ] } }, { "type": "Feature", "properties": { "height": 109.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00785407, 40.70535878 ], [ -74.00785201, 40.70537696 ], [ -74.00784644, 40.70538118 ], [ -74.00782299, 40.7053628 ], [ -74.00782874, 40.70535871 ], [ -74.00785407, 40.70535878 ] ] ] } }, { "type": "Feature", "properties": { "height": 119.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00826712, 40.70502387 ], [ -74.00826137, 40.70502802 ], [ -74.00823622, 40.70502761 ], [ -74.00823693, 40.70501011 ], [ -74.00824394, 40.70500541 ], [ -74.00826712, 40.70502387 ] ] ] } }, { "type": "Feature", "properties": { "height": 109.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0076869, 40.70518867 ], [ -74.00766165, 40.7051888 ], [ -74.00765608, 40.70518451 ], [ -74.00768231, 40.70516558 ], [ -74.0076877, 40.70516987 ], [ -74.0076869, 40.70518867 ] ] ] } }, { "type": "Feature", "properties": { "height": 83.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00728957, 40.70484838 ], [ -74.0072822, 40.70485369 ], [ -74.00725058, 40.70482822 ], [ -74.00725337, 40.70482618 ], [ -74.00725804, 40.70482291 ], [ -74.00728957, 40.70484838 ] ] ] } }, { "type": "Feature", "properties": { "height": 87.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00728957, 40.70484838 ], [ -74.00725804, 40.70482291 ], [ -74.00726038, 40.7048212 ], [ -74.00726532, 40.70481766 ], [ -74.00729703, 40.7048432 ], [ -74.00728957, 40.70484838 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00876793, 40.70556512 ], [ -74.00872229, 40.70555041 ], [ -74.00871888, 40.70553209 ], [ -74.00876793, 40.70556512 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01348633, 40.70198181 ], [ -74.01348624, 40.70198392 ], [ -74.01348435, 40.70198548 ], [ -74.01348148, 40.70198576 ], [ -74.01347923, 40.7019846 ], [ -74.01347833, 40.70198256 ], [ -74.01347941, 40.70198072 ], [ -74.01348193, 40.7019797 ], [ -74.01348462, 40.7019801 ], [ -74.01348633, 40.70198181 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01287871, 40.70157578 ], [ -74.01287862, 40.70157789 ], [ -74.01287673, 40.70157946 ], [ -74.01287395, 40.70157966 ], [ -74.01287152, 40.70157857 ], [ -74.01287071, 40.7015766 ], [ -74.0128717, 40.70157462 ], [ -74.01287422, 40.7015736 ], [ -74.012877, 40.70157408 ], [ -74.01287871, 40.70157578 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01351912, 40.70143549 ], [ -74.01351903, 40.70143767 ], [ -74.01351714, 40.70143916 ], [ -74.01351427, 40.70143951 ], [ -74.01351202, 40.70143842 ], [ -74.01351112, 40.70143637 ], [ -74.0135122, 40.7014344 ], [ -74.01351472, 40.70143338 ], [ -74.01351741, 40.70143392 ], [ -74.01351912, 40.70143549 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01325609, 40.7017632 ], [ -74.013256, 40.70176531 ], [ -74.01325411, 40.70176687 ], [ -74.01325133, 40.70176708 ], [ -74.0132489, 40.70176599 ], [ -74.0132481, 40.70176401 ], [ -74.01324917, 40.70176197 ], [ -74.01325169, 40.70176102 ], [ -74.01325438, 40.70176149 ], [ -74.01325609, 40.7017632 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01339192, 40.70191779 ], [ -74.01339183, 40.7019199 ], [ -74.01338994, 40.70192147 ], [ -74.01338707, 40.70192181 ], [ -74.01338482, 40.70192058 ], [ -74.01338392, 40.70191861 ], [ -74.013385, 40.7019167 ], [ -74.01338751, 40.70191568 ], [ -74.01339021, 40.70191609 ], [ -74.01339192, 40.70191779 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01364192, 40.70127041 ], [ -74.01364183, 40.70127252 ], [ -74.01363994, 40.70127408 ], [ -74.01363725, 40.70127436 ], [ -74.01363482, 40.7012732 ], [ -74.01363392, 40.70127115 ], [ -74.013635, 40.70126932 ], [ -74.01363752, 40.70126829 ], [ -74.01364021, 40.7012687 ], [ -74.01364192, 40.70127041 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01367704, 40.70210868 ], [ -74.01367695, 40.70211086 ], [ -74.01367498, 40.70211236 ], [ -74.01367219, 40.7021127 ], [ -74.01366994, 40.70211161 ], [ -74.01366905, 40.7021095 ], [ -74.01367012, 40.70210759 ], [ -74.01367264, 40.70210657 ], [ -74.01367533, 40.70210711 ], [ -74.01367704, 40.70210868 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01329157, 40.70167119 ], [ -74.01329148, 40.70167337 ], [ -74.0132896, 40.70167487 ], [ -74.01328681, 40.70167521 ], [ -74.01328448, 40.70167412 ], [ -74.01328358, 40.70167201 ], [ -74.01328475, 40.7016701 ], [ -74.01328717, 40.70166908 ], [ -74.01328987, 40.70166956 ], [ -74.01329157, 40.70167119 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01292084, 40.70165049 ], [ -74.01292057, 40.7016526 ], [ -74.01291877, 40.70165417 ], [ -74.01291599, 40.70165451 ], [ -74.01291365, 40.70165328 ], [ -74.01291284, 40.7016513 ], [ -74.01291383, 40.7016494 ], [ -74.01291635, 40.70164838 ], [ -74.01291913, 40.70164879 ], [ -74.01292084, 40.70165049 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01344474, 40.70151442 ], [ -74.01344465, 40.7015166 ], [ -74.01344267, 40.7015181 ], [ -74.01343989, 40.70151837 ], [ -74.01343764, 40.70151728 ], [ -74.01343674, 40.70151517 ], [ -74.01343782, 40.70151326 ], [ -74.01344034, 40.70151231 ], [ -74.01344303, 40.70151278 ], [ -74.01344474, 40.70151442 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01358209, 40.70204562 ], [ -74.013582, 40.70204766 ], [ -74.01358011, 40.7020493 ], [ -74.01357733, 40.70204957 ], [ -74.01357499, 40.70204841 ], [ -74.01357409, 40.70204637 ], [ -74.01357517, 40.70204446 ], [ -74.01357769, 40.70204351 ], [ -74.01358038, 40.70204392 ], [ -74.01358209, 40.70204562 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.013597, 40.70135792 ], [ -74.01359691, 40.7013601 ], [ -74.01359503, 40.7013616 ], [ -74.01359224, 40.70136187 ], [ -74.01358982, 40.70136078 ], [ -74.01358901, 40.70135867 ], [ -74.01359008, 40.70135676 ], [ -74.01359251, 40.70135581 ], [ -74.01359529, 40.70135628 ], [ -74.013597, 40.70135792 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0132966, 40.70185418 ], [ -74.01329652, 40.70185629 ], [ -74.01329463, 40.70185786 ], [ -74.01329193, 40.7018582 ], [ -74.01328951, 40.70185697 ], [ -74.0132887, 40.701855 ], [ -74.01328969, 40.70185296 ], [ -74.0132922, 40.701852 ], [ -74.0132949, 40.70185248 ], [ -74.0132966, 40.70185418 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01303349, 40.70163966 ], [ -74.0130334, 40.70164177 ], [ -74.01303151, 40.7016434 ], [ -74.01302873, 40.70164368 ], [ -74.0130263, 40.70164252 ], [ -74.01302549, 40.70164048 ], [ -74.01302657, 40.7016385 ], [ -74.013029, 40.70163762 ], [ -74.01303178, 40.70163796 ], [ -74.01303349, 40.70163966 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01336694, 40.70159321 ], [ -74.01336667, 40.70159526 ], [ -74.01336479, 40.70159675 ], [ -74.01336209, 40.7015971 ], [ -74.01335967, 40.70159601 ], [ -74.01335895, 40.70159396 ], [ -74.01335994, 40.70159199 ], [ -74.01336245, 40.70159097 ], [ -74.01336524, 40.70159151 ], [ -74.01336694, 40.70159321 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01285023, 40.71598 ], [ -74.01279633, 40.71620809 ], [ -74.0127878, 40.71624751 ], [ -74.01155271, 40.71569246 ], [ -74.01136451, 40.71560599 ], [ -74.01150878, 40.71505951 ], [ -74.01155792, 40.71506509 ], [ -74.01222653, 40.7151692 ], [ -74.01210885, 40.71531219 ], [ -74.01205181, 40.71537789 ], [ -74.01290458, 40.71575776 ], [ -74.01285023, 40.71598 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01593289, 40.7148502 ], [ -74.01547313, 40.71543747 ], [ -74.01472834, 40.71532342 ], [ -74.01487782, 40.71475842 ], [ -74.01510015, 40.71447401 ], [ -74.01510078, 40.71447306 ], [ -74.01593289, 40.7148502 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01485015, 40.71453611 ], [ -74.0147914, 40.71460542 ], [ -74.01461578, 40.71530476 ], [ -74.01443513, 40.7152744 ], [ -74.01396468, 40.71520372 ], [ -74.01401193, 40.71502308 ], [ -74.01404284, 40.71490522 ], [ -74.01416573, 40.71444936 ], [ -74.01425493, 40.71410462 ], [ -74.01495463, 40.714413 ], [ -74.01485015, 40.71453611 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01285023, 40.71598 ], [ -74.01279633, 40.71620809 ], [ -74.0127878, 40.71624751 ], [ -74.01155271, 40.71569246 ], [ -74.01167038, 40.71523402 ], [ -74.01210885, 40.71531219 ], [ -74.01205181, 40.71537789 ], [ -74.01290458, 40.71575776 ], [ -74.01285023, 40.71598 ] ] ] } }, { "type": "Feature", "properties": { "height": 71.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01237907, 40.71492231 ], [ -74.01227181, 40.71490461 ], [ -74.01216473, 40.71488697 ], [ -74.01205747, 40.71486927 ], [ -74.0119503, 40.7148517 ], [ -74.01184313, 40.714834 ], [ -74.01173587, 40.71481636 ], [ -74.01164909, 40.714802 ], [ -74.01186218, 40.71398131 ], [ -74.01187601, 40.71396585 ], [ -74.0119017, 40.71395612 ], [ -74.01192533, 40.71395939 ], [ -74.01195623, 40.71397178 ], [ -74.01205621, 40.71401549 ], [ -74.0121561, 40.71405921 ], [ -74.01225681, 40.71410306 ], [ -74.01235715, 40.71414691 ], [ -74.01245731, 40.71419069 ], [ -74.01255747, 40.71423461 ], [ -74.01266392, 40.71428097 ], [ -74.01248632, 40.71493988 ], [ -74.01237907, 40.71492231 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01543981, 40.71340956 ], [ -74.01541034, 40.71345021 ], [ -74.01536264, 40.71351571 ], [ -74.01530874, 40.71359129 ], [ -74.01525457, 40.71366612 ], [ -74.01510608, 40.71387291 ], [ -74.01516043, 40.71389497 ], [ -74.01517211, 40.71395557 ], [ -74.01514318, 40.71399527 ], [ -74.01512504, 40.71402026 ], [ -74.01503341, 40.7140432 ], [ -74.01499262, 40.71402611 ], [ -74.01497223, 40.7140541 ], [ -74.01468432, 40.71393297 ], [ -74.0146898, 40.71392541 ], [ -74.01460338, 40.71388912 ], [ -74.01460087, 40.71389252 ], [ -74.01432104, 40.71375866 ], [ -74.01441231, 40.71352402 ], [ -74.0143974, 40.71352068 ], [ -74.01440243, 40.71350706 ], [ -74.01438429, 40.71350318 ], [ -74.01439012, 40.71348766 ], [ -74.01437045, 40.7134835 ], [ -74.01443073, 40.71332158 ], [ -74.0144504, 40.7133258 ], [ -74.01445543, 40.71331225 ], [ -74.01447358, 40.71331627 ], [ -74.01447915, 40.71330136 ], [ -74.01449981, 40.71330592 ], [ -74.01450421, 40.71329407 ], [ -74.01459647, 40.7132983 ], [ -74.0146651, 40.71312671 ], [ -74.01475861, 40.71308558 ], [ -74.01492633, 40.71314366 ], [ -74.01504473, 40.71318479 ], [ -74.01502739, 40.71320869 ], [ -74.01516663, 40.71326731 ], [ -74.01515091, 40.7132889 ], [ -74.01543981, 40.71340956 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01237907, 40.71492231 ], [ -74.01227181, 40.71490461 ], [ -74.01216473, 40.71488697 ], [ -74.01205747, 40.71486927 ], [ -74.0119503, 40.7148517 ], [ -74.01184313, 40.714834 ], [ -74.01173587, 40.71481636 ], [ -74.01195623, 40.71397178 ], [ -74.01205621, 40.71401549 ], [ -74.0121561, 40.71405921 ], [ -74.01225681, 40.71410306 ], [ -74.01235715, 40.71414691 ], [ -74.01245731, 40.71419069 ], [ -74.01255747, 40.71423461 ], [ -74.01266392, 40.71428097 ], [ -74.01248632, 40.71493988 ], [ -74.01237907, 40.71492231 ] ] ] } }, { "type": "Feature", "properties": { "height": 53.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01455847, 40.71806836 ], [ -74.01454302, 40.71808817 ], [ -74.01453475, 40.71808436 ], [ -74.01451661, 40.71811091 ], [ -74.01442974, 40.71821767 ], [ -74.01435195, 40.71831742 ], [ -74.01433443, 40.71833982 ], [ -74.01395273, 40.71828746 ], [ -74.01395363, 40.71828406 ], [ -74.01387593, 40.71824988 ], [ -74.01386964, 40.71828086 ], [ -74.01360086, 40.71824409 ], [ -74.01360697, 40.71821856 ], [ -74.0135308, 40.71820807 ], [ -74.01352594, 40.71822911 ], [ -74.01325501, 40.718192 ], [ -74.01332328, 40.71790298 ], [ -74.01335167, 40.71790679 ], [ -74.01335526, 40.71789106 ], [ -74.01334583, 40.7178784 ], [ -74.01333936, 40.71786478 ], [ -74.01333613, 40.71784946 ], [ -74.01333649, 40.71783517 ], [ -74.01337907, 40.71766046 ], [ -74.0134071, 40.71754546 ], [ -74.01455847, 40.71806836 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00399455, 40.71576109 ], [ -74.00393733, 40.71582986 ], [ -74.00383178, 40.71577948 ], [ -74.00362651, 40.7156815 ], [ -74.00406399, 40.71515429 ], [ -74.00409103, 40.71512147 ], [ -74.00421841, 40.71496929 ], [ -74.00442179, 40.71506639 ], [ -74.00453677, 40.71512127 ], [ -74.00447003, 40.71520168 ], [ -74.00458573, 40.71525697 ], [ -74.00472254, 40.71532226 ], [ -74.00448, 40.71561409 ], [ -74.0042547, 40.71588529 ], [ -74.00399455, 40.71576109 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01338662, 40.71372488 ], [ -74.01334853, 40.71388701 ], [ -74.01331772, 40.71402196 ], [ -74.01327819, 40.71418871 ], [ -74.01326642, 40.71423917 ], [ -74.0124653, 40.71387986 ], [ -74.01248165, 40.7138166 ], [ -74.01250752, 40.7137163 ], [ -74.01252298, 40.71365638 ], [ -74.01255541, 40.71353089 ], [ -74.01260122, 40.71335359 ], [ -74.01261559, 40.71330231 ], [ -74.01339991, 40.71366878 ], [ -74.01338662, 40.71372488 ] ] ] } }, { "type": "Feature", "properties": { "height": 79.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01237907, 40.71492231 ], [ -74.01227181, 40.71490461 ], [ -74.01216473, 40.71488697 ], [ -74.01205747, 40.71486927 ], [ -74.0119503, 40.7148517 ], [ -74.01184313, 40.714834 ], [ -74.01205621, 40.71401549 ], [ -74.0121561, 40.71405921 ], [ -74.01225681, 40.71410306 ], [ -74.01235715, 40.71414691 ], [ -74.01245731, 40.71419069 ], [ -74.01255747, 40.71423461 ], [ -74.01266392, 40.71428097 ], [ -74.01248632, 40.71493988 ], [ -74.01237907, 40.71492231 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00882856, 40.7176179 ], [ -74.00882255, 40.71762566 ], [ -74.00875868, 40.71770689 ], [ -74.00881823, 40.71773399 ], [ -74.00872454, 40.717853 ], [ -74.00874493, 40.71786226 ], [ -74.00879398, 40.71788466 ], [ -74.00866507, 40.71804862 ], [ -74.00865052, 40.71806816 ], [ -74.00851667, 40.7180081 ], [ -74.0084528, 40.71797917 ], [ -74.00845064, 40.71798196 ], [ -74.00836423, 40.71794288 ], [ -74.00830062, 40.71791421 ], [ -74.0079528, 40.71775598 ], [ -74.007951, 40.7177583 ], [ -74.00772777, 40.71765671 ], [ -74.007822, 40.71753668 ], [ -74.00797283, 40.71734467 ], [ -74.00806086, 40.71723308 ], [ -74.00827853, 40.71733221 ], [ -74.00827619, 40.71733521 ], [ -74.00862959, 40.71749596 ], [ -74.00869427, 40.71752558 ], [ -74.00869714, 40.7175221 ], [ -74.0087805, 40.7175601 ], [ -74.00884941, 40.71759148 ], [ -74.00882856, 40.7176179 ] ] ] } }, { "type": "Feature", "properties": { "height": 144.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00478992, 40.7145216 ], [ -74.00493248, 40.71434477 ], [ -74.00569138, 40.71469932 ], [ -74.00536241, 40.71510717 ], [ -74.00526782, 40.71506312 ], [ -74.00527357, 40.7150559 ], [ -74.00522201, 40.7150318 ], [ -74.00521617, 40.71503901 ], [ -74.00474042, 40.7148167 ], [ -74.00474761, 40.71480778 ], [ -74.00469613, 40.71478368 ], [ -74.00468895, 40.7147926 ], [ -74.00459211, 40.71474739 ], [ -74.00465203, 40.7146731 ], [ -74.00466344, 40.71467841 ], [ -74.00478992, 40.7145216 ] ] ] } }, { "type": "Feature", "properties": { "height": 83.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01237907, 40.71492231 ], [ -74.01227181, 40.71490461 ], [ -74.01216473, 40.71488697 ], [ -74.01205747, 40.71486927 ], [ -74.0119503, 40.7148517 ], [ -74.0121561, 40.71405921 ], [ -74.01225681, 40.71410306 ], [ -74.01235715, 40.71414691 ], [ -74.01245731, 40.71419069 ], [ -74.01255747, 40.71423461 ], [ -74.01266392, 40.71428097 ], [ -74.01248632, 40.71493988 ], [ -74.01237907, 40.71492231 ] ] ] } }, { "type": "Feature", "properties": { "height": 33.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01070811, 40.71402707 ], [ -74.01124997, 40.71427246 ], [ -74.01133837, 40.71431257 ], [ -74.01122231, 40.71474759 ], [ -74.01033082, 40.71433831 ], [ -74.01062214, 40.71398812 ], [ -74.01070811, 40.71402707 ] ] ] } }, { "type": "Feature", "properties": { "height": 81.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0075967, 40.7173397 ], [ -74.00744875, 40.71752728 ], [ -74.00644659, 40.7170696 ], [ -74.00677915, 40.71664807 ], [ -74.0073105, 40.7168908 ], [ -74.00713713, 40.71711052 ], [ -74.00712599, 40.71712468 ], [ -74.00722911, 40.7171718 ], [ -74.00719237, 40.7172183 ], [ -74.0073397, 40.71728557 ], [ -74.00737653, 40.71723907 ], [ -74.00744947, 40.71727236 ], [ -74.0075967, 40.7173397 ] ], [ [ -74.00704918, 40.71702541 ], [ -74.00669965, 40.71686636 ], [ -74.00666183, 40.7169145 ], [ -74.00686314, 40.71700601 ], [ -74.00682622, 40.71705387 ], [ -74.00697408, 40.71712107 ], [ -74.00704918, 40.71702541 ] ] ] } }, { "type": "Feature", "properties": { "height": 179.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00399455, 40.71576109 ], [ -74.00380815, 40.71566979 ], [ -74.0042812, 40.71510928 ], [ -74.00447003, 40.71520168 ], [ -74.00458573, 40.71525697 ], [ -74.00472254, 40.71532226 ], [ -74.00448, 40.71561409 ], [ -74.0042547, 40.71588529 ], [ -74.00399455, 40.71576109 ] ] ] } }, { "type": "Feature", "properties": { "height": 32.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00513182, 40.71421786 ], [ -74.00540589, 40.71388551 ], [ -74.00541173, 40.71387849 ], [ -74.00548647, 40.71391397 ], [ -74.00549222, 40.71390709 ], [ -74.00611637, 40.71420288 ], [ -74.00583089, 40.71454918 ], [ -74.00513182, 40.71421786 ] ] ] } }, { "type": "Feature", "properties": { "height": 228.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01451957, 40.71524689 ], [ -74.01445067, 40.715217 ], [ -74.01401193, 40.71502308 ], [ -74.01409548, 40.71491366 ], [ -74.01442498, 40.71448681 ], [ -74.01451337, 40.71437072 ], [ -74.0145396, 40.71439591 ], [ -74.01457158, 40.7144401 ], [ -74.01460473, 40.71449178 ], [ -74.0146297, 40.71453829 ], [ -74.01465153, 40.71458826 ], [ -74.01466977, 40.7146441 ], [ -74.01468181, 40.71469789 ], [ -74.0146889, 40.71475181 ], [ -74.01469043, 40.71481418 ], [ -74.01468881, 40.71485592 ], [ -74.01468306, 40.71490535 ], [ -74.01466887, 40.71496841 ], [ -74.01464812, 40.71503588 ], [ -74.01462503, 40.71509171 ], [ -74.01459952, 40.71514101 ], [ -74.0145697, 40.71518561 ], [ -74.01454257, 40.71522102 ], [ -74.01451957, 40.71524689 ] ] ] } }, { "type": "Feature", "properties": { "height": 87.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01237907, 40.71492231 ], [ -74.01227181, 40.71490461 ], [ -74.01216473, 40.71488697 ], [ -74.01205747, 40.71486927 ], [ -74.01225681, 40.71410306 ], [ -74.01235715, 40.71414691 ], [ -74.01245731, 40.71419069 ], [ -74.01255747, 40.71423461 ], [ -74.01266392, 40.71428097 ], [ -74.01248632, 40.71493988 ], [ -74.01237907, 40.71492231 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01240179, 40.71683347 ], [ -74.01195479, 40.71662996 ], [ -74.01195713, 40.7166271 ], [ -74.01195308, 40.7166252 ], [ -74.01205657, 40.71649351 ], [ -74.01217084, 40.71634828 ], [ -74.01226085, 40.7162339 ], [ -74.0122648, 40.71623567 ], [ -74.01226839, 40.71623131 ], [ -74.01261739, 40.71639016 ], [ -74.01274935, 40.71645021 ], [ -74.01264649, 40.71688011 ], [ -74.01255082, 40.71683647 ], [ -74.01253789, 40.71689659 ], [ -74.01240054, 40.71683926 ], [ -74.01240179, 40.71683347 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00633816, 40.71659129 ], [ -74.00636979, 40.71660531 ], [ -74.00634113, 40.71664249 ], [ -74.00632882, 40.71663711 ], [ -74.00632038, 40.71664787 ], [ -74.0063334, 40.71665366 ], [ -74.0063052, 40.71669022 ], [ -74.00628921, 40.71668307 ], [ -74.00627699, 40.71669887 ], [ -74.00628957, 40.71670459 ], [ -74.00626423, 40.71673747 ], [ -74.00624761, 40.71673012 ], [ -74.00623513, 40.71674639 ], [ -74.00625148, 40.71675361 ], [ -74.00622444, 40.71678881 ], [ -74.00619183, 40.71677431 ], [ -74.00617557, 40.71676716 ], [ -74.0061276, 40.71682932 ], [ -74.00604415, 40.71679228 ], [ -74.00598279, 40.71676512 ], [ -74.00599034, 40.71675551 ], [ -74.0059712, 40.716747 ], [ -74.00596267, 40.71675797 ], [ -74.00590599, 40.71673277 ], [ -74.0059129, 40.71672392 ], [ -74.0058944, 40.71671568 ], [ -74.00588694, 40.71672549 ], [ -74.0058308, 40.71670057 ], [ -74.00583978, 40.71668886 ], [ -74.00582118, 40.71668069 ], [ -74.00581319, 40.7166911 ], [ -74.00575731, 40.71666632 ], [ -74.00565652, 40.71662159 ], [ -74.0055975, 40.71659537 ], [ -74.00560739, 40.71658257 ], [ -74.00559652, 40.71657767 ], [ -74.00558717, 40.71658972 ], [ -74.00552869, 40.71656371 ], [ -74.00542961, 40.7165198 ], [ -74.00543778, 40.71650931 ], [ -74.00542799, 40.71650489 ], [ -74.00546653, 40.71645498 ], [ -74.00548117, 40.71646158 ], [ -74.0054915, 40.71644817 ], [ -74.00547731, 40.71644197 ], [ -74.0055039, 40.71640759 ], [ -74.00551971, 40.7164146 ], [ -74.00552995, 40.71640126 ], [ -74.00551585, 40.71639506 ], [ -74.00554235, 40.71636068 ], [ -74.00555744, 40.71636742 ], [ -74.00556957, 40.71635148 ], [ -74.00555492, 40.71634502 ], [ -74.00557891, 40.71631397 ], [ -74.00559418, 40.71632078 ], [ -74.0056081, 40.7163028 ], [ -74.00559095, 40.71629518 ], [ -74.00561852, 40.7162595 ], [ -74.00563757, 40.71626801 ], [ -74.00568069, 40.71621211 ], [ -74.00571905, 40.71622906 ], [ -74.00576531, 40.71624956 ], [ -74.00581633, 40.7162723 ], [ -74.00582415, 40.7162757 ], [ -74.00581427, 40.71628837 ], [ -74.00582532, 40.71629327 ], [ -74.00583484, 40.71628088 ], [ -74.00589341, 40.71630689 ], [ -74.00599681, 40.71635278 ], [ -74.00605789, 40.71637988 ], [ -74.0060507, 40.7163892 ], [ -74.00606984, 40.71639772 ], [ -74.00607837, 40.71638662 ], [ -74.00613515, 40.71641181 ], [ -74.00612832, 40.71642059 ], [ -74.00614673, 40.71642876 ], [ -74.00615437, 40.71641889 ], [ -74.00621051, 40.71644381 ], [ -74.00620162, 40.71645532 ], [ -74.00622013, 40.71646356 ], [ -74.00622911, 40.71645191 ], [ -74.00628498, 40.71647677 ], [ -74.00637527, 40.7165168 ], [ -74.00632298, 40.71658448 ], [ -74.00633816, 40.71659129 ] ] ] } }, { "type": "Feature", "properties": { "height": 47.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01128384, 40.71434546 ], [ -74.01119059, 40.71470136 ], [ -74.0103716, 40.71432809 ], [ -74.01060687, 40.71403789 ], [ -74.01128384, 40.71434546 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01143431, 40.71878857 ], [ -74.01138948, 40.71878278 ], [ -74.0112153, 40.71876249 ], [ -74.01129228, 40.71841049 ], [ -74.0112577, 40.71836841 ], [ -74.01126282, 40.7183452 ], [ -74.01124629, 40.71832661 ], [ -74.01126084, 40.71826057 ], [ -74.01121368, 40.71825471 ], [ -74.01084825, 40.71820841 ], [ -74.01084322, 40.71823122 ], [ -74.0107091, 40.71821427 ], [ -74.0107594, 40.71798441 ], [ -74.0113239, 40.71805576 ], [ -74.01158702, 40.71808906 ], [ -74.01143431, 40.71878857 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00407145, 40.71662036 ], [ -74.00396041, 40.71675279 ], [ -74.00274535, 40.71615941 ], [ -74.00277652, 40.71612291 ], [ -74.00290705, 40.71597006 ], [ -74.00407145, 40.71662036 ] ] ] } }, { "type": "Feature", "properties": { "height": 57.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00402887, 40.71616281 ], [ -74.00389807, 40.71632268 ], [ -74.0038307, 40.71629068 ], [ -74.00376225, 40.7163745 ], [ -74.00295188, 40.71592287 ], [ -74.00311905, 40.71573188 ], [ -74.00402887, 40.71616281 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00517503, 40.71700172 ], [ -74.00499339, 40.71723042 ], [ -74.00422497, 40.71687719 ], [ -74.00443922, 40.71660736 ], [ -74.00491613, 40.7168266 ], [ -74.0049341, 40.71680386 ], [ -74.00499833, 40.71683341 ], [ -74.00496015, 40.71688148 ], [ -74.00494775, 40.7168972 ], [ -74.00517503, 40.71700172 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01111639, 40.71398887 ], [ -74.01075294, 40.713826 ], [ -74.01104094, 40.71345388 ], [ -74.01140475, 40.71361689 ], [ -74.01138194, 40.71364638 ], [ -74.01144787, 40.71367048 ], [ -74.01140745, 40.71411926 ], [ -74.01111639, 40.71398887 ] ] ] } }, { "type": "Feature", "properties": { "height": 168.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00633816, 40.71659129 ], [ -74.00630915, 40.7166271 ], [ -74.00629774, 40.71662179 ], [ -74.00628903, 40.71663248 ], [ -74.0063025, 40.71663881 ], [ -74.00627322, 40.7166749 ], [ -74.00625813, 40.71666789 ], [ -74.00624555, 40.71668348 ], [ -74.00625857, 40.71668961 ], [ -74.00623234, 40.71672208 ], [ -74.00621662, 40.7167148 ], [ -74.0062036, 40.71673087 ], [ -74.00622049, 40.71673877 ], [ -74.00619183, 40.71677431 ], [ -74.00617557, 40.71676716 ], [ -74.0061276, 40.71682932 ], [ -74.00604415, 40.71679228 ], [ -74.00607882, 40.716747 ], [ -74.00601774, 40.71672011 ], [ -74.00602519, 40.71671017 ], [ -74.00600615, 40.71670166 ], [ -74.0059977, 40.71671262 ], [ -74.00594093, 40.71668756 ], [ -74.00594785, 40.71667858 ], [ -74.00592934, 40.71667041 ], [ -74.00592189, 40.71668007 ], [ -74.00586574, 40.71665536 ], [ -74.00587472, 40.71664358 ], [ -74.00585613, 40.71663541 ], [ -74.00584751, 40.71664678 ], [ -74.00579127, 40.716622 ], [ -74.00575731, 40.71666632 ], [ -74.00565652, 40.71662159 ], [ -74.00569012, 40.71657767 ], [ -74.00563029, 40.71655132 ], [ -74.00563972, 40.71653907 ], [ -74.00562868, 40.71653416 ], [ -74.00561978, 40.71654581 ], [ -74.00556202, 40.71652027 ], [ -74.00552869, 40.71656371 ], [ -74.00542961, 40.7165198 ], [ -74.00543778, 40.71650931 ], [ -74.00542799, 40.71650489 ], [ -74.00546653, 40.71645498 ], [ -74.00548117, 40.71646158 ], [ -74.0054915, 40.71644817 ], [ -74.00547731, 40.71644197 ], [ -74.0055039, 40.71640759 ], [ -74.00551971, 40.7164146 ], [ -74.00552995, 40.71640126 ], [ -74.00551585, 40.71639506 ], [ -74.00554235, 40.71636068 ], [ -74.00555744, 40.71636742 ], [ -74.00556957, 40.71635148 ], [ -74.00555492, 40.71634502 ], [ -74.00557891, 40.71631397 ], [ -74.00559418, 40.71632078 ], [ -74.0056081, 40.7163028 ], [ -74.00559095, 40.71629518 ], [ -74.00561852, 40.7162595 ], [ -74.00563757, 40.71626801 ], [ -74.00568069, 40.71621211 ], [ -74.00571905, 40.71622906 ], [ -74.00576531, 40.71624956 ], [ -74.00573162, 40.71629347 ], [ -74.00579172, 40.71631996 ], [ -74.00578238, 40.71633208 ], [ -74.00579343, 40.71633691 ], [ -74.00580241, 40.7163252 ], [ -74.0058599, 40.7163506 ], [ -74.00589341, 40.71630689 ], [ -74.00599681, 40.71635278 ], [ -74.00596222, 40.71639778 ], [ -74.00602349, 40.71642481 ], [ -74.00601603, 40.71643462 ], [ -74.00603507, 40.71644299 ], [ -74.00604361, 40.71643196 ], [ -74.00610038, 40.71645709 ], [ -74.00609364, 40.71646601 ], [ -74.00611197, 40.71647411 ], [ -74.0061196, 40.71646431 ], [ -74.00617584, 40.71648909 ], [ -74.00616677, 40.71650066 ], [ -74.00618545, 40.7165089 ], [ -74.00619408, 40.71649746 ], [ -74.00625022, 40.71652218 ], [ -74.00628498, 40.71647677 ], [ -74.00637527, 40.7165168 ], [ -74.00632298, 40.71658448 ], [ -74.00633816, 40.71659129 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01195641, 40.7160822 ], [ -74.01182921, 40.71656998 ], [ -74.01164074, 40.7164848 ], [ -74.01164568, 40.7164784 ], [ -74.01169087, 40.71642039 ], [ -74.01166374, 40.7164082 ], [ -74.01175653, 40.71628912 ], [ -74.01172913, 40.71627666 ], [ -74.01176408, 40.71623179 ], [ -74.01171081, 40.71620782 ], [ -74.01169599, 40.71622668 ], [ -74.01169383, 40.71623376 ], [ -74.01169167, 40.7162371 ], [ -74.01168557, 40.71624261 ], [ -74.0116817, 40.71624479 ], [ -74.0116729, 40.71624772 ], [ -74.01166338, 40.71624826 ], [ -74.01165871, 40.71624779 ], [ -74.01164981, 40.71624506 ], [ -74.01164595, 40.71624302 ], [ -74.01163957, 40.71623757 ], [ -74.0116358, 40.7162309 ], [ -74.0116349, 40.71622368 ], [ -74.01163562, 40.71622007 ], [ -74.01163005, 40.7162181 ], [ -74.01158127, 40.71621749 ], [ -74.01154902, 40.71621456 ], [ -74.01150132, 40.71620659 ], [ -74.01147051, 40.71619897 ], [ -74.01142622, 40.71618419 ], [ -74.01138499, 40.7161656 ], [ -74.01134762, 40.71614361 ], [ -74.01132525, 40.7161272 ], [ -74.01130504, 40.71610957 ], [ -74.01128707, 40.71609091 ], [ -74.01127171, 40.71607117 ], [ -74.01125905, 40.71605081 ], [ -74.0112489, 40.7160297 ], [ -74.01130414, 40.71581917 ], [ -74.01130738, 40.71581972 ], [ -74.01130818, 40.71581679 ], [ -74.01130693, 40.71581141 ], [ -74.01130863, 40.71580617 ], [ -74.01131061, 40.71580392 ], [ -74.01131627, 40.71580058 ], [ -74.01132319, 40.7157995 ], [ -74.01133019, 40.71580072 ], [ -74.01133567, 40.71580406 ], [ -74.01133882, 40.71580896 ], [ -74.01134484, 40.71580596 ], [ -74.01195641, 40.7160822 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01237907, 40.71492231 ], [ -74.01227181, 40.71490461 ], [ -74.01216473, 40.71488697 ], [ -74.01235715, 40.71414691 ], [ -74.01245731, 40.71419069 ], [ -74.01255747, 40.71423461 ], [ -74.01266392, 40.71428097 ], [ -74.01248632, 40.71493988 ], [ -74.01237907, 40.71492231 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00710631, 40.71796507 ], [ -74.00697525, 40.71813502 ], [ -74.00635829, 40.71784905 ], [ -74.00654523, 40.71761559 ], [ -74.00662257, 40.71764888 ], [ -74.00681391, 40.7174214 ], [ -74.00695594, 40.71749358 ], [ -74.00677654, 40.71771656 ], [ -74.00687248, 40.71776129 ], [ -74.0069492, 40.71779697 ], [ -74.00698145, 40.71781208 ], [ -74.00700337, 40.7178223 ], [ -74.00699537, 40.71783217 ], [ -74.00694875, 40.71789018 ], [ -74.00695468, 40.7178929 ], [ -74.00710631, 40.71796507 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01322797, 40.71442546 ], [ -74.01310895, 40.71493007 ], [ -74.01269033, 40.71473159 ], [ -74.01281681, 40.7142472 ], [ -74.0128178, 40.71424359 ], [ -74.01322797, 40.71442546 ] ] ] } }, { "type": "Feature", "properties": { "height": 81.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01452442, 40.71782502 ], [ -74.01464219, 40.71767489 ], [ -74.01465378, 40.71766012 ], [ -74.01491339, 40.71777818 ], [ -74.01493253, 40.7177713 ], [ -74.01495265, 40.71776626 ], [ -74.0149734, 40.71776327 ], [ -74.01499442, 40.71776231 ], [ -74.01502155, 40.71776388 ], [ -74.01504212, 40.71776749 ], [ -74.0150715, 40.71777641 ], [ -74.01522592, 40.71768435 ], [ -74.01521657, 40.71766951 ], [ -74.01521298, 40.71765807 ], [ -74.01521271, 40.71764146 ], [ -74.01521828, 40.71762437 ], [ -74.01528458, 40.71753988 ], [ -74.01559557, 40.71768109 ], [ -74.0155556, 40.71771418 ], [ -74.01551832, 40.71774216 ], [ -74.0154416, 40.71779649 ], [ -74.01536192, 40.71784817 ], [ -74.01529482, 40.71788861 ], [ -74.0152102, 40.71793546 ], [ -74.01512315, 40.71797978 ], [ -74.01505021, 40.71801376 ], [ -74.01503727, 40.71801852 ], [ -74.0150238, 40.71802186 ], [ -74.01500987, 40.71802397 ], [ -74.01499568, 40.71802472 ], [ -74.01497843, 40.7180237 ], [ -74.01496451, 40.71802138 ], [ -74.01495112, 40.71801791 ], [ -74.01493908, 40.71801341 ], [ -74.01452442, 40.71782502 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01008378, 40.7139745 ], [ -74.00991822, 40.71418687 ], [ -74.00902799, 40.71378521 ], [ -74.0091675, 40.71360607 ], [ -74.00943762, 40.71372802 ], [ -74.00998218, 40.71397382 ], [ -74.00999341, 40.71395939 ], [ -74.01000823, 40.71394039 ], [ -74.01008378, 40.7139745 ] ] ] } }, { "type": "Feature", "properties": { "height": 33.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00395619, 40.71505447 ], [ -74.00392861, 40.71508702 ], [ -74.00391298, 40.7151054 ], [ -74.00342053, 40.71486307 ], [ -74.00348745, 40.71478429 ], [ -74.00344263, 40.7147623 ], [ -74.00342825, 40.71475522 ], [ -74.00334588, 40.71471471 ], [ -74.00345457, 40.71458677 ], [ -74.00354387, 40.71463068 ], [ -74.00347739, 40.71470899 ], [ -74.00352958, 40.71473466 ], [ -74.00366163, 40.71457928 ], [ -74.00393939, 40.71471586 ], [ -74.00415409, 40.71482147 ], [ -74.00395619, 40.71505447 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01527685, 40.71670629 ], [ -74.0150441, 40.71700288 ], [ -74.01524595, 40.71709452 ], [ -74.01511408, 40.71726249 ], [ -74.01469214, 40.71707076 ], [ -74.01494394, 40.7167498 ], [ -74.01505658, 40.7166062 ], [ -74.01527685, 40.71670629 ] ] ] } }, { "type": "Feature", "properties": { "height": 59.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01138194, 40.71364638 ], [ -74.0113434, 40.7136952 ], [ -74.01122913, 40.71384302 ], [ -74.01118017, 40.71390628 ], [ -74.01115044, 40.71394488 ], [ -74.01111639, 40.71398887 ], [ -74.01075294, 40.713826 ], [ -74.01104094, 40.71345388 ], [ -74.01140475, 40.71361689 ], [ -74.01138194, 40.71364638 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00540589, 40.71388551 ], [ -74.00513182, 40.71421786 ], [ -74.00512292, 40.71422861 ], [ -74.00497165, 40.71415691 ], [ -74.00486133, 40.71410462 ], [ -74.00474851, 40.71405117 ], [ -74.00503148, 40.71370806 ], [ -74.00512903, 40.71375437 ], [ -74.00524752, 40.71381047 ], [ -74.00540589, 40.71388551 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0148056, 40.71618269 ], [ -74.0147402, 40.71626386 ], [ -74.01473642, 40.71626862 ], [ -74.01467211, 40.71623812 ], [ -74.01467615, 40.71623322 ], [ -74.01453493, 40.71616601 ], [ -74.01475484, 40.71587541 ], [ -74.01457104, 40.71576511 ], [ -74.01467552, 40.7156367 ], [ -74.01468657, 40.71562281 ], [ -74.01510042, 40.71581829 ], [ -74.0148056, 40.71618269 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00689629, 40.71600819 ], [ -74.00657757, 40.7164176 ], [ -74.00626612, 40.7162772 ], [ -74.00658484, 40.71586779 ], [ -74.00689629, 40.71600819 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01488743, 40.71735951 ], [ -74.01482167, 40.71744326 ], [ -74.01476787, 40.71751176 ], [ -74.01465764, 40.71746171 ], [ -74.01453017, 40.71762396 ], [ -74.01464219, 40.71767489 ], [ -74.01452442, 40.71782502 ], [ -74.01421244, 40.71768327 ], [ -74.01457697, 40.71721851 ], [ -74.01488743, 40.71735951 ] ] ] } }, { "type": "Feature", "properties": { "height": 71.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00610469, 40.71528618 ], [ -74.00600588, 40.7154135 ], [ -74.00557307, 40.71521911 ], [ -74.00580546, 40.71494171 ], [ -74.00583682, 40.71495928 ], [ -74.00616201, 40.715067 ], [ -74.00617063, 40.71509648 ], [ -74.00622183, 40.71512746 ], [ -74.00610029, 40.7152842 ], [ -74.00610469, 40.71528618 ] ] ] } }, { "type": "Feature", "properties": { "height": 58.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01124997, 40.71427246 ], [ -74.01111091, 40.71444766 ], [ -74.01096539, 40.71438127 ], [ -74.01089011, 40.71447598 ], [ -74.01058881, 40.71433858 ], [ -74.01066463, 40.71424312 ], [ -74.01057058, 40.71420029 ], [ -74.01070811, 40.71402707 ], [ -74.01124997, 40.71427246 ] ] ] } }, { "type": "Feature", "properties": { "height": 165.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00447003, 40.71520168 ], [ -74.0042812, 40.71510928 ], [ -74.00380815, 40.71566979 ], [ -74.00399455, 40.71576109 ], [ -74.00393733, 40.71582986 ], [ -74.00383178, 40.71577948 ], [ -74.00362651, 40.7156815 ], [ -74.00406399, 40.71515429 ], [ -74.00409103, 40.71512147 ], [ -74.00421841, 40.71496929 ], [ -74.00442179, 40.71506639 ], [ -74.00453677, 40.71512127 ], [ -74.00447003, 40.71520168 ] ] ] } }, { "type": "Feature", "properties": { "height": 42.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00855988, 40.71376921 ], [ -74.00822867, 40.71419191 ], [ -74.00783952, 40.71401529 ], [ -74.0079731, 40.71384472 ], [ -74.00812833, 40.7139152 ], [ -74.00813884, 40.71390178 ], [ -74.00832587, 40.71366299 ], [ -74.00855988, 40.71376921 ] ], [ [ -74.00833602, 40.71391451 ], [ -74.00826316, 40.71388135 ], [ -74.00821699, 40.71394039 ], [ -74.00828984, 40.71397341 ], [ -74.00833602, 40.71391451 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01134546, 40.71795656 ], [ -74.0113239, 40.71805576 ], [ -74.0107594, 40.71798441 ], [ -74.01083603, 40.7176339 ], [ -74.01095973, 40.71764956 ], [ -74.0109715, 40.71765106 ], [ -74.01095398, 40.7177314 ], [ -74.01101111, 40.71773862 ], [ -74.01101497, 40.71772078 ], [ -74.011187, 40.71774257 ], [ -74.01119482, 40.71770648 ], [ -74.01131645, 40.71772187 ], [ -74.01130297, 40.71778308 ], [ -74.01127764, 40.71777988 ], [ -74.01126848, 40.71782162 ], [ -74.01129291, 40.71782461 ], [ -74.01127584, 40.71790271 ], [ -74.01125258, 40.71789978 ], [ -74.01124315, 40.71794356 ], [ -74.01134546, 40.71795656 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01475861, 40.71308558 ], [ -74.01492633, 40.71314366 ], [ -74.01494474, 40.71320699 ], [ -74.01491627, 40.71324662 ], [ -74.01473804, 40.7131728 ], [ -74.01436165, 40.71369622 ], [ -74.01503368, 40.71397382 ], [ -74.01510608, 40.71387291 ], [ -74.01516043, 40.71389497 ], [ -74.01517211, 40.71395557 ], [ -74.01514318, 40.71399527 ], [ -74.01512504, 40.71402026 ], [ -74.01503341, 40.7140432 ], [ -74.01499262, 40.71402611 ], [ -74.01497223, 40.7140541 ], [ -74.01468432, 40.71393297 ], [ -74.0146898, 40.71392541 ], [ -74.01460338, 40.71388912 ], [ -74.01460087, 40.71389252 ], [ -74.01432104, 40.71375866 ], [ -74.01441231, 40.71352402 ], [ -74.0143974, 40.71352068 ], [ -74.01440243, 40.71350706 ], [ -74.01438429, 40.71350318 ], [ -74.01439012, 40.71348766 ], [ -74.01437045, 40.7134835 ], [ -74.01443073, 40.71332158 ], [ -74.0144504, 40.7133258 ], [ -74.01445543, 40.71331225 ], [ -74.01447358, 40.71331627 ], [ -74.01447915, 40.71330136 ], [ -74.01449981, 40.71330592 ], [ -74.01450421, 40.71329407 ], [ -74.01459647, 40.7132983 ], [ -74.0146651, 40.71312671 ], [ -74.01475861, 40.71308558 ] ] ] } }, { "type": "Feature", "properties": { "height": 84.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0042335, 40.71418851 ], [ -74.0040471, 40.71410319 ], [ -74.00407693, 40.71406547 ], [ -74.00395709, 40.71401059 ], [ -74.00389708, 40.71408637 ], [ -74.0037724, 40.71424421 ], [ -74.00356821, 40.71409631 ], [ -74.00367727, 40.71383512 ], [ -74.00376961, 40.71380632 ], [ -74.00433681, 40.71406601 ], [ -74.0042335, 40.71418851 ] ] ] } }, { "type": "Feature", "properties": { "height": 82.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01362027, 40.71741569 ], [ -74.01386236, 40.71710596 ], [ -74.01360203, 40.7169881 ], [ -74.01371324, 40.71684199 ], [ -74.01372169, 40.71683116 ], [ -74.01414542, 40.71702296 ], [ -74.01378143, 40.71748861 ], [ -74.01362027, 40.71741569 ] ] ] } }, { "type": "Feature", "properties": { "height": 95.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01237907, 40.71492231 ], [ -74.01227181, 40.71490461 ], [ -74.01245731, 40.71419069 ], [ -74.01255747, 40.71423461 ], [ -74.01266392, 40.71428097 ], [ -74.01248632, 40.71493988 ], [ -74.01237907, 40.71492231 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01485015, 40.71453611 ], [ -74.01451337, 40.71437072 ], [ -74.01442498, 40.71448681 ], [ -74.01416573, 40.71444936 ], [ -74.01425493, 40.71410462 ], [ -74.01495463, 40.714413 ], [ -74.01485015, 40.71453611 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00737895, 40.71432918 ], [ -74.00729846, 40.71443016 ], [ -74.00728661, 40.71444507 ], [ -74.00727484, 40.71445998 ], [ -74.00724942, 40.71449192 ], [ -74.00723747, 40.71450676 ], [ -74.00709293, 40.71444017 ], [ -74.00688183, 40.71434287 ], [ -74.00680089, 40.71430556 ], [ -74.00666353, 40.7142423 ], [ -74.00650732, 40.71417026 ], [ -74.00659984, 40.71405396 ], [ -74.00667575, 40.71408896 ], [ -74.00688704, 40.71418626 ], [ -74.00689844, 40.71417196 ], [ -74.00693581, 40.71412498 ], [ -74.0069642, 40.71413799 ], [ -74.00697175, 40.71414146 ], [ -74.0069987, 40.71415378 ], [ -74.00710452, 40.7142026 ], [ -74.00713892, 40.71421847 ], [ -74.00737895, 40.71432918 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00590661, 40.71726419 ], [ -74.00583789, 40.7172326 ], [ -74.00585694, 40.71720857 ], [ -74.00569605, 40.71713456 ], [ -74.00564502, 40.7171989 ], [ -74.00533304, 40.71705551 ], [ -74.00550902, 40.71683382 ], [ -74.0060507, 40.71708281 ], [ -74.00590661, 40.71726419 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0146368, 40.71641426 ], [ -74.01426903, 40.71688611 ], [ -74.0140414, 40.71678336 ], [ -74.01408964, 40.71672161 ], [ -74.01407517, 40.71671507 ], [ -74.01409629, 40.71668797 ], [ -74.01408739, 40.71668396 ], [ -74.01415369, 40.71659891 ], [ -74.01416258, 40.716603 ], [ -74.01418728, 40.71657127 ], [ -74.01420175, 40.71657781 ], [ -74.01428439, 40.71647179 ], [ -74.01429805, 40.71647799 ], [ -74.01442291, 40.71631771 ], [ -74.0146368, 40.71641426 ] ] ] } }, { "type": "Feature", "properties": { "height": 33.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0075967, 40.7173397 ], [ -74.00744947, 40.71727236 ], [ -74.0074607, 40.71725827 ], [ -74.00713713, 40.71711052 ], [ -74.0073105, 40.7168908 ], [ -74.00778122, 40.71710575 ], [ -74.0075967, 40.7173397 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00540589, 40.71388551 ], [ -74.00513182, 40.71421786 ], [ -74.00512292, 40.71422861 ], [ -74.00497165, 40.71415691 ], [ -74.00505447, 40.7140509 ], [ -74.00494299, 40.7139999 ], [ -74.00486133, 40.71410462 ], [ -74.00474851, 40.71405117 ], [ -74.00503148, 40.71370806 ], [ -74.00512903, 40.71375437 ], [ -74.00502671, 40.71388292 ], [ -74.00514628, 40.7139376 ], [ -74.00524752, 40.71381047 ], [ -74.00540589, 40.71388551 ] ] ] } }, { "type": "Feature", "properties": { "height": 42.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01234125, 40.71574809 ], [ -74.01233595, 40.71577321 ], [ -74.01229687, 40.71595821 ], [ -74.01229202, 40.71598129 ], [ -74.01176588, 40.71574312 ], [ -74.01177127, 40.71572038 ], [ -74.01181403, 40.71554049 ], [ -74.01182067, 40.71551209 ], [ -74.01234125, 40.71574809 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01134546, 40.71795656 ], [ -74.01124315, 40.71794356 ], [ -74.01125258, 40.71789978 ], [ -74.01127584, 40.71790271 ], [ -74.01129291, 40.71782461 ], [ -74.01126848, 40.71782162 ], [ -74.01127764, 40.71777988 ], [ -74.01130297, 40.71778308 ], [ -74.01131645, 40.71772187 ], [ -74.01119482, 40.71770648 ], [ -74.011187, 40.71774257 ], [ -74.01101497, 40.71772078 ], [ -74.01101111, 40.71773862 ], [ -74.01095398, 40.7177314 ], [ -74.0109715, 40.71765106 ], [ -74.01095973, 40.71764956 ], [ -74.01097635, 40.71756806 ], [ -74.01098102, 40.71754662 ], [ -74.01115583, 40.71756868 ], [ -74.01115143, 40.71758849 ], [ -74.01139281, 40.71761899 ], [ -74.01139694, 40.7176002 ], [ -74.01145039, 40.71760701 ], [ -74.01144212, 40.717645 ], [ -74.0115731, 40.71766161 ], [ -74.01156097, 40.71771036 ], [ -74.01153977, 40.71770737 ], [ -74.01150815, 40.71784422 ], [ -74.01152818, 40.71784797 ], [ -74.01149647, 40.71798761 ], [ -74.01135777, 40.71797181 ], [ -74.01136101, 40.7179584 ], [ -74.01134546, 40.71795656 ] ] ] } }, { "type": "Feature", "properties": { "height": 113.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00858943, 40.7176288 ], [ -74.00843618, 40.71782025 ], [ -74.00841938, 40.71784116 ], [ -74.00812734, 40.71770669 ], [ -74.00800472, 40.71765058 ], [ -74.00802152, 40.717629 ], [ -74.00817468, 40.71743747 ], [ -74.00819157, 40.71741698 ], [ -74.0083141, 40.71747322 ], [ -74.00860641, 40.71760762 ], [ -74.00858943, 40.7176288 ] ] ] } }, { "type": "Feature", "properties": { "height": 120.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01285023, 40.71598 ], [ -74.01279633, 40.71620809 ], [ -74.01229202, 40.71598129 ], [ -74.01229687, 40.71595821 ], [ -74.01233595, 40.71577321 ], [ -74.01234125, 40.71574809 ], [ -74.01285023, 40.71598 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00550902, 40.71683382 ], [ -74.00533304, 40.71705551 ], [ -74.00531292, 40.71708077 ], [ -74.00543033, 40.71713476 ], [ -74.00525794, 40.71735196 ], [ -74.00499339, 40.71723042 ], [ -74.00517503, 40.71700172 ], [ -74.00518742, 40.71698599 ], [ -74.0052009, 40.7169691 ], [ -74.00536188, 40.7167662 ], [ -74.00550902, 40.71683382 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01057938, 40.71525322 ], [ -74.0106525, 40.71515905 ], [ -74.01083333, 40.71524042 ], [ -74.01084367, 40.71522599 ], [ -74.0108495, 40.71522292 ], [ -74.01085642, 40.7152219 ], [ -74.01088678, 40.71522619 ], [ -74.01093817, 40.71503391 ], [ -74.01087061, 40.71500347 ], [ -74.01096332, 40.71488411 ], [ -74.01108163, 40.71493729 ], [ -74.01110597, 40.71493749 ], [ -74.01111864, 40.71493988 ], [ -74.01113023, 40.71494451 ], [ -74.01114011, 40.71495091 ], [ -74.01114442, 40.71495458 ], [ -74.01115098, 40.71496316 ], [ -74.01115502, 40.71497256 ], [ -74.0111561, 40.7149825 ], [ -74.01115439, 40.7149923 ], [ -74.01114981, 40.7150015 ], [ -74.01114271, 40.7150098 ], [ -74.01113328, 40.71501668 ], [ -74.01112789, 40.71501947 ], [ -74.01103599, 40.71536346 ], [ -74.01104273, 40.7153721 ], [ -74.01104659, 40.7153817 ], [ -74.01104758, 40.71539171 ], [ -74.01104686, 40.71539668 ], [ -74.01104327, 40.71540642 ], [ -74.01103689, 40.71541507 ], [ -74.011028, 40.71542256 ], [ -74.0110227, 40.71542562 ], [ -74.01101102, 40.71543032 ], [ -74.01100473, 40.71543182 ], [ -74.01099162, 40.71543318 ], [ -74.0109785, 40.71543229 ], [ -74.01096593, 40.71542909 ], [ -74.01096009, 40.71542671 ], [ -74.01094985, 40.71542038 ], [ -74.01094158, 40.71541262 ], [ -74.01093844, 40.71540805 ], [ -74.01093457, 40.71541296 ], [ -74.01077414, 40.71534078 ], [ -74.01077261, 40.71533622 ], [ -74.01077297, 40.71532921 ], [ -74.0108124, 40.71527848 ], [ -74.01077243, 40.71526051 ], [ -74.01073218, 40.71531232 ], [ -74.01072895, 40.7153145 ], [ -74.01072024, 40.7153162 ], [ -74.01057938, 40.71525322 ] ] ] } }, { "type": "Feature", "properties": { "height": 250.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00654523, 40.71761559 ], [ -74.00635829, 40.71784905 ], [ -74.00597039, 40.71766801 ], [ -74.00614215, 40.71744489 ], [ -74.00620791, 40.71747451 ], [ -74.00625615, 40.71749616 ], [ -74.00630322, 40.71751727 ], [ -74.00632891, 40.71748418 ], [ -74.00648549, 40.71755458 ], [ -74.00646671, 40.71757882 ], [ -74.00654523, 40.71761559 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00609589, 40.71790597 ], [ -74.00598881, 40.71804249 ], [ -74.00595072, 40.71809096 ], [ -74.00593644, 40.71810921 ], [ -74.00591515, 40.71813638 ], [ -74.00587059, 40.71811656 ], [ -74.005859, 40.71813127 ], [ -74.00585388, 40.71813767 ], [ -74.00582002, 40.71812222 ], [ -74.00580007, 40.71814761 ], [ -74.00583412, 40.71816266 ], [ -74.00571905, 40.7183085 ], [ -74.00568473, 40.71835187 ], [ -74.00550372, 40.71826976 ], [ -74.00568877, 40.71803398 ], [ -74.00586978, 40.7178033 ], [ -74.00609589, 40.71790597 ] ] ] } }, { "type": "Feature", "properties": { "height": 33.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01074683, 40.71654002 ], [ -74.01054462, 40.71644837 ], [ -74.01059115, 40.716389 ], [ -74.01058181, 40.71637518 ], [ -74.01038274, 40.71628496 ], [ -74.01033342, 40.71634801 ], [ -74.01039307, 40.71637661 ], [ -74.01038597, 40.7163841 ], [ -74.01024521, 40.71656412 ], [ -74.0100977, 40.71649726 ], [ -74.01023039, 40.71632779 ], [ -74.01023847, 40.71631737 ], [ -74.0102488, 40.716322 ], [ -74.01039289, 40.7161381 ], [ -74.0107585, 40.71630369 ], [ -74.0107577, 40.71630471 ], [ -74.01077521, 40.71631029 ], [ -74.01078483, 40.71631621 ], [ -74.01079183, 40.71632309 ], [ -74.01079453, 40.71632731 ], [ -74.01079794, 40.7163363 ], [ -74.01079848, 40.716341 ], [ -74.0107974, 40.71635026 ], [ -74.0107957, 40.71635482 ], [ -74.01079031, 40.7163632 ], [ -74.01079282, 40.7163636 ], [ -74.01074683, 40.71654002 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00786988, 40.71645382 ], [ -74.00779317, 40.71655146 ], [ -74.00777718, 40.71654417 ], [ -74.00768923, 40.71665618 ], [ -74.00770522, 40.71666346 ], [ -74.00754397, 40.71686868 ], [ -74.00731571, 40.71676491 ], [ -74.00749394, 40.71653811 ], [ -74.00751711, 40.71650849 ], [ -74.00764162, 40.71634999 ], [ -74.00786988, 40.71645382 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01119994, 40.71901706 ], [ -74.01119563, 40.71903667 ], [ -74.01117784, 40.71911749 ], [ -74.01116697, 40.71911619 ], [ -74.01114918, 40.71919728 ], [ -74.01109268, 40.7191902 ], [ -74.0110969, 40.71917141 ], [ -74.01092209, 40.71914928 ], [ -74.01093044, 40.7191115 ], [ -74.01081142, 40.71909638 ], [ -74.01079767, 40.71915888 ], [ -74.01082049, 40.71916167 ], [ -74.01081088, 40.71920511 ], [ -74.01078851, 40.71920232 ], [ -74.01077108, 40.7192813 ], [ -74.01079417, 40.71928416 ], [ -74.01078501, 40.71932617 ], [ -74.01077009, 40.7193244 ], [ -74.01068161, 40.71931316 ], [ -74.01067945, 40.71932317 ], [ -74.0105686, 40.71930921 ], [ -74.01054489, 40.71930622 ], [ -74.01057462, 40.71917127 ], [ -74.01059852, 40.71917427 ], [ -74.01063121, 40.71902578 ], [ -74.01060705, 40.71902278 ], [ -74.01061621, 40.71898091 ], [ -74.01072347, 40.71899446 ], [ -74.01073138, 40.7189583 ], [ -74.01078501, 40.71896511 ], [ -74.01078114, 40.71898282 ], [ -74.0110209, 40.71901311 ], [ -74.01102495, 40.71899487 ], [ -74.01119994, 40.71901706 ] ] ] } }, { "type": "Feature", "properties": { "height": 132.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01315755, 40.71379651 ], [ -74.01306762, 40.71391077 ], [ -74.01300241, 40.7139935 ], [ -74.01294662, 40.71396851 ], [ -74.01273327, 40.71387196 ], [ -74.01267785, 40.71384676 ], [ -74.01274324, 40.71376186 ], [ -74.01282634, 40.71365809 ], [ -74.01290045, 40.71356412 ], [ -74.01295605, 40.71358857 ], [ -74.01316931, 40.71368498 ], [ -74.01322492, 40.71371079 ], [ -74.01315755, 40.71379651 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0059809, 40.71592948 ], [ -74.00595539, 40.71596182 ], [ -74.00593824, 40.7159642 ], [ -74.00589512, 40.71601731 ], [ -74.00589619, 40.7160218 ], [ -74.00588757, 40.71603331 ], [ -74.00586987, 40.71603671 ], [ -74.0058599, 40.71603351 ], [ -74.00585523, 40.71602582 ], [ -74.00575489, 40.71598081 ], [ -74.00575282, 40.71596958 ], [ -74.0055834, 40.71589468 ], [ -74.00568329, 40.71576811 ], [ -74.00572704, 40.71570928 ], [ -74.00572165, 40.71570676 ], [ -74.0058564, 40.71553456 ], [ -74.0059606, 40.71558182 ], [ -74.00596617, 40.71559966 ], [ -74.00589134, 40.71569968 ], [ -74.00594273, 40.71572201 ], [ -74.00593743, 40.71572896 ], [ -74.00594551, 40.71573256 ], [ -74.00594812, 40.71572916 ], [ -74.00601819, 40.7157598 ], [ -74.00605017, 40.71577369 ], [ -74.00606148, 40.71577137 ], [ -74.00607747, 40.71577846 ], [ -74.0060799, 40.71579112 ], [ -74.00607155, 40.71580229 ], [ -74.00606247, 40.71580372 ], [ -74.00601944, 40.71586077 ], [ -74.00602528, 40.71587317 ], [ -74.0059809, 40.71592948 ] ] ] } }, { "type": "Feature", "properties": { "height": 73.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01362027, 40.71741569 ], [ -74.01345291, 40.71733991 ], [ -74.01358658, 40.71678466 ], [ -74.01371324, 40.71684199 ], [ -74.01360203, 40.7169881 ], [ -74.01386236, 40.71710596 ], [ -74.01362027, 40.71741569 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01003824, 40.71552272 ], [ -74.00996089, 40.71548806 ], [ -74.00988157, 40.71545252 ], [ -74.01005647, 40.7152266 ], [ -74.0104502, 40.71540322 ], [ -74.01027512, 40.715629 ], [ -74.01003824, 40.71552272 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00376225, 40.7163745 ], [ -74.0038307, 40.71629068 ], [ -74.00389807, 40.71632268 ], [ -74.00402887, 40.71616281 ], [ -74.00432989, 40.71630539 ], [ -74.00433232, 40.7163092 ], [ -74.00428237, 40.71636326 ], [ -74.00410792, 40.71656712 ], [ -74.00376225, 40.7163745 ] ] ] } }, { "type": "Feature", "properties": { "height": 241.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01297249, 40.71541847 ], [ -74.01277271, 40.71567612 ], [ -74.01244482, 40.71553 ], [ -74.01264461, 40.71527242 ], [ -74.01297249, 40.71541847 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00493248, 40.71434477 ], [ -74.00478992, 40.7145216 ], [ -74.00432594, 40.71430487 ], [ -74.0044685, 40.71412811 ], [ -74.00493248, 40.71434477 ] ] ] } }, { "type": "Feature", "properties": { "height": 31.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00991723, 40.71593948 ], [ -74.00983099, 40.71604958 ], [ -74.00979434, 40.71603297 ], [ -74.00978509, 40.71604482 ], [ -74.0097497, 40.71602882 ], [ -74.00973694, 40.71604516 ], [ -74.00973182, 40.71604277 ], [ -74.00972733, 40.71604856 ], [ -74.00969508, 40.71603406 ], [ -74.00968547, 40.71604638 ], [ -74.00970379, 40.71605462 ], [ -74.00967109, 40.71609636 ], [ -74.00965142, 40.71608751 ], [ -74.0096313, 40.71611331 ], [ -74.00970388, 40.71614606 ], [ -74.00969607, 40.716156 ], [ -74.00973425, 40.71617316 ], [ -74.00964927, 40.71628169 ], [ -74.00956617, 40.71624397 ], [ -74.00955907, 40.71625317 ], [ -74.0093733, 40.71616901 ], [ -74.00937735, 40.7161639 ], [ -74.00936621, 40.71615771 ], [ -74.00936153, 40.71615396 ], [ -74.00935372, 40.71614538 ], [ -74.0093486, 40.71613578 ], [ -74.00934662, 40.7161255 ], [ -74.00934671, 40.71612026 ], [ -74.00933998, 40.71611992 ], [ -74.00935372, 40.71597101 ], [ -74.00937052, 40.71597189 ], [ -74.00937483, 40.71592437 ], [ -74.00939423, 40.71593322 ], [ -74.00954713, 40.71600247 ], [ -74.00950167, 40.71606048 ], [ -74.00951057, 40.71606456 ], [ -74.00950275, 40.71607471 ], [ -74.00955261, 40.71609731 ], [ -74.00956428, 40.71608247 ], [ -74.00961082, 40.71610358 ], [ -74.00968349, 40.71601077 ], [ -74.00958872, 40.71596781 ], [ -74.00969023, 40.71583817 ], [ -74.00972499, 40.7158539 ], [ -74.00973128, 40.71584586 ], [ -74.00989001, 40.71591776 ], [ -74.00988462, 40.71592471 ], [ -74.00991723, 40.71593948 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01240179, 40.71683347 ], [ -74.01243575, 40.71668886 ], [ -74.01248147, 40.71649358 ], [ -74.01250115, 40.71640841 ], [ -74.012604, 40.71645198 ], [ -74.01261739, 40.71639016 ], [ -74.01274935, 40.71645021 ], [ -74.01264649, 40.71688011 ], [ -74.01255082, 40.71683647 ], [ -74.01253789, 40.71689659 ], [ -74.01240054, 40.71683926 ], [ -74.01240179, 40.71683347 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01072248, 40.7157069 ], [ -74.01082345, 40.71557725 ], [ -74.01091059, 40.71561457 ], [ -74.0109149, 40.7156177 ], [ -74.01091921, 40.71562267 ], [ -74.01093224, 40.71562417 ], [ -74.01094464, 40.71562791 ], [ -74.01095021, 40.7156305 ], [ -74.01096018, 40.7156371 ], [ -74.01096799, 40.71564521 ], [ -74.0109732, 40.71565447 ], [ -74.01097554, 40.71566441 ], [ -74.01097491, 40.71567449 ], [ -74.01097123, 40.71568422 ], [ -74.01096844, 40.71568872 ], [ -74.01096072, 40.71569702 ], [ -74.01095604, 40.71570049 ], [ -74.01094517, 40.71570628 ], [ -74.01085445, 40.71604979 ], [ -74.01086145, 40.71605816 ], [ -74.01086585, 40.71606756 ], [ -74.01086729, 40.7160775 ], [ -74.01086585, 40.71608737 ], [ -74.01086154, 40.71609677 ], [ -74.01085445, 40.71610521 ], [ -74.0108451, 40.71611216 ], [ -74.01083971, 40.71611502 ], [ -74.01082794, 40.71611917 ], [ -74.0108151, 40.71612128 ], [ -74.01080198, 40.71612108 ], [ -74.01079561, 40.71612019 ], [ -74.01078932, 40.71611869 ], [ -74.01077764, 40.7161142 ], [ -74.01076758, 40.7161078 ], [ -74.01075985, 40.71609976 ], [ -74.0107568, 40.71609541 ], [ -74.01075294, 40.71608581 ], [ -74.01067514, 40.71604986 ], [ -74.01063094, 40.7160295 ], [ -74.01062097, 40.71604189 ], [ -74.01051039, 40.71599069 ], [ -74.01050437, 40.71598218 ], [ -74.01050213, 40.71597258 ], [ -74.01047275, 40.71595896 ], [ -74.01053087, 40.7158861 ], [ -74.01067811, 40.71595419 ], [ -74.01070425, 40.71592158 ], [ -74.01075994, 40.71572222 ], [ -74.01072248, 40.7157069 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00521177, 40.7166973 ], [ -74.00507639, 40.71686779 ], [ -74.0050048, 40.7168349 ], [ -74.005041, 40.71678922 ], [ -74.00449428, 40.71653798 ], [ -74.00459355, 40.7164131 ], [ -74.00521177, 40.7166973 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01233595, 40.71577321 ], [ -74.01229687, 40.71595821 ], [ -74.01177127, 40.71572038 ], [ -74.01181403, 40.71554049 ], [ -74.01233595, 40.71577321 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00825095, 40.7184559 ], [ -74.00809509, 40.71865478 ], [ -74.00771438, 40.71848212 ], [ -74.00787033, 40.71828317 ], [ -74.00825095, 40.7184559 ] ] ] } }, { "type": "Feature", "properties": { "height": 51.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00590661, 40.71726419 ], [ -74.00568222, 40.71754696 ], [ -74.00538694, 40.71741126 ], [ -74.00554899, 40.71720707 ], [ -74.00566218, 40.71725909 ], [ -74.00572462, 40.71718058 ], [ -74.00583789, 40.7172326 ], [ -74.00590661, 40.71726419 ] ] ] } }, { "type": "Feature", "properties": { "height": 41.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00952108, 40.71762587 ], [ -74.00946304, 40.71790611 ], [ -74.0091101, 40.71786369 ], [ -74.00916813, 40.71758359 ], [ -74.00952108, 40.71762587 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00927584, 40.7189805 ], [ -74.00927359, 40.71899398 ], [ -74.00926604, 40.7190396 ], [ -74.0092302, 40.71925658 ], [ -74.008876, 40.71922281 ], [ -74.00892154, 40.71894659 ], [ -74.00927584, 40.7189805 ] ] ] } }, { "type": "Feature", "properties": { "height": 33.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01074683, 40.71654002 ], [ -74.01069203, 40.71675068 ], [ -74.01067173, 40.71675742 ], [ -74.01024521, 40.71656412 ], [ -74.01038597, 40.7163841 ], [ -74.01054021, 40.71645396 ], [ -74.01054462, 40.71644837 ], [ -74.01074683, 40.71654002 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0051859, 40.71616356 ], [ -74.00506813, 40.71630301 ], [ -74.00511107, 40.71632398 ], [ -74.00506723, 40.71637586 ], [ -74.00502519, 40.71642556 ], [ -74.00479944, 40.71631506 ], [ -74.00479477, 40.71632037 ], [ -74.00470889, 40.71627836 ], [ -74.00491712, 40.71603202 ], [ -74.0051859, 40.71616356 ] ] ] } }, { "type": "Feature", "properties": { "height": 47.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01210885, 40.71531219 ], [ -74.01167038, 40.71523402 ], [ -74.0115148, 40.71520958 ], [ -74.01155792, 40.71506509 ], [ -74.01222653, 40.7151692 ], [ -74.01210885, 40.71531219 ] ] ] } }, { "type": "Feature", "properties": { "height": 43.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0087779, 40.71463797 ], [ -74.00861674, 40.7148423 ], [ -74.00858988, 40.71487628 ], [ -74.00851514, 40.7148421 ], [ -74.00843762, 40.71480676 ], [ -74.00836, 40.71477129 ], [ -74.0083662, 40.71476339 ], [ -74.00829182, 40.71472948 ], [ -74.00847355, 40.714499 ], [ -74.0087779, 40.71463797 ] ] ] } }, { "type": "Feature", "properties": { "height": 145.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01319707, 40.71372516 ], [ -74.01300564, 40.71396858 ], [ -74.01270965, 40.71383471 ], [ -74.01290117, 40.71359136 ], [ -74.01319707, 40.71372516 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00991822, 40.71418687 ], [ -74.01008378, 40.7139745 ], [ -74.0100933, 40.71396231 ], [ -74.01002332, 40.71393072 ], [ -74.0101516, 40.71376608 ], [ -74.01037762, 40.71386808 ], [ -74.01007417, 40.71425728 ], [ -74.00991822, 40.71418687 ] ] ] } }, { "type": "Feature", "properties": { "height": 47.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01167038, 40.71523402 ], [ -74.01155271, 40.71569246 ], [ -74.01136451, 40.71560599 ], [ -74.01150878, 40.71505951 ], [ -74.01155792, 40.71506509 ], [ -74.0115148, 40.71520958 ], [ -74.01167038, 40.71523402 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00697525, 40.71458506 ], [ -74.00669273, 40.71493797 ], [ -74.00645522, 40.71482787 ], [ -74.00658215, 40.71466936 ], [ -74.00660191, 40.71464478 ], [ -74.00667872, 40.71468039 ], [ -74.00681463, 40.71451057 ], [ -74.00697525, 40.71458506 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01469025, 40.71836746 ], [ -74.01468729, 40.71838918 ], [ -74.01437845, 40.7183503 ], [ -74.01437692, 40.71834962 ], [ -74.01438887, 40.71833417 ], [ -74.01435195, 40.71831742 ], [ -74.01442974, 40.71821767 ], [ -74.01451661, 40.71811091 ], [ -74.01453475, 40.71808436 ], [ -74.01454302, 40.71808817 ], [ -74.01455847, 40.71806836 ], [ -74.01456395, 40.71806148 ], [ -74.01468675, 40.71811731 ], [ -74.01468127, 40.71812419 ], [ -74.01483892, 40.71819731 ], [ -74.01482491, 40.71821808 ], [ -74.0148418, 40.71822577 ], [ -74.01472933, 40.71836909 ], [ -74.01469025, 40.71836746 ] ] ] } }, { "type": "Feature", "properties": { "height": 42.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0148056, 40.71618269 ], [ -74.01474208, 40.71615226 ], [ -74.01467615, 40.71623322 ], [ -74.01453493, 40.71616601 ], [ -74.01475484, 40.71587541 ], [ -74.01476903, 40.71585771 ], [ -74.01494977, 40.71594221 ], [ -74.01502514, 40.71584961 ], [ -74.01505434, 40.71581379 ], [ -74.0148904, 40.71573719 ], [ -74.01467552, 40.7156367 ], [ -74.01468657, 40.71562281 ], [ -74.01510042, 40.71581829 ], [ -74.0148056, 40.71618269 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00787033, 40.71828317 ], [ -74.00771438, 40.71848212 ], [ -74.00740213, 40.71834036 ], [ -74.00757577, 40.71811881 ], [ -74.00788012, 40.71825689 ], [ -74.00788812, 40.7182605 ], [ -74.00787033, 40.71828317 ] ] ] } }, { "type": "Feature", "properties": { "height": 113.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00737895, 40.71432918 ], [ -74.00729846, 40.71443016 ], [ -74.00715428, 40.71436377 ], [ -74.00707865, 40.71432877 ], [ -74.0070667, 40.71434369 ], [ -74.00699097, 40.71430869 ], [ -74.00697911, 40.71432346 ], [ -74.00691946, 40.71429602 ], [ -74.00690994, 40.71430787 ], [ -74.006829, 40.71427056 ], [ -74.00669165, 40.7142073 ], [ -74.00661071, 40.71416999 ], [ -74.00667575, 40.71408896 ], [ -74.00688704, 40.71418626 ], [ -74.00689844, 40.71417196 ], [ -74.00693581, 40.71412498 ], [ -74.0069642, 40.71413799 ], [ -74.00697175, 40.71414146 ], [ -74.0069987, 40.71415378 ], [ -74.00710452, 40.7142026 ], [ -74.00713892, 40.71421847 ], [ -74.00737895, 40.71432918 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726801, 40.71394761 ], [ -74.00711907, 40.71413458 ], [ -74.0070181, 40.71408808 ], [ -74.00699187, 40.71407596 ], [ -74.00705098, 40.71400181 ], [ -74.00687132, 40.71391901 ], [ -74.00681239, 40.71399329 ], [ -74.00669228, 40.71393787 ], [ -74.00684113, 40.71375089 ], [ -74.00726801, 40.71394761 ] ] ] } }, { "type": "Feature", "properties": { "height": 31.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.007337, 40.7150557 ], [ -74.0072248, 40.71519582 ], [ -74.00699618, 40.71508981 ], [ -74.00710784, 40.7149505 ], [ -74.00719435, 40.7149906 ], [ -74.00727942, 40.71488432 ], [ -74.00719121, 40.71484339 ], [ -74.00728068, 40.71473159 ], [ -74.00752125, 40.71484312 ], [ -74.00742998, 40.7149571 ], [ -74.00733844, 40.71491468 ], [ -74.0072557, 40.71501797 ], [ -74.007337, 40.7150557 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0042335, 40.71418851 ], [ -74.00402599, 40.71443472 ], [ -74.0037724, 40.71424421 ], [ -74.00389708, 40.71408637 ], [ -74.00395332, 40.71411218 ], [ -74.0039835, 40.71407398 ], [ -74.0040471, 40.71410319 ], [ -74.0042335, 40.71418851 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00696079, 40.71525792 ], [ -74.00685128, 40.71539907 ], [ -74.00682101, 40.71543808 ], [ -74.00662464, 40.7156913 ], [ -74.00647264, 40.71562308 ], [ -74.00665707, 40.71538531 ], [ -74.00668357, 40.71535106 ], [ -74.00676244, 40.71524961 ], [ -74.00680888, 40.71518969 ], [ -74.00696079, 40.71525792 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00732892, 40.71620836 ], [ -74.00700337, 40.71662281 ], [ -74.00684634, 40.71655139 ], [ -74.00717189, 40.71613701 ], [ -74.00732892, 40.71620836 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00901865, 40.71646349 ], [ -74.00898811, 40.7164496 ], [ -74.00880934, 40.71667681 ], [ -74.00873029, 40.71664079 ], [ -74.00886692, 40.7164673 ], [ -74.00871367, 40.71639738 ], [ -74.00890609, 40.71615301 ], [ -74.00903877, 40.71621347 ], [ -74.00901865, 40.71646349 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.009618, 40.71668661 ], [ -74.00955719, 40.71676389 ], [ -74.00954093, 40.71675647 ], [ -74.00950419, 40.71680331 ], [ -74.00952054, 40.71681067 ], [ -74.00940834, 40.71695338 ], [ -74.00926371, 40.71688767 ], [ -74.00929784, 40.71655936 ], [ -74.00938974, 40.71660116 ], [ -74.00942262, 40.71655936 ], [ -74.009474, 40.71658278 ], [ -74.00946475, 40.71659456 ], [ -74.00963094, 40.7166702 ], [ -74.009618, 40.71668661 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00825185, 40.71872586 ], [ -74.00829344, 40.71867269 ], [ -74.00832838, 40.71868392 ], [ -74.00835623, 40.71863381 ], [ -74.00836261, 40.71863592 ], [ -74.00841759, 40.71853672 ], [ -74.0086657, 40.71857117 ], [ -74.00861018, 40.71888852 ], [ -74.00825185, 40.71872586 ] ] ] } }, { "type": "Feature", "properties": { "height": 58.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0058564, 40.71553456 ], [ -74.00572165, 40.71570676 ], [ -74.00565742, 40.71567769 ], [ -74.00568491, 40.71564262 ], [ -74.00561125, 40.71560919 ], [ -74.00558843, 40.71559877 ], [ -74.00555582, 40.71564037 ], [ -74.00534382, 40.7155443 ], [ -74.00548369, 40.7153657 ], [ -74.0058564, 40.71553456 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01111639, 40.71398887 ], [ -74.01115044, 40.71394488 ], [ -74.01118017, 40.71390628 ], [ -74.01122913, 40.71384302 ], [ -74.0113434, 40.7136952 ], [ -74.01138194, 40.71364638 ], [ -74.01144787, 40.71367048 ], [ -74.01140745, 40.71411926 ], [ -74.01111639, 40.71398887 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00429351, 40.71759448 ], [ -74.00422057, 40.71768531 ], [ -74.00370951, 40.717453 ], [ -74.00381174, 40.71733269 ], [ -74.00419667, 40.71751162 ], [ -74.00417448, 40.71753919 ], [ -74.00429351, 40.71759448 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01237907, 40.71492231 ], [ -74.01255747, 40.71423461 ], [ -74.01266392, 40.71428097 ], [ -74.01248632, 40.71493988 ], [ -74.01237907, 40.71492231 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00933575, 40.71513801 ], [ -74.00914819, 40.71537571 ], [ -74.00891283, 40.7152682 ], [ -74.00903122, 40.715118 ], [ -74.00906024, 40.7150813 ], [ -74.00910803, 40.7150207 ], [ -74.00917639, 40.71505202 ], [ -74.00916867, 40.71506176 ], [ -74.00933575, 40.71513801 ] ] ] } }, { "type": "Feature", "properties": { "height": 122.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01469025, 40.71836746 ], [ -74.01465818, 40.71836671 ], [ -74.01462063, 40.71836222 ], [ -74.01459117, 40.718355 ], [ -74.01455209, 40.71834302 ], [ -74.01456215, 40.71832981 ], [ -74.01441195, 40.71826152 ], [ -74.01444384, 40.71822482 ], [ -74.01442974, 40.71821767 ], [ -74.01451661, 40.71811091 ], [ -74.01453188, 40.71811718 ], [ -74.01456467, 40.71807551 ], [ -74.01468127, 40.71812419 ], [ -74.01483892, 40.71819731 ], [ -74.01482491, 40.71821808 ], [ -74.0148418, 40.71822577 ], [ -74.01472933, 40.71836909 ], [ -74.01469025, 40.71836746 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0039764, 40.7178927 ], [ -74.0038748, 40.71800987 ], [ -74.00340768, 40.71779826 ], [ -74.0035056, 40.71767952 ], [ -74.0039764, 40.7178927 ] ] ] } }, { "type": "Feature", "properties": { "height": 42.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00952108, 40.71762587 ], [ -74.00916813, 40.71758359 ], [ -74.00920154, 40.71742229 ], [ -74.0091931, 40.71742127 ], [ -74.00920451, 40.71736619 ], [ -74.00927718, 40.7173749 ], [ -74.00927557, 40.7173828 ], [ -74.00956428, 40.71741739 ], [ -74.00952108, 40.71762587 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00931033, 40.71877162 ], [ -74.00927584, 40.7189805 ], [ -74.00892154, 40.71894659 ], [ -74.00893214, 40.71888246 ], [ -74.00892783, 40.71888212 ], [ -74.00894175, 40.71879796 ], [ -74.00894597, 40.71879837 ], [ -74.00895684, 40.7187326 ], [ -74.00906707, 40.71874309 ], [ -74.00906635, 40.71874826 ], [ -74.00931033, 40.71877162 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01017415, 40.7190686 ], [ -74.01014019, 40.71927401 ], [ -74.00991472, 40.7192525 ], [ -74.00980548, 40.71924201 ], [ -74.00982821, 40.71910448 ], [ -74.00982291, 40.71910401 ], [ -74.00980045, 40.71911041 ], [ -74.0097991, 40.71911837 ], [ -74.0097797, 40.7191166 ], [ -74.00974799, 40.71911347 ], [ -74.00972634, 40.7191115 ], [ -74.00973452, 40.71906159 ], [ -74.00973532, 40.71905689 ], [ -74.0098345, 40.71906636 ], [ -74.00983944, 40.71903667 ], [ -74.01017415, 40.7190686 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00658215, 40.71466936 ], [ -74.00645522, 40.71482787 ], [ -74.00644929, 40.71483529 ], [ -74.00638272, 40.71480451 ], [ -74.00638712, 40.71479628 ], [ -74.00643051, 40.71474208 ], [ -74.00612473, 40.71460031 ], [ -74.00626028, 40.71443111 ], [ -74.00645809, 40.71452276 ], [ -74.0063962, 40.71460011 ], [ -74.00650678, 40.71465138 ], [ -74.00651397, 40.71463776 ], [ -74.00658215, 40.71466936 ] ] ] } }, { "type": "Feature", "properties": { "height": 128.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01280298, 40.7159962 ], [ -74.01276507, 40.71615648 ], [ -74.01234789, 40.71596958 ], [ -74.01238248, 40.71580542 ], [ -74.01280298, 40.7159962 ] ] ] } }, { "type": "Feature", "properties": { "height": 208.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01442498, 40.71448681 ], [ -74.01409548, 40.71491366 ], [ -74.01404284, 40.71490522 ], [ -74.01416573, 40.71444936 ], [ -74.01442498, 40.71448681 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0039764, 40.7178927 ], [ -74.0035056, 40.71767952 ], [ -74.00359938, 40.71756548 ], [ -74.00407387, 40.71778036 ], [ -74.0039764, 40.7178927 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00818088, 40.71513291 ], [ -74.00804685, 40.71530129 ], [ -74.00801981, 40.7153352 ], [ -74.00789477, 40.71549221 ], [ -74.00774439, 40.71542276 ], [ -74.00803059, 40.71506359 ], [ -74.00818088, 40.71513291 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01243575, 40.71668886 ], [ -74.01240179, 40.71683347 ], [ -74.01195479, 40.71662996 ], [ -74.01195713, 40.7166271 ], [ -74.01195308, 40.7166252 ], [ -74.01205657, 40.71649351 ], [ -74.0120607, 40.71649542 ], [ -74.01206268, 40.71649277 ], [ -74.012347, 40.7166222 ], [ -74.01233828, 40.71667381 ], [ -74.01243575, 40.71668886 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00577124, 40.71892876 ], [ -74.00561439, 40.71912559 ], [ -74.0053413, 40.71899956 ], [ -74.00549815, 40.7188028 ], [ -74.00577124, 40.71892876 ] ] ] } }, { "type": "Feature", "properties": { "height": 150.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0059809, 40.71592948 ], [ -74.00595539, 40.71596182 ], [ -74.00593824, 40.7159642 ], [ -74.00589512, 40.71601731 ], [ -74.00589619, 40.7160218 ], [ -74.00588757, 40.71603331 ], [ -74.00586987, 40.71603671 ], [ -74.0058599, 40.71603351 ], [ -74.00585523, 40.71602582 ], [ -74.00575489, 40.71598081 ], [ -74.00575282, 40.71596958 ], [ -74.00576163, 40.71595596 ], [ -74.00573001, 40.7159418 ], [ -74.00572767, 40.71593377 ], [ -74.00575345, 40.71590006 ], [ -74.00573351, 40.71589196 ], [ -74.00573108, 40.71588229 ], [ -74.00573701, 40.71587596 ], [ -74.00570422, 40.71586077 ], [ -74.00569488, 40.71586248 ], [ -74.00567727, 40.71585628 ], [ -74.00567251, 40.71583967 ], [ -74.00568311, 40.71582898 ], [ -74.00569605, 40.71582816 ], [ -74.00574761, 40.71576062 ], [ -74.00574761, 40.71574911 ], [ -74.00575579, 40.71573849 ], [ -74.0057698, 40.71573576 ], [ -74.0057839, 40.7157408 ], [ -74.00578983, 40.71575231 ], [ -74.0058237, 40.71576566 ], [ -74.00582963, 40.71576239 ], [ -74.00583771, 40.7157598 ], [ -74.00585891, 40.71576858 ], [ -74.00588227, 40.71573931 ], [ -74.00589637, 40.71573461 ], [ -74.0059324, 40.71574931 ], [ -74.00594551, 40.71573256 ], [ -74.00594812, 40.71572916 ], [ -74.00601819, 40.7157598 ], [ -74.00605017, 40.71577369 ], [ -74.00606148, 40.71577137 ], [ -74.00607747, 40.71577846 ], [ -74.0060799, 40.71579112 ], [ -74.00607155, 40.71580229 ], [ -74.00606247, 40.71580372 ], [ -74.00601944, 40.71586077 ], [ -74.00602528, 40.71587317 ], [ -74.0059809, 40.71592948 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01485015, 40.71453611 ], [ -74.0147914, 40.71460542 ], [ -74.01461578, 40.71530476 ], [ -74.01451957, 40.71524689 ], [ -74.01454257, 40.71522102 ], [ -74.0145697, 40.71518561 ], [ -74.01459952, 40.71514101 ], [ -74.01462503, 40.71509171 ], [ -74.01464812, 40.71503588 ], [ -74.01466887, 40.71496841 ], [ -74.01468306, 40.71490535 ], [ -74.01468881, 40.71485592 ], [ -74.01469043, 40.71481418 ], [ -74.0146889, 40.71475181 ], [ -74.01468181, 40.71469789 ], [ -74.01466977, 40.7146441 ], [ -74.01465153, 40.71458826 ], [ -74.0146297, 40.71453829 ], [ -74.01460473, 40.71449178 ], [ -74.01457158, 40.7144401 ], [ -74.0145396, 40.71439591 ], [ -74.01451337, 40.71437072 ], [ -74.01485015, 40.71453611 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00766561, 40.71490086 ], [ -74.0073741, 40.715265 ], [ -74.0072248, 40.71519582 ], [ -74.007337, 40.7150557 ], [ -74.00737114, 40.71501321 ], [ -74.00738434, 40.71501927 ], [ -74.0075296, 40.71483788 ], [ -74.00766561, 40.71490086 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00777843, 40.7147561 ], [ -74.00791983, 40.71457839 ], [ -74.00784787, 40.7145453 ], [ -74.00804038, 40.71430351 ], [ -74.00819498, 40.71437467 ], [ -74.00786117, 40.71479417 ], [ -74.00777843, 40.7147561 ] ] ] } }, { "type": "Feature", "properties": { "height": 57.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00609589, 40.71790597 ], [ -74.00598881, 40.71804249 ], [ -74.00595072, 40.71809096 ], [ -74.00593644, 40.71810921 ], [ -74.00591515, 40.71813638 ], [ -74.00587059, 40.71811656 ], [ -74.00583879, 40.71810206 ], [ -74.00574851, 40.71806107 ], [ -74.00568877, 40.71803398 ], [ -74.00586978, 40.7178033 ], [ -74.00609589, 40.71790597 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0088866, 40.71570621 ], [ -74.00880889, 40.7156704 ], [ -74.0087982, 40.71566536 ], [ -74.00880584, 40.71565576 ], [ -74.00865995, 40.71558849 ], [ -74.00867145, 40.71557405 ], [ -74.00859321, 40.71553797 ], [ -74.00871843, 40.71538082 ], [ -74.00903087, 40.71552496 ], [ -74.0088866, 40.71570621 ] ], [ [ -74.00882362, 40.71555118 ], [ -74.00873101, 40.7155074 ], [ -74.00871547, 40.71552639 ], [ -74.00880808, 40.71557017 ], [ -74.00882362, 40.71555118 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01248147, 40.71649358 ], [ -74.01243575, 40.71668886 ], [ -74.01233828, 40.71667381 ], [ -74.012347, 40.7166222 ], [ -74.01206268, 40.71649277 ], [ -74.0120607, 40.71649542 ], [ -74.01205657, 40.71649351 ], [ -74.01217084, 40.71634828 ], [ -74.01217488, 40.71635019 ], [ -74.01217272, 40.71635298 ], [ -74.01248147, 40.71649358 ] ] ] } }, { "type": "Feature", "properties": { "height": 69.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01039289, 40.7161381 ], [ -74.0102488, 40.716322 ], [ -74.01023847, 40.71631737 ], [ -74.0101799, 40.71629082 ], [ -74.01019104, 40.71627659 ], [ -74.01017388, 40.71626889 ], [ -74.01019068, 40.71624751 ], [ -74.0100492, 40.71618331 ], [ -74.01002162, 40.71621851 ], [ -74.00994041, 40.71618167 ], [ -74.0099511, 40.71616806 ], [ -74.01008414, 40.71599811 ], [ -74.01039289, 40.7161381 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01016508, 40.71629817 ], [ -74.01003249, 40.71646771 ], [ -74.00971484, 40.71632377 ], [ -74.00983791, 40.71616642 ], [ -74.01007704, 40.71627468 ], [ -74.01008648, 40.71626256 ], [ -74.01016508, 40.71629817 ] ] ] } }, { "type": "Feature", "properties": { "height": 84.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00616201, 40.715067 ], [ -74.00583682, 40.71495928 ], [ -74.00595539, 40.71480642 ], [ -74.00625848, 40.71494246 ], [ -74.00625669, 40.71494491 ], [ -74.00632981, 40.71497767 ], [ -74.00624043, 40.71509287 ], [ -74.00616731, 40.71506012 ], [ -74.00616201, 40.715067 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01329912, 40.71401386 ], [ -74.01326157, 40.71418068 ], [ -74.01296962, 40.71404416 ], [ -74.01294465, 40.71407589 ], [ -74.01261362, 40.71392446 ], [ -74.01264272, 40.71388796 ], [ -74.01267785, 40.71384676 ], [ -74.01273327, 40.71387196 ], [ -74.01269141, 40.71392527 ], [ -74.01290458, 40.71402169 ], [ -74.01294662, 40.71396851 ], [ -74.01300241, 40.7139935 ], [ -74.01306762, 40.71391077 ], [ -74.01329912, 40.71401386 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0059032, 40.71844937 ], [ -74.00605052, 40.71821808 ], [ -74.00628319, 40.71832389 ], [ -74.00610963, 40.7185451 ], [ -74.0059032, 40.71844937 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00757577, 40.71811881 ], [ -74.00740213, 40.71834036 ], [ -74.00724241, 40.71826792 ], [ -74.00746492, 40.71798407 ], [ -74.0074784, 40.71796691 ], [ -74.00763803, 40.71803929 ], [ -74.00757577, 40.71811881 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00830862, 40.71891446 ], [ -74.00823648, 40.71900549 ], [ -74.00821618, 40.71903109 ], [ -74.0082364, 40.71904042 ], [ -74.00828904, 40.71904688 ], [ -74.00828311, 40.71906179 ], [ -74.00827511, 40.71908978 ], [ -74.00823765, 40.719158 ], [ -74.00793411, 40.71912947 ], [ -74.00799735, 40.71904967 ], [ -74.00815905, 40.71884576 ], [ -74.00830862, 40.71891446 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00487032, 40.71538627 ], [ -74.00467287, 40.71561688 ], [ -74.00472192, 40.71564119 ], [ -74.00466694, 40.7157054 ], [ -74.0046196, 40.71576062 ], [ -74.0045728, 40.7157374 ], [ -74.00438271, 40.71595937 ], [ -74.00431372, 40.71592512 ], [ -74.0045498, 40.71564936 ], [ -74.00480348, 40.71535318 ], [ -74.00487032, 40.71538627 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00724457, 40.71558869 ], [ -74.00702529, 40.71587126 ], [ -74.00685982, 40.71579698 ], [ -74.00706463, 40.71553307 ], [ -74.0070791, 40.71551427 ], [ -74.00724457, 40.71558869 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00668779, 40.71944457 ], [ -74.0066223, 40.71943817 ], [ -74.0066055, 40.71945137 ], [ -74.00659005, 40.71944416 ], [ -74.00639341, 40.71935211 ], [ -74.00653274, 40.71917999 ], [ -74.00672929, 40.71919919 ], [ -74.00668779, 40.71944457 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00872454, 40.717853 ], [ -74.0086666, 40.7179264 ], [ -74.00860327, 40.71789726 ], [ -74.00843618, 40.71782025 ], [ -74.00858943, 40.7176288 ], [ -74.00875868, 40.71770689 ], [ -74.00881823, 40.71773399 ], [ -74.00872454, 40.717853 ] ] ] } }, { "type": "Feature", "properties": { "height": 43.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00823765, 40.719158 ], [ -74.00827511, 40.71908978 ], [ -74.00828311, 40.71906179 ], [ -74.0083238, 40.7190686 ], [ -74.00832973, 40.71904818 ], [ -74.00823648, 40.71900549 ], [ -74.00830862, 40.71891446 ], [ -74.00857263, 40.71903558 ], [ -74.00854793, 40.71918721 ], [ -74.00823765, 40.719158 ] ] ] } }, { "type": "Feature", "properties": { "height": 97.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01502514, 40.71584961 ], [ -74.01494977, 40.71594221 ], [ -74.01479392, 40.71586929 ], [ -74.01476903, 40.71585771 ], [ -74.01457104, 40.71576511 ], [ -74.01467552, 40.7156367 ], [ -74.0148904, 40.71573719 ], [ -74.01486102, 40.7157758 ], [ -74.01502514, 40.71584961 ] ] ] } }, { "type": "Feature", "properties": { "height": 208.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01445067, 40.715217 ], [ -74.01443513, 40.7152744 ], [ -74.01396468, 40.71520372 ], [ -74.01401193, 40.71502308 ], [ -74.01445067, 40.715217 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00944292, 40.71806802 ], [ -74.00941022, 40.71822428 ], [ -74.00937043, 40.71821937 ], [ -74.00937205, 40.71821148 ], [ -74.00915798, 40.71818547 ], [ -74.0091587, 40.71818247 ], [ -74.00909303, 40.71817451 ], [ -74.00908953, 40.71819098 ], [ -74.00904362, 40.71818547 ], [ -74.00907758, 40.7180237 ], [ -74.00944292, 40.71806802 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00706463, 40.71553307 ], [ -74.00685982, 40.71579698 ], [ -74.00670504, 40.71572746 ], [ -74.00678472, 40.71562478 ], [ -74.00690159, 40.7154741 ], [ -74.00690985, 40.71546348 ], [ -74.00696645, 40.71548901 ], [ -74.00698019, 40.71547131 ], [ -74.00701999, 40.71548922 ], [ -74.00700633, 40.71550692 ], [ -74.00706463, 40.71553307 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01278223, 40.71600342 ], [ -74.01275142, 40.71613367 ], [ -74.01236847, 40.71596216 ], [ -74.01239667, 40.7158285 ], [ -74.01278223, 40.71600342 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00765231, 40.71894101 ], [ -74.00762644, 40.71910047 ], [ -74.00738147, 40.71907752 ], [ -74.00742342, 40.71881989 ], [ -74.00759832, 40.7188939 ], [ -74.00760057, 40.7188796 ], [ -74.00765815, 40.71890506 ], [ -74.00765231, 40.71894101 ] ] ] } }, { "type": "Feature", "properties": { "height": 36.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00824304, 40.71584511 ], [ -74.00813947, 40.71597789 ], [ -74.00783188, 40.71583905 ], [ -74.00793528, 40.71570628 ], [ -74.00824304, 40.71584511 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00507639, 40.71686779 ], [ -74.00503731, 40.71691702 ], [ -74.00496015, 40.71688148 ], [ -74.00499833, 40.71683341 ], [ -74.0049341, 40.71680386 ], [ -74.00491613, 40.7168266 ], [ -74.00443922, 40.71660736 ], [ -74.00449428, 40.71653798 ], [ -74.005041, 40.71678922 ], [ -74.0050048, 40.7168349 ], [ -74.00507639, 40.71686779 ] ] ] } }, { "type": "Feature", "properties": { "height": 39.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00742342, 40.71881989 ], [ -74.00738147, 40.71907752 ], [ -74.00722911, 40.71906309 ], [ -74.00723055, 40.71905492 ], [ -74.00719228, 40.71905131 ], [ -74.00719264, 40.7190494 ], [ -74.00719498, 40.71905056 ], [ -74.00723837, 40.71880266 ], [ -74.00723307, 40.71880042 ], [ -74.00723388, 40.71879551 ], [ -74.00728535, 40.71876828 ], [ -74.0073785, 40.71877529 ], [ -74.00742585, 40.71880518 ], [ -74.00742342, 40.71881989 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00411744, 40.71813508 ], [ -74.00393769, 40.71836161 ], [ -74.00376198, 40.71828086 ], [ -74.00394182, 40.7180544 ], [ -74.00411744, 40.71813508 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00666964, 40.71444337 ], [ -74.00656598, 40.71457281 ], [ -74.00645809, 40.71452276 ], [ -74.00626028, 40.71443111 ], [ -74.00636377, 40.71430167 ], [ -74.00666964, 40.71444337 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01121368, 40.71825471 ], [ -74.01118844, 40.71837039 ], [ -74.01080755, 40.71832218 ], [ -74.01081124, 40.71830516 ], [ -74.01069248, 40.71829012 ], [ -74.0107091, 40.71821427 ], [ -74.01084322, 40.71823122 ], [ -74.01084825, 40.71820841 ], [ -74.01121368, 40.71825471 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01261739, 40.71639016 ], [ -74.012604, 40.71645198 ], [ -74.01250115, 40.71640841 ], [ -74.01248147, 40.71649358 ], [ -74.01217272, 40.71635298 ], [ -74.01217488, 40.71635019 ], [ -74.01217084, 40.71634828 ], [ -74.01226085, 40.7162339 ], [ -74.0122648, 40.71623567 ], [ -74.01226839, 40.71623131 ], [ -74.01261739, 40.71639016 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00764162, 40.71634999 ], [ -74.00751711, 40.71650849 ], [ -74.00728167, 40.71640146 ], [ -74.00741228, 40.71623519 ], [ -74.00764773, 40.71634229 ], [ -74.00764162, 40.71634999 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00475713, 40.71729197 ], [ -74.00455447, 40.71758148 ], [ -74.00443194, 40.71753177 ], [ -74.00452438, 40.71736469 ], [ -74.00460334, 40.71722212 ], [ -74.00475713, 40.71729197 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01028967, 40.71838707 ], [ -74.01009582, 40.7183644 ], [ -74.0101119, 40.71828446 ], [ -74.01001632, 40.71827337 ], [ -74.0100412, 40.71814986 ], [ -74.01033073, 40.71818356 ], [ -74.01028967, 40.71838707 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00508358, 40.71744047 ], [ -74.0049058, 40.71766679 ], [ -74.00473593, 40.71758951 ], [ -74.00491362, 40.71736319 ], [ -74.00508358, 40.71744047 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00851963, 40.7161686 ], [ -74.00830125, 40.71644892 ], [ -74.00816471, 40.71638737 ], [ -74.00838138, 40.71610916 ], [ -74.00838309, 40.71610698 ], [ -74.00843825, 40.7161319 ], [ -74.00851963, 40.7161686 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00498818, 40.7184301 ], [ -74.00484948, 40.71836617 ], [ -74.00478264, 40.71833566 ], [ -74.00476288, 40.71832668 ], [ -74.00481525, 40.71826091 ], [ -74.00489664, 40.7181583 ], [ -74.00512185, 40.71826179 ], [ -74.00498818, 40.7184301 ] ] ] } }, { "type": "Feature", "properties": { "height": 43.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0064916, 40.71727488 ], [ -74.00632891, 40.71748418 ], [ -74.00630322, 40.71751727 ], [ -74.00625615, 40.71749616 ], [ -74.00627124, 40.71747676 ], [ -74.006223, 40.71745511 ], [ -74.00620791, 40.71747451 ], [ -74.00614215, 40.71744489 ], [ -74.00633053, 40.71720237 ], [ -74.0064916, 40.71727488 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00618958, 40.71913192 ], [ -74.00613263, 40.71920341 ], [ -74.00597893, 40.71913247 ], [ -74.00590742, 40.71922227 ], [ -74.00588496, 40.71925039 ], [ -74.00573333, 40.7191804 ], [ -74.00586008, 40.71902142 ], [ -74.00593554, 40.71905621 ], [ -74.0059597, 40.71902578 ], [ -74.00598108, 40.71903572 ], [ -74.00618958, 40.71913192 ] ] ] } }, { "type": "Feature", "properties": { "height": 36.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00840663, 40.71550896 ], [ -74.00827889, 40.71566931 ], [ -74.00804748, 40.71556262 ], [ -74.00805044, 40.71555901 ], [ -74.00817531, 40.71540227 ], [ -74.00840663, 40.71550896 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00894049, 40.71710507 ], [ -74.00869993, 40.71707927 ], [ -74.00865447, 40.71705857 ], [ -74.00866408, 40.71704652 ], [ -74.00864252, 40.71703658 ], [ -74.0086772, 40.71699259 ], [ -74.00867028, 40.71698946 ], [ -74.00876667, 40.71686718 ], [ -74.00896762, 40.71695889 ], [ -74.00894049, 40.71710507 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00417745, 40.7189711 ], [ -74.0041505, 40.71900508 ], [ -74.00412049, 40.719043 ], [ -74.00398781, 40.71921076 ], [ -74.00383393, 40.71914036 ], [ -74.00402348, 40.71890057 ], [ -74.00417745, 40.7189711 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00892747, 40.71418231 ], [ -74.0089086, 40.71420601 ], [ -74.00888022, 40.71424169 ], [ -74.00873703, 40.71442138 ], [ -74.00858413, 40.71435077 ], [ -74.00860327, 40.71432666 ], [ -74.00877449, 40.71411177 ], [ -74.00892747, 40.71418231 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00402348, 40.71890057 ], [ -74.00383393, 40.71914036 ], [ -74.00368122, 40.71907051 ], [ -74.00387067, 40.71883071 ], [ -74.00402348, 40.71890057 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00665707, 40.71538531 ], [ -74.00647264, 40.71562308 ], [ -74.00631723, 40.71555329 ], [ -74.00650157, 40.71531552 ], [ -74.00665707, 40.71538531 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00595234, 40.71863456 ], [ -74.00576989, 40.7188636 ], [ -74.00574842, 40.71886442 ], [ -74.00569524, 40.71883868 ], [ -74.00570315, 40.71882881 ], [ -74.00569515, 40.71882506 ], [ -74.00567323, 40.7188303 ], [ -74.00563083, 40.71881151 ], [ -74.00561673, 40.71879109 ], [ -74.0057981, 40.71856348 ], [ -74.00595234, 40.71863456 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00594551, 40.71573256 ], [ -74.0059324, 40.71574931 ], [ -74.00589637, 40.71573461 ], [ -74.00588227, 40.71573931 ], [ -74.00585891, 40.71576858 ], [ -74.00583771, 40.7157598 ], [ -74.00582963, 40.71576239 ], [ -74.0058237, 40.71576566 ], [ -74.00578983, 40.71575231 ], [ -74.0057839, 40.7157408 ], [ -74.0057698, 40.71573576 ], [ -74.00575579, 40.71573849 ], [ -74.00574761, 40.71574911 ], [ -74.00574761, 40.71576062 ], [ -74.00569605, 40.71582816 ], [ -74.00568311, 40.71582898 ], [ -74.00567251, 40.71583967 ], [ -74.00567727, 40.71585628 ], [ -74.00569488, 40.71586248 ], [ -74.00570422, 40.71586077 ], [ -74.00573701, 40.71587596 ], [ -74.00573108, 40.71588229 ], [ -74.00573351, 40.71589196 ], [ -74.00575345, 40.71590006 ], [ -74.00572767, 40.71593377 ], [ -74.00573001, 40.7159418 ], [ -74.00576163, 40.71595596 ], [ -74.00575282, 40.71596958 ], [ -74.0055834, 40.71589468 ], [ -74.00568329, 40.71576811 ], [ -74.00572704, 40.71570928 ], [ -74.00572165, 40.71570676 ], [ -74.0058564, 40.71553456 ], [ -74.0059606, 40.71558182 ], [ -74.00596617, 40.71559966 ], [ -74.00589134, 40.71569968 ], [ -74.00594273, 40.71572201 ], [ -74.00593743, 40.71572896 ], [ -74.00594551, 40.71573256 ] ] ] } }, { "type": "Feature", "properties": { "height": 64.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01038975, 40.71787622 ], [ -74.01036073, 40.7180109 ], [ -74.01000374, 40.7179663 ], [ -74.01003285, 40.71783156 ], [ -74.0101507, 40.7178464 ], [ -74.01038975, 40.71787622 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00627322, 40.71902687 ], [ -74.0060172, 40.71890881 ], [ -74.00605915, 40.71885618 ], [ -74.00615033, 40.71889832 ], [ -74.0061497, 40.71887177 ], [ -74.00623477, 40.71876488 ], [ -74.00641551, 40.71884828 ], [ -74.00627322, 40.71902687 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00662257, 40.71764888 ], [ -74.00646671, 40.71757882 ], [ -74.00648549, 40.71755458 ], [ -74.00664808, 40.71734528 ], [ -74.00680403, 40.71741541 ], [ -74.00662257, 40.71764888 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0070181, 40.71408808 ], [ -74.00697175, 40.71414146 ], [ -74.0069642, 40.71413799 ], [ -74.00693581, 40.71412498 ], [ -74.00689844, 40.71417196 ], [ -74.00688704, 40.71418626 ], [ -74.00667575, 40.71408896 ], [ -74.00659984, 40.71405396 ], [ -74.00669228, 40.71393787 ], [ -74.00681239, 40.71399329 ], [ -74.00699187, 40.71407596 ], [ -74.0070181, 40.71408808 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00973452, 40.71906159 ], [ -74.00972634, 40.7191115 ], [ -74.00972401, 40.71912511 ], [ -74.00969499, 40.71930098 ], [ -74.00949727, 40.71928212 ], [ -74.00953311, 40.7190652 ], [ -74.0095368, 40.71904266 ], [ -74.00962744, 40.71905138 ], [ -74.00973452, 40.71906159 ] ] ] } }, { "type": "Feature", "properties": { "height": 31.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00814558, 40.7160186 ], [ -74.00793797, 40.7162851 ], [ -74.00780457, 40.71622491 ], [ -74.00801218, 40.71595841 ], [ -74.00814558, 40.7160186 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00523899, 40.71751121 ], [ -74.0050613, 40.71773746 ], [ -74.0049058, 40.71766679 ], [ -74.00508358, 40.71744047 ], [ -74.00523899, 40.71751121 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01081878, 40.71480302 ], [ -74.01065798, 40.71500987 ], [ -74.01063624, 40.71503786 ], [ -74.01055809, 40.71500279 ], [ -74.0104856, 40.71497018 ], [ -74.01050743, 40.71494205 ], [ -74.01066822, 40.7147352 ], [ -74.01081878, 40.71480302 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00822867, 40.71419191 ], [ -74.00855988, 40.71376921 ], [ -74.00864324, 40.713807 ], [ -74.00831203, 40.7142297 ], [ -74.00830718, 40.71422746 ], [ -74.00822867, 40.71419191 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00530501, 40.71605306 ], [ -74.0052044, 40.71617262 ], [ -74.0051859, 40.71616356 ], [ -74.00491712, 40.71603202 ], [ -74.00501252, 40.71591906 ], [ -74.00530501, 40.71605306 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00963004, 40.71838768 ], [ -74.00958162, 40.71862782 ], [ -74.00940268, 40.71860692 ], [ -74.00945747, 40.71833526 ], [ -74.00955261, 40.71834642 ], [ -74.00954623, 40.71837788 ], [ -74.00963004, 40.71838768 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0082796, 40.71606327 ], [ -74.00806293, 40.71634141 ], [ -74.00793797, 40.7162851 ], [ -74.00814558, 40.7160186 ], [ -74.00815474, 40.71600689 ], [ -74.0082796, 40.71606327 ] ] ] } }, { "type": "Feature", "properties": { "height": 32.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00801218, 40.71595841 ], [ -74.00780457, 40.71622491 ], [ -74.0076798, 40.71616867 ], [ -74.00789647, 40.71589046 ], [ -74.00802134, 40.71594677 ], [ -74.00801218, 40.71595841 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00488092, 40.71768422 ], [ -74.00470647, 40.71790632 ], [ -74.00455187, 40.71783598 ], [ -74.00468419, 40.71766747 ], [ -74.00472641, 40.71761389 ], [ -74.00488092, 40.71768422 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01115044, 40.71394488 ], [ -74.01118017, 40.71390628 ], [ -74.01122913, 40.71384302 ], [ -74.0113434, 40.7136952 ], [ -74.01142047, 40.71373646 ], [ -74.01134699, 40.71403646 ], [ -74.01115044, 40.71394488 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00815905, 40.71884576 ], [ -74.00799735, 40.71904967 ], [ -74.0079218, 40.71901502 ], [ -74.00791507, 40.71902326 ], [ -74.00782883, 40.7189837 ], [ -74.00799699, 40.71877148 ], [ -74.00815905, 40.71884576 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00860327, 40.71789726 ], [ -74.00853778, 40.71798067 ], [ -74.00831554, 40.71787826 ], [ -74.008345, 40.71784116 ], [ -74.0080791, 40.71771996 ], [ -74.00801999, 40.71769307 ], [ -74.00784159, 40.71761211 ], [ -74.00787707, 40.71756228 ], [ -74.0078971, 40.71757147 ], [ -74.00802152, 40.717629 ], [ -74.00800472, 40.71765058 ], [ -74.00812734, 40.71770669 ], [ -74.00841938, 40.71784116 ], [ -74.00843618, 40.71782025 ], [ -74.00860327, 40.71789726 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00489664, 40.7181583 ], [ -74.00481525, 40.71826091 ], [ -74.00476288, 40.71832668 ], [ -74.00472452, 40.71837509 ], [ -74.00457064, 40.71830441 ], [ -74.00474267, 40.71808756 ], [ -74.00489664, 40.7181583 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00621321, 40.71595208 ], [ -74.00603714, 40.716175 ], [ -74.00585334, 40.71609091 ], [ -74.00595539, 40.71596182 ], [ -74.0059809, 40.71592948 ], [ -74.00610478, 40.71598619 ], [ -74.00615338, 40.71592478 ], [ -74.00621321, 40.71595208 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00901496, 40.7147463 ], [ -74.00884967, 40.71495588 ], [ -74.00881581, 40.71499891 ], [ -74.00868528, 40.7151643 ], [ -74.00860605, 40.71512807 ], [ -74.00874143, 40.71495642 ], [ -74.00877449, 40.71491441 ], [ -74.00893573, 40.71471007 ], [ -74.00901496, 40.7147463 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00536188, 40.7167662 ], [ -74.0052009, 40.7169691 ], [ -74.00518742, 40.71698599 ], [ -74.00503731, 40.71691702 ], [ -74.00507639, 40.71686779 ], [ -74.00521177, 40.7166973 ], [ -74.00536188, 40.7167662 ] ] ] } }, { "type": "Feature", "properties": { "height": 31.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00454019, 40.71833628 ], [ -74.00436987, 40.71855081 ], [ -74.00421994, 40.71848178 ], [ -74.00424779, 40.71844671 ], [ -74.00437283, 40.71828916 ], [ -74.00439403, 40.71826247 ], [ -74.00454405, 40.71833151 ], [ -74.00454019, 40.71833628 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00724457, 40.71558869 ], [ -74.0070791, 40.71551427 ], [ -74.00702493, 40.71548997 ], [ -74.00703238, 40.71548037 ], [ -74.00714189, 40.71533929 ], [ -74.00736153, 40.71543788 ], [ -74.00724457, 40.71558869 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00742279, 40.7140189 ], [ -74.00725552, 40.71422909 ], [ -74.00710074, 40.7141578 ], [ -74.00711907, 40.71413458 ], [ -74.00726801, 40.71394761 ], [ -74.00742279, 40.7140189 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00778068, 40.71583817 ], [ -74.00756401, 40.71611638 ], [ -74.00744597, 40.7160632 ], [ -74.00745145, 40.71605626 ], [ -74.00763659, 40.71581849 ], [ -74.00766273, 40.71578499 ], [ -74.00778068, 40.71583817 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00664808, 40.71734528 ], [ -74.00648549, 40.71755458 ], [ -74.00632891, 40.71748418 ], [ -74.0064916, 40.71727488 ], [ -74.00664808, 40.71734528 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00741228, 40.71623519 ], [ -74.00728167, 40.71640146 ], [ -74.00726334, 40.71642488 ], [ -74.00708044, 40.71665781 ], [ -74.00700337, 40.71662281 ], [ -74.00732892, 40.71620836 ], [ -74.00733529, 40.71620019 ], [ -74.00741228, 40.71623519 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00757649, 40.71408971 ], [ -74.00740923, 40.71429997 ], [ -74.00725552, 40.71422909 ], [ -74.00742279, 40.7140189 ], [ -74.00757649, 40.71408971 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0096896, 40.71429316 ], [ -74.0095429, 40.71447728 ], [ -74.00951542, 40.71451187 ], [ -74.00935893, 40.7147083 ], [ -74.00928123, 40.71467249 ], [ -74.00943484, 40.7144798 ], [ -74.00944589, 40.7144657 ], [ -74.0096119, 40.71425742 ], [ -74.0096896, 40.71429316 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00498818, 40.7184301 ], [ -74.00484948, 40.71836617 ], [ -74.00490185, 40.71830026 ], [ -74.00483223, 40.7182686 ], [ -74.00481525, 40.71826091 ], [ -74.00489664, 40.7181583 ], [ -74.00512185, 40.71826179 ], [ -74.00498818, 40.7184301 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00977925, 40.71773338 ], [ -74.00973613, 40.71793287 ], [ -74.00955243, 40.71790999 ], [ -74.00960444, 40.71766917 ], [ -74.00969445, 40.71768041 ], [ -74.00975122, 40.71768749 ], [ -74.00974233, 40.71772881 ], [ -74.00977925, 40.71773338 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00789647, 40.71589046 ], [ -74.0076798, 40.71616867 ], [ -74.00756401, 40.71611638 ], [ -74.00778068, 40.71583817 ], [ -74.00789647, 40.71589046 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00829344, 40.71867269 ], [ -74.00825185, 40.71872586 ], [ -74.00809509, 40.71865478 ], [ -74.00825095, 40.7184559 ], [ -74.00828113, 40.71841737 ], [ -74.00836369, 40.71845488 ], [ -74.00831778, 40.7185135 ], [ -74.00837231, 40.71853822 ], [ -74.00832883, 40.71862762 ], [ -74.00829344, 40.71867269 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00456678, 40.7172055 ], [ -74.00452752, 40.71725561 ], [ -74.00454908, 40.71726542 ], [ -74.00451764, 40.71730552 ], [ -74.00442951, 40.71726549 ], [ -74.00445143, 40.7172375 ], [ -74.00404845, 40.71705421 ], [ -74.00410019, 40.71699328 ], [ -74.00456678, 40.7172055 ] ] ] } }, { "type": "Feature", "properties": { "height": 53.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01058073, 40.71470116 ], [ -74.01042298, 40.71490406 ], [ -74.01041939, 40.71490869 ], [ -74.0102656, 40.71483951 ], [ -74.01042694, 40.71463198 ], [ -74.01058073, 40.71470116 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00847589, 40.71595011 ], [ -74.00836908, 40.71608717 ], [ -74.00821582, 40.71601806 ], [ -74.00821924, 40.71601377 ], [ -74.00813947, 40.71597789 ], [ -74.00824304, 40.71584511 ], [ -74.00847589, 40.71595011 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00627322, 40.71902687 ], [ -74.00618958, 40.71913192 ], [ -74.00598108, 40.71903572 ], [ -74.00598872, 40.71902619 ], [ -74.00589583, 40.71898336 ], [ -74.00597192, 40.7188879 ], [ -74.0060172, 40.71890881 ], [ -74.00627322, 40.71902687 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00992954, 40.7174581 ], [ -74.00988373, 40.71767046 ], [ -74.00988121, 40.71768218 ], [ -74.00969894, 40.7176595 ], [ -74.00974727, 40.71743536 ], [ -74.00992954, 40.7174581 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00882255, 40.71762566 ], [ -74.00875868, 40.71770689 ], [ -74.00858943, 40.7176288 ], [ -74.00860641, 40.71760762 ], [ -74.0083141, 40.71747322 ], [ -74.00819157, 40.71741698 ], [ -74.00817468, 40.71743747 ], [ -74.00804999, 40.71738042 ], [ -74.00803005, 40.71737116 ], [ -74.00806347, 40.71733017 ], [ -74.00824178, 40.7174114 ], [ -74.00830862, 40.71744176 ], [ -74.00856635, 40.71755921 ], [ -74.00859599, 40.7175217 ], [ -74.00882255, 40.71762566 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01003285, 40.71783156 ], [ -74.01000374, 40.7179663 ], [ -74.009823, 40.71794369 ], [ -74.00987115, 40.71772092 ], [ -74.0100518, 40.71774339 ], [ -74.01003285, 40.71783156 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0060984, 40.71818281 ], [ -74.00625795, 40.71797958 ], [ -74.00640707, 40.71804739 ], [ -74.00624761, 40.71825056 ], [ -74.0060984, 40.71818281 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00675615, 40.71497848 ], [ -74.00704514, 40.71461747 ], [ -74.00712814, 40.71465601 ], [ -74.00683907, 40.71501702 ], [ -74.00675615, 40.71497848 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00784311, 40.71870081 ], [ -74.00769273, 40.71889049 ], [ -74.00753445, 40.71881791 ], [ -74.00768483, 40.71862816 ], [ -74.00784311, 40.71870081 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00933575, 40.71513801 ], [ -74.00916867, 40.71506176 ], [ -74.00917639, 40.71505202 ], [ -74.00931105, 40.71488139 ], [ -74.00947787, 40.71495772 ], [ -74.00933575, 40.71513801 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00419667, 40.71751162 ], [ -74.00381174, 40.71733269 ], [ -74.003866, 40.71726875 ], [ -74.00432217, 40.71748078 ], [ -74.00427015, 40.71754566 ], [ -74.00419667, 40.71751162 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0063122, 40.71529121 ], [ -74.00616272, 40.71548391 ], [ -74.00600588, 40.7154135 ], [ -74.00610469, 40.71528618 ], [ -74.00615545, 40.71522081 ], [ -74.0063122, 40.71529121 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00850032, 40.71702711 ], [ -74.00833862, 40.7172324 ], [ -74.00812959, 40.71713707 ], [ -74.00822148, 40.71702051 ], [ -74.00836584, 40.71708621 ], [ -74.0083768, 40.71709132 ], [ -74.00845612, 40.71699062 ], [ -74.00850984, 40.71701506 ], [ -74.00850032, 40.71702711 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0089025, 40.71731036 ], [ -74.00887195, 40.7174756 ], [ -74.00851559, 40.71731322 ], [ -74.00855242, 40.71726651 ], [ -74.00861153, 40.71727277 ], [ -74.00861045, 40.71727897 ], [ -74.0089025, 40.71731036 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00909051, 40.71478082 ], [ -74.00890825, 40.71501191 ], [ -74.00887923, 40.71504861 ], [ -74.00876083, 40.71519882 ], [ -74.00868528, 40.7151643 ], [ -74.00881581, 40.71499891 ], [ -74.00886566, 40.71502172 ], [ -74.00889962, 40.71497869 ], [ -74.00884967, 40.71495588 ], [ -74.00901496, 40.7147463 ], [ -74.00909051, 40.71478082 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0099802, 40.71519242 ], [ -74.00979722, 40.71542862 ], [ -74.0097868, 40.71544196 ], [ -74.00976389, 40.71547158 ], [ -74.00964325, 40.71541738 ], [ -74.00963238, 40.71543141 ], [ -74.00951542, 40.71537891 ], [ -74.00956024, 40.71532097 ], [ -74.0097011, 40.71538416 ], [ -74.0097232, 40.7153941 ], [ -74.00990546, 40.71515892 ], [ -74.0099802, 40.71519242 ] ] ] } }, { "type": "Feature", "properties": { "height": 31.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00991157, 40.71660797 ], [ -74.00981285, 40.7167338 ], [ -74.00958099, 40.71662826 ], [ -74.00967981, 40.7165025 ], [ -74.00991157, 40.71660797 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00554899, 40.71720707 ], [ -74.00538694, 40.71741126 ], [ -74.00525794, 40.71735196 ], [ -74.00543033, 40.71713476 ], [ -74.00543617, 40.71712741 ], [ -74.00556507, 40.71718671 ], [ -74.00554899, 40.71720707 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0101101, 40.71748071 ], [ -74.01008225, 40.71761028 ], [ -74.01006429, 40.717693 ], [ -74.00988373, 40.71767046 ], [ -74.00992954, 40.7174581 ], [ -74.0101101, 40.71748071 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0073741, 40.715265 ], [ -74.00766561, 40.71490086 ], [ -74.00774385, 40.71493722 ], [ -74.00745235, 40.71530129 ], [ -74.0073741, 40.715265 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00903563, 40.71431856 ], [ -74.0088954, 40.7144945 ], [ -74.00873703, 40.71442138 ], [ -74.00888022, 40.71424169 ], [ -74.00903859, 40.71431468 ], [ -74.00903563, 40.71431856 ] ] ] } }, { "type": "Feature", "properties": { "height": 51.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00975311, 40.71548547 ], [ -74.00965879, 40.71560728 ], [ -74.00944238, 40.71551026 ], [ -74.00943223, 40.71548622 ], [ -74.00951542, 40.71537891 ], [ -74.00963238, 40.71543141 ], [ -74.00975311, 40.71548547 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00931105, 40.71488139 ], [ -74.00917639, 40.71505202 ], [ -74.00910803, 40.7150207 ], [ -74.00906024, 40.7150813 ], [ -74.00898433, 40.71504657 ], [ -74.00906033, 40.71495016 ], [ -74.00908153, 40.71495996 ], [ -74.00910974, 40.71492422 ], [ -74.00908854, 40.71491448 ], [ -74.00916651, 40.71481548 ], [ -74.00931105, 40.71488139 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0084908, 40.71527576 ], [ -74.00835461, 40.71544666 ], [ -74.00834779, 40.71545531 ], [ -74.00819067, 40.71538286 ], [ -74.00833368, 40.71520338 ], [ -74.0084908, 40.71527576 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0086436, 40.7153463 ], [ -74.00851838, 40.71550352 ], [ -74.00849709, 40.71553021 ], [ -74.00841741, 40.71563016 ], [ -74.0083574, 40.71570547 ], [ -74.00827889, 40.71566931 ], [ -74.00840663, 40.71550896 ], [ -74.00842899, 40.71548098 ], [ -74.00856509, 40.71531008 ], [ -74.0086436, 40.7153463 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00605052, 40.71821808 ], [ -74.0059032, 40.71844937 ], [ -74.00576109, 40.7183868 ], [ -74.00593482, 40.71816559 ], [ -74.00605052, 40.71821808 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.004268, 40.71786948 ], [ -74.00409148, 40.71809192 ], [ -74.00396544, 40.71803391 ], [ -74.00414205, 40.71781147 ], [ -74.004268, 40.71786948 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00838138, 40.71610916 ], [ -74.00816471, 40.71638737 ], [ -74.00806293, 40.71634141 ], [ -74.0082796, 40.71606327 ], [ -74.00838138, 40.71610916 ] ] ] } }, { "type": "Feature", "properties": { "height": 33.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00526998, 40.71795758 ], [ -74.0051514, 40.7181086 ], [ -74.00499833, 40.71803901 ], [ -74.00517044, 40.71781991 ], [ -74.00524123, 40.71785212 ], [ -74.00520683, 40.7178959 ], [ -74.00518778, 40.7179202 ], [ -74.00526998, 40.71795758 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00421733, 40.71821767 ], [ -74.00409229, 40.71837529 ], [ -74.00405887, 40.7184173 ], [ -74.00393769, 40.71836161 ], [ -74.00411744, 40.71813508 ], [ -74.00423871, 40.71819078 ], [ -74.00421733, 40.71821767 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01063103, 40.7169787 ], [ -74.01060444, 40.71709112 ], [ -74.01026641, 40.7170506 ], [ -74.01028725, 40.71695011 ], [ -74.01035624, 40.7169815 ], [ -74.01038184, 40.71694888 ], [ -74.01063103, 40.7169787 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00791507, 40.71902326 ], [ -74.00783817, 40.71912041 ], [ -74.00762644, 40.71910047 ], [ -74.00765231, 40.71894101 ], [ -74.00767073, 40.71891779 ], [ -74.0077655, 40.71896137 ], [ -74.00776945, 40.7189564 ], [ -74.00782883, 40.7189837 ], [ -74.00791507, 40.71902326 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00917415, 40.71440878 ], [ -74.00904928, 40.71456538 ], [ -74.0088954, 40.7144945 ], [ -74.00903563, 40.71431856 ], [ -74.00918942, 40.71438958 ], [ -74.00917415, 40.71440878 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00833368, 40.71520338 ], [ -74.00819067, 40.71538286 ], [ -74.00817531, 40.71540227 ], [ -74.00805044, 40.71555901 ], [ -74.00804748, 40.71556262 ], [ -74.00797247, 40.71552796 ], [ -74.00809761, 40.71537108 ], [ -74.00812464, 40.71533717 ], [ -74.00825867, 40.71516879 ], [ -74.00833368, 40.71520338 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01017882, 40.7156115 ], [ -74.01016445, 40.71562996 ], [ -74.01004318, 40.71578649 ], [ -74.01004237, 40.71578751 ], [ -74.00988714, 40.71571779 ], [ -74.0098919, 40.71571146 ], [ -74.00995505, 40.71563009 ], [ -74.01002341, 40.71554178 ], [ -74.01017882, 40.7156115 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0090677, 40.71400637 ], [ -74.00892747, 40.71418231 ], [ -74.00877449, 40.71411177 ], [ -74.0089148, 40.71393576 ], [ -74.0090677, 40.71400637 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00935561, 40.71444316 ], [ -74.00920208, 40.71463586 ], [ -74.00904928, 40.71456538 ], [ -74.00917415, 40.71440878 ], [ -74.00924907, 40.71444337 ], [ -74.00927781, 40.71440728 ], [ -74.00935561, 40.71444316 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00863812, 40.71561586 ], [ -74.00851038, 40.71577607 ], [ -74.0083574, 40.71570547 ], [ -74.00841741, 40.71563016 ], [ -74.00849709, 40.71553021 ], [ -74.00862689, 40.71558999 ], [ -74.00861495, 40.71560517 ], [ -74.00863812, 40.71561586 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00873029, 40.71664079 ], [ -74.00857713, 40.716571 ], [ -74.00871367, 40.71639738 ], [ -74.00886692, 40.7164673 ], [ -74.00873029, 40.71664079 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0079731, 40.71384472 ], [ -74.00783952, 40.71401529 ], [ -74.00768339, 40.71394447 ], [ -74.00781715, 40.71377398 ], [ -74.0079731, 40.71384472 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00449141, 40.71758747 ], [ -74.00437858, 40.71775721 ], [ -74.00422057, 40.71768531 ], [ -74.00429351, 40.71759448 ], [ -74.00436546, 40.71750467 ], [ -74.0044862, 40.717562 ], [ -74.00447371, 40.71758066 ], [ -74.00449141, 40.71758747 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00586008, 40.71902142 ], [ -74.00573333, 40.7191804 ], [ -74.00561439, 40.71912559 ], [ -74.00577124, 40.71892876 ], [ -74.00579055, 40.71890452 ], [ -74.00590949, 40.71895939 ], [ -74.00586008, 40.71902142 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00649375, 40.71504807 ], [ -74.00635514, 40.7152268 ], [ -74.00620638, 40.71516001 ], [ -74.00634499, 40.71498141 ], [ -74.00649375, 40.71504807 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00437283, 40.71828916 ], [ -74.00424779, 40.71844671 ], [ -74.00409229, 40.71837529 ], [ -74.00421733, 40.71821767 ], [ -74.00426979, 40.71824191 ], [ -74.00429935, 40.7182048 ], [ -74.00434624, 40.71822632 ], [ -74.00431678, 40.71826336 ], [ -74.00437283, 40.71828916 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00971233, 40.71672951 ], [ -74.00950275, 40.71699641 ], [ -74.00940834, 40.71695338 ], [ -74.00952054, 40.71681067 ], [ -74.00955719, 40.71676389 ], [ -74.009618, 40.71668661 ], [ -74.009641, 40.71668307 ], [ -74.00970155, 40.71671058 ], [ -74.00971233, 40.71672951 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00831554, 40.71787826 ], [ -74.00830979, 40.71788562 ], [ -74.00776981, 40.71763976 ], [ -74.0078423, 40.71754587 ], [ -74.00787707, 40.71756228 ], [ -74.00784159, 40.71761211 ], [ -74.00801999, 40.71769307 ], [ -74.0080791, 40.71771996 ], [ -74.008345, 40.71784116 ], [ -74.00831554, 40.71787826 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00860165, 40.71751482 ], [ -74.00859599, 40.7175217 ], [ -74.00856635, 40.71755921 ], [ -74.00830862, 40.71744176 ], [ -74.00824178, 40.7174114 ], [ -74.00806347, 40.71733017 ], [ -74.00803005, 40.71737116 ], [ -74.00799313, 40.71735386 ], [ -74.00806158, 40.71726875 ], [ -74.00860165, 40.71751482 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00704514, 40.71461747 ], [ -74.00675615, 40.71497848 ], [ -74.00668617, 40.71494607 ], [ -74.00669273, 40.71493797 ], [ -74.00697525, 40.71458506 ], [ -74.00704514, 40.71461747 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00714189, 40.71533929 ], [ -74.00703238, 40.71548037 ], [ -74.00685128, 40.71539907 ], [ -74.00696079, 40.71525792 ], [ -74.00714189, 40.71533929 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00680888, 40.71518969 ], [ -74.00676244, 40.71524961 ], [ -74.00668357, 40.71535106 ], [ -74.00652852, 40.71528148 ], [ -74.00665383, 40.71511997 ], [ -74.00680888, 40.71518969 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00836369, 40.71845488 ], [ -74.00828113, 40.71841737 ], [ -74.00829002, 40.718406 ], [ -74.00846609, 40.71818131 ], [ -74.00861009, 40.71824661 ], [ -74.00855413, 40.71831796 ], [ -74.00854613, 40.71831442 ], [ -74.0085358, 40.71832749 ], [ -74.0084978, 40.71831027 ], [ -74.00848334, 40.71832886 ], [ -74.00846789, 40.71832191 ], [ -74.00836369, 40.71845488 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01334853, 40.71388701 ], [ -74.01331772, 40.71402196 ], [ -74.01329912, 40.71401386 ], [ -74.01306762, 40.71391077 ], [ -74.01315755, 40.71379651 ], [ -74.01333083, 40.71387829 ], [ -74.01334853, 40.71388701 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00971332, 40.71881008 ], [ -74.00967675, 40.71903252 ], [ -74.00967577, 40.71903742 ], [ -74.0096304, 40.71903306 ], [ -74.00962744, 40.71905138 ], [ -74.0095368, 40.71904266 ], [ -74.00954057, 40.71901951 ], [ -74.00957731, 40.71879708 ], [ -74.00971332, 40.71881008 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00603714, 40.716175 ], [ -74.00621321, 40.71595208 ], [ -74.006322, 40.71600192 ], [ -74.00629334, 40.71603821 ], [ -74.00614593, 40.71622477 ], [ -74.00603714, 40.716175 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00554145, 40.71574959 ], [ -74.00546922, 40.71584178 ], [ -74.00520467, 40.71572187 ], [ -74.0052769, 40.71562968 ], [ -74.00554145, 40.71574959 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00901865, 40.71646349 ], [ -74.00899664, 40.71673577 ], [ -74.00899323, 40.71674169 ], [ -74.00898712, 40.71674619 ], [ -74.00897939, 40.71674877 ], [ -74.00897095, 40.71674898 ], [ -74.00896295, 40.7167468 ], [ -74.00880934, 40.71667681 ], [ -74.00898811, 40.7164496 ], [ -74.00901865, 40.71646349 ] ] ] } }, { "type": "Feature", "properties": { "height": 108.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01495472, 40.71578772 ], [ -74.0149045, 40.7158526 ], [ -74.01482293, 40.71581631 ], [ -74.01479068, 40.71585791 ], [ -74.01461102, 40.71577798 ], [ -74.0146934, 40.71567156 ], [ -74.01495472, 40.71578772 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0095262, 40.71643271 ], [ -74.00949071, 40.71647785 ], [ -74.00947472, 40.71647057 ], [ -74.0094095, 40.7165535 ], [ -74.00942262, 40.71655936 ], [ -74.00938974, 40.71660116 ], [ -74.00929784, 40.71655936 ], [ -74.00930458, 40.7164944 ], [ -74.00932075, 40.71633916 ], [ -74.0095262, 40.71643271 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00817468, 40.71743747 ], [ -74.00802152, 40.717629 ], [ -74.0078971, 40.71757147 ], [ -74.00792315, 40.71753892 ], [ -74.00802403, 40.71741276 ], [ -74.00804999, 40.71738042 ], [ -74.00817468, 40.71743747 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01082345, 40.71557725 ], [ -74.01072248, 40.7157069 ], [ -74.01071431, 40.71570322 ], [ -74.01070622, 40.71571357 ], [ -74.01063975, 40.71568368 ], [ -74.01062735, 40.71569961 ], [ -74.01062268, 40.7156975 ], [ -74.01061693, 40.71570499 ], [ -74.01054623, 40.71567306 ], [ -74.01067954, 40.71550181 ], [ -74.01082947, 40.71556936 ], [ -74.01082345, 40.71557725 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00554145, 40.71574959 ], [ -74.0052769, 40.71562968 ], [ -74.00534382, 40.7155443 ], [ -74.00555582, 40.71564037 ], [ -74.00562041, 40.71566972 ], [ -74.00555349, 40.7157551 ], [ -74.00554145, 40.71574959 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00796798, 40.7168744 ], [ -74.00785362, 40.7170201 ], [ -74.00769273, 40.71694691 ], [ -74.00780709, 40.71680127 ], [ -74.00796798, 40.7168744 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00419973, 40.71863722 ], [ -74.00404153, 40.71883732 ], [ -74.00392511, 40.71878401 ], [ -74.0040833, 40.7185839 ], [ -74.00419973, 40.71863722 ] ] ] } }, { "type": "Feature", "properties": { "height": 11.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00989145, 40.71676947 ], [ -74.00987771, 40.7167869 ], [ -74.00985058, 40.71682136 ], [ -74.0096578, 40.71706688 ], [ -74.0095792, 40.71703106 ], [ -74.00980072, 40.71674911 ], [ -74.00981285, 40.7167338 ], [ -74.00989145, 40.71676947 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01080755, 40.71832218 ], [ -74.01075473, 40.71856361 ], [ -74.01063597, 40.71854857 ], [ -74.01069248, 40.71829012 ], [ -74.01081124, 40.71830516 ], [ -74.01080755, 40.71832218 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00670288, 40.71609166 ], [ -74.00658107, 40.71624697 ], [ -74.0064315, 40.71617956 ], [ -74.00655331, 40.71602432 ], [ -74.00670288, 40.71609166 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0040833, 40.7185839 ], [ -74.00392511, 40.71878401 ], [ -74.00381004, 40.71873138 ], [ -74.00396823, 40.71853127 ], [ -74.0040833, 40.7185839 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01026228, 40.71852256 ], [ -74.01024018, 40.71863272 ], [ -74.00996403, 40.71860052 ], [ -74.00998622, 40.71849036 ], [ -74.01026228, 40.71852256 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00451, 40.71877917 ], [ -74.00439448, 40.71892522 ], [ -74.00433537, 40.71899997 ], [ -74.00425614, 40.71896362 ], [ -74.00420395, 40.71902959 ], [ -74.0041505, 40.71900508 ], [ -74.00417745, 40.7189711 ], [ -74.00420242, 40.71893938 ], [ -74.00418167, 40.71892998 ], [ -74.00419092, 40.7189182 ], [ -74.00421257, 40.7188909 ], [ -74.00429315, 40.71892767 ], [ -74.00430707, 40.7189101 ], [ -74.00443697, 40.71874581 ], [ -74.00451, 40.71877917 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01004461, 40.71683981 ], [ -74.01002189, 40.71686881 ], [ -74.00981141, 40.71713667 ], [ -74.00973523, 40.71710208 ], [ -74.0099281, 40.71685656 ], [ -74.00995514, 40.71682217 ], [ -74.00996853, 40.71680522 ], [ -74.01004461, 40.71683981 ] ] ] } }, { "type": "Feature", "properties": { "height": 57.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00587059, 40.71811656 ], [ -74.005859, 40.71813127 ], [ -74.00585388, 40.71813767 ], [ -74.00582002, 40.71812222 ], [ -74.00580007, 40.71814761 ], [ -74.00583412, 40.71816266 ], [ -74.00571905, 40.7183085 ], [ -74.00559688, 40.71825301 ], [ -74.00574851, 40.71806107 ], [ -74.00583879, 40.71810206 ], [ -74.00587059, 40.71811656 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00778104, 40.7156367 ], [ -74.00767153, 40.71577709 ], [ -74.00766875, 40.7157807 ], [ -74.00759374, 40.71574686 ], [ -74.00751334, 40.71571057 ], [ -74.00757595, 40.71563016 ], [ -74.00762554, 40.71556657 ], [ -74.00778104, 40.7156367 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00483645, 40.71732806 ], [ -74.00466793, 40.71756881 ], [ -74.00463595, 40.7176145 ], [ -74.00455447, 40.71758148 ], [ -74.00475713, 40.71729197 ], [ -74.00483645, 40.71732806 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01027773, 40.71694582 ], [ -74.01024961, 40.71704856 ], [ -74.01022787, 40.71712747 ], [ -74.01020874, 40.71719747 ], [ -74.01017442, 40.71732268 ], [ -74.0100324, 40.71725806 ], [ -74.01004452, 40.71724281 ], [ -74.01023955, 40.7169945 ], [ -74.01027773, 40.71694582 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00759374, 40.71574686 ], [ -74.00756365, 40.71578561 ], [ -74.00737832, 40.71602337 ], [ -74.00729793, 40.71598708 ], [ -74.00751334, 40.71571057 ], [ -74.00759374, 40.71574686 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726002, 40.71763526 ], [ -74.00716839, 40.7177491 ], [ -74.00712823, 40.71779908 ], [ -74.00702897, 40.71775292 ], [ -74.00699681, 40.7177378 ], [ -74.00712859, 40.71757399 ], [ -74.00726002, 40.71763526 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00705197, 40.71753831 ], [ -74.00687248, 40.71776129 ], [ -74.00677654, 40.71771656 ], [ -74.00695594, 40.71749358 ], [ -74.00705197, 40.71753831 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01266051, 40.71654288 ], [ -74.01260185, 40.71678847 ], [ -74.01249378, 40.71674047 ], [ -74.0125528, 40.71649358 ], [ -74.01266051, 40.71654288 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00980072, 40.71674911 ], [ -74.0095792, 40.71703106 ], [ -74.00950275, 40.71699641 ], [ -74.00971233, 40.71672951 ], [ -74.00972427, 40.71671432 ], [ -74.00980072, 40.71674911 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01010202, 40.71690531 ], [ -74.00989154, 40.71717316 ], [ -74.00981141, 40.71713667 ], [ -74.01002189, 40.71686881 ], [ -74.01010202, 40.71690531 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01060444, 40.71709112 ], [ -74.01058558, 40.71717037 ], [ -74.01027144, 40.71713272 ], [ -74.01022787, 40.71712747 ], [ -74.01024961, 40.71704856 ], [ -74.01026641, 40.7170506 ], [ -74.01060444, 40.71709112 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01016517, 40.71696066 ], [ -74.00997023, 40.71720897 ], [ -74.00989154, 40.71717316 ], [ -74.01010202, 40.71690531 ], [ -74.01018071, 40.71694098 ], [ -74.01016517, 40.71696066 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00860174, 40.71707328 ], [ -74.00844004, 40.7172787 ], [ -74.00833862, 40.7172324 ], [ -74.00850032, 40.71702711 ], [ -74.00860174, 40.71707328 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00766219, 40.71412927 ], [ -74.00746977, 40.71437099 ], [ -74.00746259, 40.71436772 ], [ -74.00738407, 40.7143315 ], [ -74.00740923, 40.71429997 ], [ -74.00757649, 40.71408971 ], [ -74.00766219, 40.71412927 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00690159, 40.7154741 ], [ -74.00678472, 40.71562478 ], [ -74.00670504, 40.71572746 ], [ -74.00662464, 40.7156913 ], [ -74.00682101, 40.71543808 ], [ -74.00690159, 40.7154741 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00530501, 40.71605306 ], [ -74.00501252, 40.71591906 ], [ -74.00506381, 40.71585839 ], [ -74.00538981, 40.7160075 ], [ -74.00537975, 40.71601949 ], [ -74.00533834, 40.71606838 ], [ -74.00530501, 40.71605306 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01018538, 40.71900011 ], [ -74.01017415, 40.7190686 ], [ -74.00983944, 40.71903667 ], [ -74.00981195, 40.71903402 ], [ -74.00982578, 40.71894939 ], [ -74.00990178, 40.71895667 ], [ -74.00990124, 40.71896069 ], [ -74.009952, 40.71896552 ], [ -74.00994858, 40.71898629 ], [ -74.0099838, 40.71898956 ], [ -74.0099873, 40.71896886 ], [ -74.01000994, 40.7189711 ], [ -74.01000787, 40.71898316 ], [ -74.01018538, 40.71900011 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00650157, 40.71531552 ], [ -74.00631723, 40.71555329 ], [ -74.00623324, 40.7155155 ], [ -74.00638272, 40.71532288 ], [ -74.00641767, 40.7152778 ], [ -74.00650157, 40.71531552 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00930234, 40.71411449 ], [ -74.00913094, 40.71432966 ], [ -74.00903958, 40.71428758 ], [ -74.00904515, 40.7142807 ], [ -74.00921098, 40.71407248 ], [ -74.00930234, 40.71411449 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0073459, 40.71646247 ], [ -74.007163, 40.71669539 ], [ -74.00715869, 40.71670091 ], [ -74.00707613, 40.71666326 ], [ -74.00708044, 40.71665781 ], [ -74.00726334, 40.71642488 ], [ -74.0073459, 40.71646247 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00804038, 40.71430351 ], [ -74.00784787, 40.7145453 ], [ -74.0078441, 40.71454346 ], [ -74.00776828, 40.7145086 ], [ -74.0079607, 40.71426681 ], [ -74.00804038, 40.71430351 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00435855, 40.71791101 ], [ -74.00426072, 40.71803411 ], [ -74.00424428, 40.71802656 ], [ -74.00415679, 40.71813679 ], [ -74.00409085, 40.71810649 ], [ -74.00409938, 40.71809546 ], [ -74.00409148, 40.71809192 ], [ -74.004268, 40.71786948 ], [ -74.00435855, 40.71791101 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00574851, 40.71806107 ], [ -74.00559688, 40.71825301 ], [ -74.00571905, 40.7183085 ], [ -74.00568473, 40.71835187 ], [ -74.00550372, 40.71826976 ], [ -74.00568877, 40.71803398 ], [ -74.00574851, 40.71806107 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00396823, 40.71853127 ], [ -74.00381004, 40.71873138 ], [ -74.0037149, 40.7186878 ], [ -74.0038731, 40.7184877 ], [ -74.00396823, 40.71853127 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0099281, 40.71685656 ], [ -74.00973523, 40.71710208 ], [ -74.0096578, 40.71706688 ], [ -74.00985058, 40.71682136 ], [ -74.0099281, 40.71685656 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01018538, 40.71900011 ], [ -74.01000787, 40.71898316 ], [ -74.01000994, 40.7189711 ], [ -74.0100315, 40.71884052 ], [ -74.01020892, 40.71885747 ], [ -74.01018538, 40.71900011 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0077399, 40.71416502 ], [ -74.00754748, 40.7144068 ], [ -74.00754029, 40.71440347 ], [ -74.00746977, 40.71437099 ], [ -74.00766219, 40.71412927 ], [ -74.0077399, 40.71416502 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00549447, 40.7177858 ], [ -74.00544551, 40.7178481 ], [ -74.00532927, 40.71779527 ], [ -74.00534463, 40.71777579 ], [ -74.00526531, 40.71773971 ], [ -74.00539071, 40.71758011 ], [ -74.00546761, 40.71761511 ], [ -74.00540095, 40.71770001 ], [ -74.00538218, 40.7176915 ], [ -74.00534984, 40.7177327 ], [ -74.00536861, 40.71774127 ], [ -74.00537589, 40.71773188 ], [ -74.00549447, 40.7177858 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00937797, 40.71829781 ], [ -74.00936504, 40.71837121 ], [ -74.00902817, 40.71833662 ], [ -74.0090412, 40.71826309 ], [ -74.00937797, 40.71829781 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00603247, 40.7186716 ], [ -74.00585011, 40.71890057 ], [ -74.00576989, 40.7188636 ], [ -74.00595234, 40.71863456 ], [ -74.00603247, 40.7186716 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00938049, 40.71415058 ], [ -74.00921493, 40.71435839 ], [ -74.00919319, 40.7143857 ], [ -74.00911504, 40.71434961 ], [ -74.00913094, 40.71432966 ], [ -74.00930234, 40.71411449 ], [ -74.00938049, 40.71415058 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01023955, 40.7169945 ], [ -74.01004452, 40.71724281 ], [ -74.00997023, 40.71720897 ], [ -74.01016517, 40.71696066 ], [ -74.01023955, 40.7169945 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00544551, 40.7178481 ], [ -74.00535505, 40.7179633 ], [ -74.00528911, 40.71793328 ], [ -74.00520683, 40.7178959 ], [ -74.00524123, 40.71785212 ], [ -74.00525417, 40.71783571 ], [ -74.00523018, 40.71782468 ], [ -74.0052733, 40.7177698 ], [ -74.00532927, 40.71779527 ], [ -74.00544551, 40.7178481 ] ] ] } }, { "type": "Feature", "properties": { "height": 41.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00953734, 40.7157504 ], [ -74.00940915, 40.71591416 ], [ -74.00939423, 40.71593322 ], [ -74.00937483, 40.71592437 ], [ -74.00936612, 40.71591926 ], [ -74.00935049, 40.71591851 ], [ -74.00936935, 40.71571466 ], [ -74.00941678, 40.7156958 ], [ -74.00953734, 40.7157504 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00491362, 40.71736319 ], [ -74.00473593, 40.71758951 ], [ -74.0046991, 40.71763629 ], [ -74.0046487, 40.71761348 ], [ -74.0046797, 40.71757405 ], [ -74.00466793, 40.71756881 ], [ -74.00483645, 40.71732806 ], [ -74.00491362, 40.71736319 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00846609, 40.71818131 ], [ -74.00829002, 40.718406 ], [ -74.00820864, 40.71836896 ], [ -74.00838462, 40.71814441 ], [ -74.00846609, 40.71818131 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00749394, 40.71653811 ], [ -74.00731571, 40.71676491 ], [ -74.00723522, 40.71672828 ], [ -74.00741345, 40.71650148 ], [ -74.00749394, 40.71653811 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0057981, 40.71856348 ], [ -74.00561673, 40.71879109 ], [ -74.00553723, 40.71875446 ], [ -74.00555169, 40.71873642 ], [ -74.00571869, 40.71852678 ], [ -74.0057981, 40.71856348 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0079607, 40.71426681 ], [ -74.00776828, 40.7145086 ], [ -74.00769363, 40.71447408 ], [ -74.00788605, 40.71423236 ], [ -74.0079607, 40.71426681 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00978419, 40.7181199 ], [ -74.00973838, 40.7183471 ], [ -74.00973541, 40.71836167 ], [ -74.00970846, 40.71837481 ], [ -74.00965268, 40.71836828 ], [ -74.00964199, 40.71835078 ], [ -74.00964783, 40.71832171 ], [ -74.00969068, 40.71810901 ], [ -74.00978419, 40.7181199 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00977018, 40.7146042 ], [ -74.00968125, 40.71456307 ], [ -74.0098407, 40.71436295 ], [ -74.00992972, 40.71440401 ], [ -74.00977018, 40.7146042 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01005647, 40.7152266 ], [ -74.00988157, 40.71545252 ], [ -74.00987357, 40.7154628 ], [ -74.00979722, 40.71542862 ], [ -74.0099802, 40.71519242 ], [ -74.01005647, 40.7152266 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00788605, 40.71423236 ], [ -74.00769363, 40.71447408 ], [ -74.00768654, 40.71447088 ], [ -74.00762042, 40.71444037 ], [ -74.00781284, 40.71419859 ], [ -74.00788605, 40.71423236 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00838462, 40.71814441 ], [ -74.00820864, 40.71836896 ], [ -74.00819678, 40.71838401 ], [ -74.0081224, 40.71835017 ], [ -74.00813354, 40.71833601 ], [ -74.00831024, 40.71811057 ], [ -74.00838462, 40.71814441 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00781284, 40.71419859 ], [ -74.00762042, 40.71444037 ], [ -74.00761323, 40.7144371 ], [ -74.00754748, 40.7144068 ], [ -74.0077399, 40.71416502 ], [ -74.00781284, 40.71419859 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00474267, 40.71808756 ], [ -74.00457064, 40.71830441 ], [ -74.0045657, 40.71831047 ], [ -74.00448665, 40.71827418 ], [ -74.00466362, 40.7180512 ], [ -74.00474267, 40.71808756 ] ] ] } }, { "type": "Feature", "properties": { "height": 39.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01042694, 40.71463198 ], [ -74.0102656, 40.71483951 ], [ -74.01025698, 40.71485061 ], [ -74.01017756, 40.7148148 ], [ -74.01019373, 40.7147941 ], [ -74.01035148, 40.71459099 ], [ -74.01043098, 40.7146268 ], [ -74.01042694, 40.71463198 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0097214, 40.7183934 ], [ -74.00967199, 40.71863837 ], [ -74.00958162, 40.71862782 ], [ -74.00963004, 40.71838768 ], [ -74.00963103, 40.71838292 ], [ -74.00965268, 40.71836828 ], [ -74.00970846, 40.71837481 ], [ -74.0097214, 40.7183934 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00916651, 40.71481548 ], [ -74.00908854, 40.71491448 ], [ -74.00906033, 40.71495016 ], [ -74.00898433, 40.71504657 ], [ -74.00890825, 40.71501191 ], [ -74.00909051, 40.71478082 ], [ -74.00916651, 40.71481548 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00443679, 40.71794696 ], [ -74.00425982, 40.71817001 ], [ -74.00418149, 40.71813399 ], [ -74.00426072, 40.71803411 ], [ -74.00435855, 40.71791101 ], [ -74.00443679, 40.71794696 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00823307, 40.71807558 ], [ -74.00805664, 40.71830108 ], [ -74.0079784, 40.71826567 ], [ -74.00815492, 40.71804017 ], [ -74.00823307, 40.71807558 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00539071, 40.71758011 ], [ -74.00526531, 40.71773971 ], [ -74.00521294, 40.71780636 ], [ -74.00513568, 40.7177713 ], [ -74.00531355, 40.71754498 ], [ -74.00539071, 40.71758011 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00936504, 40.71837121 ], [ -74.00935273, 40.71844052 ], [ -74.00933027, 40.7184382 ], [ -74.00924224, 40.71842908 ], [ -74.00920505, 40.71842527 ], [ -74.00901595, 40.71840586 ], [ -74.00902817, 40.71833662 ], [ -74.00936504, 40.71837121 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00815492, 40.71804017 ], [ -74.0079784, 40.71826567 ], [ -74.00790069, 40.71823047 ], [ -74.00807748, 40.71800497 ], [ -74.00815492, 40.71804017 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01042038, 40.71773399 ], [ -74.01040493, 40.71780589 ], [ -74.01016589, 40.717776 ], [ -74.01008405, 40.71776579 ], [ -74.0100995, 40.71769389 ], [ -74.01011828, 40.7176962 ], [ -74.01042038, 40.71773399 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00551342, 40.71586186 ], [ -74.00546922, 40.71591838 ], [ -74.00516047, 40.71577846 ], [ -74.00520467, 40.71572187 ], [ -74.00546922, 40.71584178 ], [ -74.00551342, 40.71586186 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00869993, 40.71707927 ], [ -74.00864872, 40.71714416 ], [ -74.0086312, 40.71716642 ], [ -74.00855242, 40.71726651 ], [ -74.00851559, 40.71731322 ], [ -74.00844004, 40.7172787 ], [ -74.00860174, 40.71707328 ], [ -74.00864513, 40.71705428 ], [ -74.00865447, 40.71705857 ], [ -74.00869993, 40.71707927 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00461493, 40.71838081 ], [ -74.00445062, 40.71858779 ], [ -74.00436987, 40.71855081 ], [ -74.00454019, 40.71833628 ], [ -74.00462095, 40.71837332 ], [ -74.00461493, 40.71838081 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00831024, 40.71811057 ], [ -74.00813354, 40.71833601 ], [ -74.00805664, 40.71830108 ], [ -74.00823307, 40.71807558 ], [ -74.00831024, 40.71811057 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01066822, 40.7147352 ], [ -74.01050743, 40.71494205 ], [ -74.01042298, 40.71490406 ], [ -74.01058073, 40.71470116 ], [ -74.01058378, 40.71469721 ], [ -74.01066822, 40.7147352 ] ] ] } }, { "type": "Feature", "properties": { "height": 32.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0045895, 40.71801716 ], [ -74.00441254, 40.71824007 ], [ -74.00433519, 40.7182046 ], [ -74.00451225, 40.71798169 ], [ -74.0045895, 40.71801716 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00712859, 40.71757399 ], [ -74.00699681, 40.7177378 ], [ -74.0069492, 40.71779697 ], [ -74.00687248, 40.71776129 ], [ -74.00705197, 40.71753831 ], [ -74.00712859, 40.71757399 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00741345, 40.71650148 ], [ -74.00723522, 40.71672828 ], [ -74.007163, 40.71669539 ], [ -74.0073459, 40.71646247 ], [ -74.00735102, 40.716456 ], [ -74.00742333, 40.71648888 ], [ -74.00741345, 40.71650148 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00981042, 40.71840041 ], [ -74.00976039, 40.71864872 ], [ -74.00967199, 40.71863837 ], [ -74.0097214, 40.7183934 ], [ -74.00972212, 40.71839 ], [ -74.0097391, 40.71837897 ], [ -74.0097965, 40.71838571 ], [ -74.00981042, 40.71840041 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00618078, 40.71794458 ], [ -74.00602133, 40.71814782 ], [ -74.00593644, 40.71810921 ], [ -74.00595072, 40.71809096 ], [ -74.00598881, 40.71804249 ], [ -74.00609589, 40.71790597 ], [ -74.00618078, 40.71794458 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00763659, 40.71581849 ], [ -74.00745145, 40.71605626 ], [ -74.00737832, 40.71602337 ], [ -74.00756365, 40.71578561 ], [ -74.00763659, 40.71581849 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00866507, 40.71804862 ], [ -74.00853302, 40.71798747 ], [ -74.00853778, 40.71798067 ], [ -74.00860327, 40.71789726 ], [ -74.0086666, 40.7179264 ], [ -74.00872454, 40.717853 ], [ -74.00874493, 40.71786226 ], [ -74.00879398, 40.71788466 ], [ -74.00866507, 40.71804862 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00435639, 40.71870891 ], [ -74.0042265, 40.7188732 ], [ -74.00421257, 40.7188909 ], [ -74.00419092, 40.7189182 ], [ -74.0041098, 40.7188811 ], [ -74.00427527, 40.7186718 ], [ -74.00435639, 40.71870891 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00451225, 40.71798169 ], [ -74.00433519, 40.7182046 ], [ -74.00425982, 40.71817001 ], [ -74.00443679, 40.71794696 ], [ -74.00451225, 40.71798169 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00564098, 40.71849097 ], [ -74.00547399, 40.71870047 ], [ -74.00539808, 40.71866547 ], [ -74.00542853, 40.71862727 ], [ -74.00542359, 40.71862496 ], [ -74.00556013, 40.71845366 ], [ -74.00564098, 40.71849097 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00531355, 40.71754498 ], [ -74.00513568, 40.7177713 ], [ -74.0050613, 40.71773746 ], [ -74.00523899, 40.71751121 ], [ -74.00531355, 40.71754498 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01090071, 40.71483979 ], [ -74.01073991, 40.71504671 ], [ -74.01065798, 40.71500987 ], [ -74.01081878, 40.71480302 ], [ -74.01090071, 40.71483979 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00509903, 40.71778737 ], [ -74.00492691, 40.71800647 ], [ -74.00485217, 40.71797256 ], [ -74.00501944, 40.71775966 ], [ -74.00503444, 40.71776647 ], [ -74.00505061, 40.7177459 ], [ -74.00508708, 40.71776252 ], [ -74.00507585, 40.71777688 ], [ -74.00509903, 40.71778737 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00593482, 40.71816559 ], [ -74.00576109, 40.7183868 ], [ -74.00568473, 40.71835187 ], [ -74.00571905, 40.7183085 ], [ -74.00583412, 40.71816266 ], [ -74.00585388, 40.71813767 ], [ -74.005859, 40.71813127 ], [ -74.00593482, 40.71816559 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00638712, 40.71479628 ], [ -74.00608134, 40.71465458 ], [ -74.00612473, 40.71460031 ], [ -74.00643051, 40.71474208 ], [ -74.00638712, 40.71479628 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00974727, 40.71743536 ], [ -74.00969894, 40.7176595 ], [ -74.00969445, 40.71768041 ], [ -74.00960444, 40.71766917 ], [ -74.00965735, 40.71742406 ], [ -74.00974727, 40.71743536 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00466362, 40.7180512 ], [ -74.00448665, 40.71827418 ], [ -74.00441254, 40.71824007 ], [ -74.0045895, 40.71801716 ], [ -74.00466362, 40.7180512 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00517044, 40.71781991 ], [ -74.00499833, 40.71803901 ], [ -74.00492691, 40.71800647 ], [ -74.00509903, 40.71778737 ], [ -74.00510963, 40.71777396 ], [ -74.00518087, 40.71780636 ], [ -74.00517044, 40.71781991 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01028967, 40.71838707 ], [ -74.01027548, 40.71845727 ], [ -74.00996152, 40.7184207 ], [ -74.00997571, 40.71835037 ], [ -74.01009582, 40.7183644 ], [ -74.01028967, 40.71838707 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00792109, 40.71873662 ], [ -74.00775283, 40.71894877 ], [ -74.00767477, 40.71891296 ], [ -74.00769273, 40.71889049 ], [ -74.00784311, 40.71870081 ], [ -74.00792109, 40.71873662 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01482167, 40.71744326 ], [ -74.01488743, 40.71735951 ], [ -74.01508479, 40.71744912 ], [ -74.01501814, 40.71753259 ], [ -74.01482167, 40.71744326 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00571869, 40.71852678 ], [ -74.00555169, 40.71873642 ], [ -74.00547399, 40.71870047 ], [ -74.00564098, 40.71849097 ], [ -74.00571869, 40.71852678 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00786, 40.71673386 ], [ -74.00784123, 40.7167579 ], [ -74.00780709, 40.71680127 ], [ -74.00769273, 40.71694691 ], [ -74.00761593, 40.71691198 ], [ -74.00762213, 40.71690422 ], [ -74.00778328, 40.716699 ], [ -74.00786, 40.71673386 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00885758, 40.7146744 ], [ -74.00869642, 40.71487866 ], [ -74.00861674, 40.7148423 ], [ -74.0087779, 40.71463797 ], [ -74.00885758, 40.7146744 ] ] ] } }, { "type": "Feature", "properties": { "height": 57.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00831913, 40.71789066 ], [ -74.00830062, 40.71791421 ], [ -74.0079528, 40.71775598 ], [ -74.007951, 40.7177583 ], [ -74.00772777, 40.71765671 ], [ -74.007822, 40.71753668 ], [ -74.0078423, 40.71754587 ], [ -74.00776981, 40.71763976 ], [ -74.00830979, 40.71788562 ], [ -74.00831913, 40.71789066 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00610272, 40.71870401 ], [ -74.00601747, 40.71881076 ], [ -74.00592018, 40.71893291 ], [ -74.00585011, 40.71890057 ], [ -74.00603247, 40.7186716 ], [ -74.00610272, 40.71870401 ] ] ] } }, { "type": "Feature", "properties": { "height": 6.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00799699, 40.71877148 ], [ -74.00782883, 40.7189837 ], [ -74.00776945, 40.7189564 ], [ -74.00775283, 40.71894877 ], [ -74.00792109, 40.71873662 ], [ -74.00799699, 40.71877148 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00945774, 40.71418619 ], [ -74.009308, 40.71437412 ], [ -74.0092921, 40.714394 ], [ -74.00921493, 40.71435839 ], [ -74.00938049, 40.71415058 ], [ -74.00945774, 40.71418619 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00456947, 40.71857151 ], [ -74.00452824, 40.71862346 ], [ -74.00445062, 40.71858779 ], [ -74.00461493, 40.71838081 ], [ -74.00469254, 40.71841648 ], [ -74.00456947, 40.71857151 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00494605, 40.71772636 ], [ -74.00477887, 40.7179392 ], [ -74.00470647, 40.71790632 ], [ -74.00488092, 40.71768422 ], [ -74.00495332, 40.7177171 ], [ -74.00494605, 40.71772636 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00778328, 40.716699 ], [ -74.00762213, 40.71690422 ], [ -74.00754397, 40.71686868 ], [ -74.00770522, 40.71666346 ], [ -74.00778328, 40.716699 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00893573, 40.71471007 ], [ -74.00877449, 40.71491441 ], [ -74.00869642, 40.71487866 ], [ -74.00885758, 40.7146744 ], [ -74.00893573, 40.71471007 ] ] ] } }, { "type": "Feature", "properties": { "height": 32.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00959626, 40.71454918 ], [ -74.0095774, 40.71457287 ], [ -74.00956051, 40.71459412 ], [ -74.00943978, 40.71474562 ], [ -74.00935893, 40.7147083 ], [ -74.00951542, 40.71451187 ], [ -74.00959626, 40.71454918 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00427527, 40.7186718 ], [ -74.0041098, 40.7188811 ], [ -74.00403417, 40.71884651 ], [ -74.00404153, 40.71883732 ], [ -74.00419973, 40.71863722 ], [ -74.00427527, 40.7186718 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0096119, 40.71425742 ], [ -74.00944589, 40.7144657 ], [ -74.00937025, 40.71443077 ], [ -74.00938651, 40.71441041 ], [ -74.00953617, 40.71422249 ], [ -74.0096119, 40.71425742 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00914612, 40.71404246 ], [ -74.00898739, 40.71424237 ], [ -74.0089086, 40.71420601 ], [ -74.00892747, 40.71418231 ], [ -74.0090677, 40.71400637 ], [ -74.00914612, 40.71404246 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01034474, 40.71591456 ], [ -74.01046934, 40.71575367 ], [ -74.01055611, 40.71579262 ], [ -74.01043601, 40.71596856 ], [ -74.0103372, 40.71592416 ], [ -74.01034474, 40.71591456 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00625795, 40.71797958 ], [ -74.0060984, 40.71818281 ], [ -74.00602133, 40.71814782 ], [ -74.00618078, 40.71794458 ], [ -74.00625795, 40.71797958 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00969292, 40.71529959 ], [ -74.00960669, 40.71526092 ], [ -74.00974871, 40.71507776 ], [ -74.00983477, 40.71511636 ], [ -74.00969292, 40.71529959 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00977054, 40.71433048 ], [ -74.00962384, 40.71451459 ], [ -74.00960013, 40.7145037 ], [ -74.0095951, 40.71450928 ], [ -74.00958782, 40.71451316 ], [ -74.0095792, 40.71451486 ], [ -74.00957471, 40.71451479 ], [ -74.00956617, 40.71451289 ], [ -74.00955898, 40.71450887 ], [ -74.00955422, 40.71450329 ], [ -74.00955279, 40.71450002 ], [ -74.00955243, 40.71449328 ], [ -74.00955458, 40.71448661 ], [ -74.00955683, 40.71448368 ], [ -74.0095429, 40.71447728 ], [ -74.0096896, 40.71429316 ], [ -74.00977054, 40.71433048 ] ] ] } }, { "type": "Feature", "properties": { "height": 57.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00862959, 40.71749596 ], [ -74.00861144, 40.71751911 ], [ -74.00860165, 40.71751482 ], [ -74.00806158, 40.71726875 ], [ -74.00799313, 40.71735386 ], [ -74.00797283, 40.71734467 ], [ -74.00806086, 40.71723308 ], [ -74.00827853, 40.71733221 ], [ -74.00827619, 40.71733521 ], [ -74.00862959, 40.71749596 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00501944, 40.71775966 ], [ -74.00485217, 40.71797256 ], [ -74.00477887, 40.7179392 ], [ -74.00494605, 40.71772636 ], [ -74.00501944, 40.71775966 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0043563, 40.71924079 ], [ -74.00427581, 40.71934258 ], [ -74.0041231, 40.71927272 ], [ -74.0042035, 40.71917087 ], [ -74.00421302, 40.71917516 ], [ -74.0043563, 40.71924079 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01035148, 40.71459099 ], [ -74.01019373, 40.7147941 ], [ -74.01011648, 40.71475937 ], [ -74.01015187, 40.71471382 ], [ -74.01027431, 40.71455626 ], [ -74.01035148, 40.71459099 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01043502, 40.71766631 ], [ -74.01042038, 40.71773399 ], [ -74.01011828, 40.7176962 ], [ -74.01013292, 40.71762846 ], [ -74.01030593, 40.71765011 ], [ -74.01043502, 40.71766631 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00969023, 40.71583817 ], [ -74.00958872, 40.71596781 ], [ -74.0095606, 40.71600376 ], [ -74.00947382, 40.7159644 ], [ -74.00948595, 40.71594902 ], [ -74.00961414, 40.7157852 ], [ -74.00970092, 40.71582448 ], [ -74.00969023, 40.71583817 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00986944, 40.71847681 ], [ -74.00983297, 40.7186571 ], [ -74.00976039, 40.71864872 ], [ -74.00981042, 40.71840041 ], [ -74.00981393, 40.71838326 ], [ -74.00990591, 40.71839401 ], [ -74.00989352, 40.71845577 ], [ -74.00987411, 40.71845352 ], [ -74.00986944, 40.71847681 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01027548, 40.71845727 ], [ -74.01026228, 40.71852256 ], [ -74.00998622, 40.71849036 ], [ -74.00994831, 40.718486 ], [ -74.00996152, 40.7184207 ], [ -74.01027548, 40.71845727 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00892774, 40.71717411 ], [ -74.00891462, 40.71724499 ], [ -74.00862249, 40.71721367 ], [ -74.0086312, 40.71716642 ], [ -74.00864872, 40.71714416 ], [ -74.00868708, 40.71714831 ], [ -74.00892774, 40.71717411 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00987402, 40.71813039 ], [ -74.00982821, 40.71835759 ], [ -74.00973838, 40.7183471 ], [ -74.00978419, 40.7181199 ], [ -74.00987402, 40.71813039 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00738731, 40.71849158 ], [ -74.00723145, 40.71868828 ], [ -74.00717504, 40.71866241 ], [ -74.00718357, 40.71860991 ], [ -74.00724852, 40.71852807 ], [ -74.00730673, 40.71845461 ], [ -74.00738731, 40.71849158 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0074651, 40.71852726 ], [ -74.00730924, 40.71872396 ], [ -74.00723145, 40.71868828 ], [ -74.00738731, 40.71849158 ], [ -74.0074651, 40.71852726 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00943484, 40.7144798 ], [ -74.00928123, 40.71467249 ], [ -74.00920208, 40.71463586 ], [ -74.00935561, 40.71444316 ], [ -74.00943484, 40.7144798 ] ] ] } }, { "type": "Feature", "properties": { "height": 32.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00987115, 40.71772092 ], [ -74.009823, 40.71794369 ], [ -74.00973613, 40.71793287 ], [ -74.00977925, 40.71773338 ], [ -74.00978743, 40.71769518 ], [ -74.00983378, 40.71770097 ], [ -74.00983153, 40.71771179 ], [ -74.00987187, 40.71771676 ], [ -74.00987115, 40.71772092 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00949152, 40.71878891 ], [ -74.00945478, 40.71901127 ], [ -74.00936342, 40.71900256 ], [ -74.00940007, 40.71878019 ], [ -74.00949152, 40.71878891 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00920505, 40.71842527 ], [ -74.00918618, 40.71853141 ], [ -74.008997, 40.71851187 ], [ -74.00901595, 40.71840586 ], [ -74.00920505, 40.71842527 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00937797, 40.71829781 ], [ -74.0090412, 40.71826309 ], [ -74.00905171, 40.71820378 ], [ -74.00938848, 40.71823837 ], [ -74.00937797, 40.71829781 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00996134, 40.71814046 ], [ -74.00992559, 40.71831721 ], [ -74.00991544, 40.7183678 ], [ -74.00982821, 40.71835759 ], [ -74.00987402, 40.71813039 ], [ -74.00996134, 40.71814046 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00940007, 40.71878019 ], [ -74.00936342, 40.71900256 ], [ -74.00927359, 40.71899398 ], [ -74.00927584, 40.7189805 ], [ -74.00931033, 40.71877162 ], [ -74.00940007, 40.71878019 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00746259, 40.71436772 ], [ -74.00732119, 40.71454537 ], [ -74.00723747, 40.71450676 ], [ -74.00724942, 40.71449192 ], [ -74.00727484, 40.71445998 ], [ -74.00728661, 40.71444507 ], [ -74.00729846, 40.71443016 ], [ -74.00737895, 40.71432918 ], [ -74.00738407, 40.7143315 ], [ -74.00746259, 40.71436772 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00935785, 40.71904838 ], [ -74.00932201, 40.71926537 ], [ -74.0092302, 40.71925658 ], [ -74.00926604, 40.7190396 ], [ -74.00935785, 40.71904838 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00953617, 40.71422249 ], [ -74.00938651, 40.71441041 ], [ -74.009308, 40.71437412 ], [ -74.00945774, 40.71418619 ], [ -74.00953617, 40.71422249 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00761332, 40.71859527 ], [ -74.00745738, 40.71879197 ], [ -74.00738228, 40.71875759 ], [ -74.00753822, 40.71856089 ], [ -74.00761332, 40.71859527 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01096332, 40.71488411 ], [ -74.01087061, 40.71500347 ], [ -74.01081178, 40.71507912 ], [ -74.01073991, 40.71504671 ], [ -74.01090071, 40.71483979 ], [ -74.01097257, 40.7148722 ], [ -74.01096332, 40.71488411 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01043502, 40.71766631 ], [ -74.01030593, 40.71765011 ], [ -74.01030845, 40.71763846 ], [ -74.01029902, 40.71763731 ], [ -74.01032686, 40.71750781 ], [ -74.01046547, 40.7175251 ], [ -74.01043502, 40.71766631 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00776828, 40.7145086 ], [ -74.00762689, 40.71468631 ], [ -74.00754514, 40.71464859 ], [ -74.00768654, 40.71447088 ], [ -74.00769363, 40.71447408 ], [ -74.00776828, 40.7145086 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00753822, 40.71856089 ], [ -74.00738228, 40.71875759 ], [ -74.00730924, 40.71872396 ], [ -74.0074651, 40.71852726 ], [ -74.00753822, 40.71856089 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00657523, 40.71508477 ], [ -74.00644111, 40.71525772 ], [ -74.00643662, 40.71526337 ], [ -74.00635514, 40.7152268 ], [ -74.00649375, 40.71504807 ], [ -74.00657523, 40.71508477 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01003824, 40.71552272 ], [ -74.01002341, 40.71554178 ], [ -74.00995505, 40.71563009 ], [ -74.0098919, 40.71571146 ], [ -74.00981465, 40.71567687 ], [ -74.0099529, 40.71549841 ], [ -74.00996089, 40.71548806 ], [ -74.01003824, 40.71552272 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00953311, 40.7190652 ], [ -74.00949727, 40.71928212 ], [ -74.00940879, 40.71927367 ], [ -74.00944463, 40.71905669 ], [ -74.00953311, 40.7190652 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01063624, 40.71503786 ], [ -74.01062304, 40.71505488 ], [ -74.01049251, 40.71522292 ], [ -74.01041427, 40.71518772 ], [ -74.01041661, 40.71518479 ], [ -74.01055809, 40.71500279 ], [ -74.01063624, 40.71503786 ] ] ] } }, { "type": "Feature", "properties": { "height": 106.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01216482, 40.71463756 ], [ -74.01213832, 40.71473806 ], [ -74.01213472, 40.714745 ], [ -74.01212655, 40.71475338 ], [ -74.01211568, 40.71475992 ], [ -74.01210041, 40.71476632 ], [ -74.0120916, 40.71476781 ], [ -74.012081, 40.71476829 ], [ -74.01206951, 40.71476761 ], [ -74.01205513, 40.71476441 ], [ -74.01204229, 40.71475801 ], [ -74.01203178, 40.71475038 ], [ -74.01202459, 40.71474119 ], [ -74.01202073, 40.71473139 ], [ -74.01202019, 40.71471927 ], [ -74.0120492, 40.71461536 ], [ -74.01205711, 40.71460617 ], [ -74.01206645, 40.71459882 ], [ -74.01207777, 40.71459296 ], [ -74.0120908, 40.71458997 ], [ -74.01210751, 40.71458888 ], [ -74.01212215, 40.71459078 ], [ -74.01213419, 40.71459425 ], [ -74.01214371, 40.71459882 ], [ -74.0121535, 40.7146074 ], [ -74.0121597, 40.71461598 ], [ -74.01216392, 40.7146253 ], [ -74.01216482, 40.71463756 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00866327, 40.71492067 ], [ -74.00852781, 40.7150924 ], [ -74.00844822, 40.71505597 ], [ -74.00858988, 40.71487628 ], [ -74.00866965, 40.71491271 ], [ -74.00866327, 40.71492067 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00891462, 40.71724499 ], [ -74.0089025, 40.71731036 ], [ -74.00861045, 40.71727897 ], [ -74.00861153, 40.71727277 ], [ -74.00862249, 40.71721367 ], [ -74.00891462, 40.71724499 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00957731, 40.71879708 ], [ -74.00954057, 40.71901951 ], [ -74.00945478, 40.71901127 ], [ -74.00949152, 40.71878891 ], [ -74.00957731, 40.71879708 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00623477, 40.71876488 ], [ -74.0061497, 40.71887177 ], [ -74.00601747, 40.71881076 ], [ -74.00610272, 40.71870401 ], [ -74.00623477, 40.71876488 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00969068, 40.71810901 ], [ -74.00964783, 40.71832171 ], [ -74.00955961, 40.71831136 ], [ -74.00957372, 40.71824171 ], [ -74.00960255, 40.71809866 ], [ -74.00969068, 40.71810901 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00768483, 40.71862816 ], [ -74.00753445, 40.71881791 ], [ -74.00752888, 40.71882479 ], [ -74.00745738, 40.71879197 ], [ -74.00761332, 40.71859527 ], [ -74.00768483, 40.71862816 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0098407, 40.71436295 ], [ -74.00968125, 40.71456307 ], [ -74.009611, 40.71453066 ], [ -74.00962384, 40.71451459 ], [ -74.00977054, 40.71433048 ], [ -74.0098407, 40.71436295 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00944463, 40.71905669 ], [ -74.00940879, 40.71927367 ], [ -74.00932201, 40.71926537 ], [ -74.00935785, 40.71904838 ], [ -74.00944463, 40.71905669 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01057282, 40.7172245 ], [ -74.01055683, 40.71729197 ], [ -74.01033908, 40.71726589 ], [ -74.01028249, 40.71725909 ], [ -74.0102965, 40.71719141 ], [ -74.01057282, 40.7172245 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0099529, 40.71549841 ], [ -74.00981465, 40.71567687 ], [ -74.00973532, 40.71564126 ], [ -74.00986306, 40.71547628 ], [ -74.00987357, 40.7154628 ], [ -74.0099529, 40.71549841 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01024018, 40.71863272 ], [ -74.01022769, 40.71869441 ], [ -74.00992604, 40.71865907 ], [ -74.00993843, 40.71859752 ], [ -74.00996403, 40.71860052 ], [ -74.01024018, 40.71863272 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00613263, 40.71920341 ], [ -74.00606112, 40.71929321 ], [ -74.00590742, 40.71922227 ], [ -74.00597893, 40.71913247 ], [ -74.00613263, 40.71920341 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00851514, 40.7148421 ], [ -74.0083733, 40.71502179 ], [ -74.00829595, 40.71498652 ], [ -74.00843528, 40.71480969 ], [ -74.00843762, 40.71480676 ], [ -74.00851514, 40.7148421 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0088866, 40.71570621 ], [ -74.00874475, 40.7158842 ], [ -74.00866714, 40.71584838 ], [ -74.00879955, 40.71568232 ], [ -74.00880889, 40.7156704 ], [ -74.0088866, 40.71570621 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00754029, 40.71440347 ], [ -74.0073989, 40.71458118 ], [ -74.00732119, 40.71454537 ], [ -74.00746259, 40.71436772 ], [ -74.00746977, 40.71437099 ], [ -74.00754029, 40.71440347 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00549447, 40.7177858 ], [ -74.00537589, 40.71773188 ], [ -74.00540095, 40.71770001 ], [ -74.00546761, 40.71761511 ], [ -74.00558619, 40.71766897 ], [ -74.00549447, 40.7177858 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00843528, 40.71480969 ], [ -74.00829595, 40.71498652 ], [ -74.00821825, 40.71495097 ], [ -74.00835758, 40.71477428 ], [ -74.00843528, 40.71480969 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0106525, 40.71515905 ], [ -74.01057938, 40.71525322 ], [ -74.01057435, 40.71525969 ], [ -74.01049251, 40.71522292 ], [ -74.01062304, 40.71505488 ], [ -74.01070479, 40.71509178 ], [ -74.0106525, 40.71515905 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00921098, 40.71407248 ], [ -74.00904515, 40.7142807 ], [ -74.00898065, 40.71425088 ], [ -74.00898739, 40.71424237 ], [ -74.00914612, 40.71404246 ], [ -74.00921098, 40.71407248 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00777843, 40.7147561 ], [ -74.00770271, 40.71472117 ], [ -74.0078441, 40.71454346 ], [ -74.00784787, 40.7145453 ], [ -74.00791983, 40.71457839 ], [ -74.00777843, 40.7147561 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0078441, 40.71454346 ], [ -74.00770271, 40.71472117 ], [ -74.00762689, 40.71468631 ], [ -74.00776828, 40.7145086 ], [ -74.0078441, 40.71454346 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01023119, 40.71488391 ], [ -74.01010588, 40.71504501 ], [ -74.01002638, 40.71500926 ], [ -74.01015942, 40.71483822 ], [ -74.01023892, 40.7148739 ], [ -74.01023119, 40.71488391 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01046943, 40.71499101 ], [ -74.01034411, 40.71515218 ], [ -74.01025967, 40.71511418 ], [ -74.01038499, 40.71495309 ], [ -74.01046943, 40.71499101 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00638272, 40.71532288 ], [ -74.00623324, 40.7155155 ], [ -74.00616272, 40.71548391 ], [ -74.0063122, 40.71529121 ], [ -74.00638272, 40.71532288 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00665383, 40.71511997 ], [ -74.00652852, 40.71528148 ], [ -74.00651962, 40.71529299 ], [ -74.00644111, 40.71525772 ], [ -74.00657523, 40.71508477 ], [ -74.00665383, 40.71511997 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00858988, 40.71487628 ], [ -74.00844822, 40.71505597 ], [ -74.0083733, 40.71502179 ], [ -74.00851514, 40.7148421 ], [ -74.00858988, 40.71487628 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00874143, 40.71495642 ], [ -74.00860605, 40.71512807 ], [ -74.00852781, 40.7150924 ], [ -74.00866327, 40.71492067 ], [ -74.00874143, 40.71495642 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00673783, 40.71447496 ], [ -74.00660191, 40.71464478 ], [ -74.00658215, 40.71466936 ], [ -74.00651397, 40.71463776 ], [ -74.00656598, 40.71457281 ], [ -74.00666964, 40.71444337 ], [ -74.00673783, 40.71447496 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01008414, 40.71599811 ], [ -74.0099511, 40.71616806 ], [ -74.00987223, 40.71613231 ], [ -74.01000518, 40.71596236 ], [ -74.01008414, 40.71599811 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00869004, 40.71683232 ], [ -74.00855539, 40.71700308 ], [ -74.00847714, 40.7169674 ], [ -74.0085155, 40.71691858 ], [ -74.00855943, 40.71686289 ], [ -74.00861162, 40.7167965 ], [ -74.00869004, 40.71683232 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00872247, 40.71564677 ], [ -74.00859015, 40.71581291 ], [ -74.00851038, 40.71577607 ], [ -74.00863812, 40.71561586 ], [ -74.00864279, 40.71561001 ], [ -74.00872247, 40.71564677 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00443697, 40.71874581 ], [ -74.00430707, 40.7189101 ], [ -74.0042265, 40.7188732 ], [ -74.00435639, 40.71870891 ], [ -74.00443697, 40.71874581 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01039909, 40.71571227 ], [ -74.01026883, 40.71588052 ], [ -74.01026362, 40.71588719 ], [ -74.01019014, 40.71585431 ], [ -74.01019535, 40.71584757 ], [ -74.01033118, 40.71567217 ], [ -74.01040475, 40.71570506 ], [ -74.01039909, 40.71571227 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01000518, 40.71596236 ], [ -74.00987223, 40.71613231 ], [ -74.00979398, 40.7160969 ], [ -74.00983099, 40.71604958 ], [ -74.00991723, 40.71593948 ], [ -74.00992702, 40.71592689 ], [ -74.01000518, 40.71596236 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00825867, 40.71516879 ], [ -74.00812464, 40.71533717 ], [ -74.00804685, 40.71530129 ], [ -74.00818088, 40.71513291 ], [ -74.00825867, 40.71516879 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00681463, 40.71451057 ], [ -74.00667872, 40.71468039 ], [ -74.00660191, 40.71464478 ], [ -74.00673783, 40.71447496 ], [ -74.00681463, 40.71451057 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00802879, 40.71652599 ], [ -74.00794058, 40.71663827 ], [ -74.00790078, 40.71668899 ], [ -74.00782003, 40.71665216 ], [ -74.0078229, 40.71664848 ], [ -74.00794804, 40.71648929 ], [ -74.00802879, 40.71652599 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00835758, 40.71477428 ], [ -74.00821825, 40.71495097 ], [ -74.00814378, 40.71491707 ], [ -74.00828329, 40.71474031 ], [ -74.00835758, 40.71477428 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00876667, 40.71686718 ], [ -74.00867028, 40.71698946 ], [ -74.0086321, 40.71703808 ], [ -74.00855539, 40.71700308 ], [ -74.00869004, 40.71683232 ], [ -74.00876667, 40.71686718 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01055809, 40.71500279 ], [ -74.01041661, 40.71518479 ], [ -74.01034411, 40.71515218 ], [ -74.01046943, 40.71499101 ], [ -74.0104856, 40.71497018 ], [ -74.01055809, 40.71500279 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00768654, 40.71447088 ], [ -74.00754514, 40.71464859 ], [ -74.00747184, 40.71461482 ], [ -74.00761323, 40.7144371 ], [ -74.00762042, 40.71444037 ], [ -74.00768654, 40.71447088 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00983791, 40.71616642 ], [ -74.00971484, 40.71632377 ], [ -74.00964208, 40.71629089 ], [ -74.00964927, 40.71628169 ], [ -74.00973425, 40.71617316 ], [ -74.00978302, 40.71611086 ], [ -74.00985561, 40.71614382 ], [ -74.00983791, 40.71616642 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01031258, 40.71492047 ], [ -74.01018727, 40.71508171 ], [ -74.01010588, 40.71504501 ], [ -74.01023119, 40.71488391 ], [ -74.01031258, 40.71492047 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0102541, 40.71564528 ], [ -74.01012259, 40.71581502 ], [ -74.01011855, 40.71582026 ], [ -74.01004318, 40.71578649 ], [ -74.01016445, 40.71562996 ], [ -74.01017882, 40.7156115 ], [ -74.0102541, 40.71564528 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00761323, 40.7144371 ], [ -74.00747184, 40.71461482 ], [ -74.0073989, 40.71458118 ], [ -74.00754029, 40.71440347 ], [ -74.00754748, 40.7144068 ], [ -74.00761323, 40.7144371 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00568329, 40.71576811 ], [ -74.0055834, 40.71589468 ], [ -74.00554037, 40.71595072 ], [ -74.00546922, 40.71591838 ], [ -74.00551342, 40.71586186 ], [ -74.00561215, 40.71573576 ], [ -74.00568329, 40.71576811 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01327819, 40.71418871 ], [ -74.01326642, 40.71423917 ], [ -74.0124653, 40.71387986 ], [ -74.01248165, 40.7138166 ], [ -74.01250851, 40.71382886 ], [ -74.01249612, 40.71387216 ], [ -74.01261362, 40.71392446 ], [ -74.01294465, 40.71407589 ], [ -74.01325313, 40.71421711 ], [ -74.01326157, 40.71418068 ], [ -74.01327819, 40.71418871 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00879955, 40.71568232 ], [ -74.00866714, 40.71584838 ], [ -74.00859015, 40.71581291 ], [ -74.00872247, 40.71564677 ], [ -74.00879955, 40.71568232 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01058558, 40.71717037 ], [ -74.01057282, 40.7172245 ], [ -74.0102965, 40.71719141 ], [ -74.01026012, 40.71718698 ], [ -74.01027144, 40.71713272 ], [ -74.01058558, 40.71717037 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00986306, 40.71547628 ], [ -74.00973532, 40.71564126 ], [ -74.00973182, 40.71564582 ], [ -74.00965555, 40.71561157 ], [ -74.00965879, 40.71560728 ], [ -74.00975311, 40.71548547 ], [ -74.00976389, 40.71547158 ], [ -74.0097868, 40.71544196 ], [ -74.00986306, 40.71547628 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00484373, 40.71861209 ], [ -74.00479414, 40.71867466 ], [ -74.00459049, 40.71858111 ], [ -74.00464017, 40.71851861 ], [ -74.00465257, 40.71852426 ], [ -74.00484373, 40.71861209 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00856509, 40.71531008 ], [ -74.00842899, 40.71548098 ], [ -74.00835461, 40.71544666 ], [ -74.0084908, 40.71527576 ], [ -74.00856509, 40.71531008 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00628498, 40.71647677 ], [ -74.00625022, 40.71652218 ], [ -74.00619408, 40.71649746 ], [ -74.00618545, 40.7165089 ], [ -74.00616677, 40.71650066 ], [ -74.00617584, 40.71648909 ], [ -74.0061196, 40.71646431 ], [ -74.00611197, 40.71647411 ], [ -74.00609364, 40.71646601 ], [ -74.00610038, 40.71645709 ], [ -74.00604361, 40.71643196 ], [ -74.00603507, 40.71644299 ], [ -74.00601603, 40.71643462 ], [ -74.00602349, 40.71642481 ], [ -74.00596222, 40.71639778 ], [ -74.00599681, 40.71635278 ], [ -74.00605789, 40.71637988 ], [ -74.0060507, 40.7163892 ], [ -74.00606984, 40.71639772 ], [ -74.00607837, 40.71638662 ], [ -74.00613515, 40.71641181 ], [ -74.00612832, 40.71642059 ], [ -74.00614673, 40.71642876 ], [ -74.00615437, 40.71641889 ], [ -74.00621051, 40.71644381 ], [ -74.00620162, 40.71645532 ], [ -74.00622013, 40.71646356 ], [ -74.00622911, 40.71645191 ], [ -74.00628498, 40.71647677 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00604415, 40.71679228 ], [ -74.00598279, 40.71676512 ], [ -74.00599034, 40.71675551 ], [ -74.0059712, 40.716747 ], [ -74.00596267, 40.71675797 ], [ -74.00590599, 40.71673277 ], [ -74.0059129, 40.71672392 ], [ -74.0058944, 40.71671568 ], [ -74.00588694, 40.71672549 ], [ -74.0058308, 40.71670057 ], [ -74.00583978, 40.71668886 ], [ -74.00582118, 40.71668069 ], [ -74.00581319, 40.7166911 ], [ -74.00575731, 40.71666632 ], [ -74.00579127, 40.716622 ], [ -74.00584751, 40.71664678 ], [ -74.00585613, 40.71663541 ], [ -74.00587472, 40.71664358 ], [ -74.00586574, 40.71665536 ], [ -74.00592189, 40.71668007 ], [ -74.00592934, 40.71667041 ], [ -74.00594785, 40.71667858 ], [ -74.00594093, 40.71668756 ], [ -74.0059977, 40.71671262 ], [ -74.00600615, 40.71670166 ], [ -74.00602519, 40.71671017 ], [ -74.00601774, 40.71672011 ], [ -74.00607882, 40.716747 ], [ -74.00604415, 40.71679228 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01040493, 40.71780589 ], [ -74.01038975, 40.71787622 ], [ -74.0101507, 40.7178464 ], [ -74.01016589, 40.717776 ], [ -74.01040493, 40.71780589 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01033118, 40.71567217 ], [ -74.01019535, 40.71584757 ], [ -74.01012259, 40.71581502 ], [ -74.0102541, 40.71564528 ], [ -74.0102585, 40.71563956 ], [ -74.01026452, 40.71564228 ], [ -74.01033118, 40.71567217 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01046934, 40.71575367 ], [ -74.01034474, 40.71591456 ], [ -74.01026883, 40.71588052 ], [ -74.01039909, 40.71571227 ], [ -74.010475, 40.71574632 ], [ -74.01046934, 40.71575367 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00961414, 40.7157852 ], [ -74.00948595, 40.71594902 ], [ -74.00940915, 40.71591416 ], [ -74.00953734, 40.7157504 ], [ -74.00961414, 40.7157852 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00404324, 40.71923616 ], [ -74.00417592, 40.7190684 ], [ -74.00419604, 40.719043 ], [ -74.00426072, 40.71907262 ], [ -74.00410792, 40.71926578 ], [ -74.00404324, 40.71923616 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00498818, 40.7184301 ], [ -74.0049403, 40.71849036 ], [ -74.00473485, 40.71839599 ], [ -74.00478264, 40.71833566 ], [ -74.00484948, 40.71836617 ], [ -74.00498818, 40.7184301 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00894049, 40.71710507 ], [ -74.00892774, 40.71717411 ], [ -74.00868708, 40.71714831 ], [ -74.00869993, 40.71707927 ], [ -74.00894049, 40.71710507 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0049403, 40.71849036 ], [ -74.00489251, 40.71855061 ], [ -74.00470143, 40.71846278 ], [ -74.00468697, 40.71845618 ], [ -74.00473485, 40.71839599 ], [ -74.0049403, 40.71849036 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0072098, 40.71783707 ], [ -74.00715419, 40.71790618 ], [ -74.0070013, 40.71783496 ], [ -74.00699537, 40.71783217 ], [ -74.00700337, 40.7178223 ], [ -74.00698145, 40.71781208 ], [ -74.00702897, 40.71775292 ], [ -74.00712823, 40.71779908 ], [ -74.0072098, 40.71783707 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00805898, 40.71675858 ], [ -74.00799771, 40.71683661 ], [ -74.00785084, 40.71676981 ], [ -74.00784123, 40.7167579 ], [ -74.00786, 40.71673386 ], [ -74.00788947, 40.71669642 ], [ -74.0079121, 40.71669179 ], [ -74.00793878, 40.7167039 ], [ -74.00805898, 40.71675858 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00794804, 40.71648929 ], [ -74.0078229, 40.71664848 ], [ -74.00774484, 40.71661301 ], [ -74.00779317, 40.71655146 ], [ -74.00786988, 40.71645382 ], [ -74.00794804, 40.71648929 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00809761, 40.71537108 ], [ -74.00797247, 40.71552796 ], [ -74.00789477, 40.71549221 ], [ -74.00801981, 40.7153352 ], [ -74.00809761, 40.71537108 ] ] ] } }, { "type": "Feature", "properties": { "height": 64.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00598881, 40.71804249 ], [ -74.00595072, 40.71809096 ], [ -74.00587481, 40.71805651 ], [ -74.00583879, 40.71810206 ], [ -74.00574851, 40.71806107 ], [ -74.0058228, 40.71796712 ], [ -74.00598881, 40.71804249 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01055683, 40.71729197 ], [ -74.0105395, 40.71736489 ], [ -74.01032399, 40.71733909 ], [ -74.01033908, 40.71726589 ], [ -74.01055683, 40.71729197 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00851963, 40.7161686 ], [ -74.00843825, 40.7161319 ], [ -74.00844364, 40.71612489 ], [ -74.00855278, 40.71598476 ], [ -74.00863417, 40.71602146 ], [ -74.00851963, 40.7161686 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00933027, 40.7184382 ], [ -74.00930234, 40.71859582 ], [ -74.00917702, 40.71858302 ], [ -74.00918618, 40.71853141 ], [ -74.00922328, 40.71853516 ], [ -74.00924224, 40.71842908 ], [ -74.00933027, 40.7184382 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00871843, 40.71538082 ], [ -74.00859321, 40.71553797 ], [ -74.00851838, 40.71550352 ], [ -74.0086436, 40.7153463 ], [ -74.00871843, 40.71538082 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00489251, 40.71855061 ], [ -74.00484373, 40.71861209 ], [ -74.00465257, 40.71852426 ], [ -74.00470143, 40.71846278 ], [ -74.00489251, 40.71855061 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00479414, 40.71867466 ], [ -74.00475282, 40.71872668 ], [ -74.00452824, 40.71862346 ], [ -74.00456947, 40.71857151 ], [ -74.00459049, 40.71858111 ], [ -74.00479414, 40.71867466 ] ] ] } }, { "type": "Feature", "properties": { "height": 115.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01095434, 40.71904001 ], [ -74.0109388, 40.71910986 ], [ -74.010717, 40.71908181 ], [ -74.01073236, 40.71901189 ], [ -74.01095434, 40.71904001 ] ] ] } }, { "type": "Feature", "properties": { "height": 115.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01142497, 40.71765801 ], [ -74.01141122, 40.7177282 ], [ -74.01118871, 40.71770301 ], [ -74.01120254, 40.71763281 ], [ -74.01142497, 40.71765801 ] ] ] } }, { "type": "Feature", "properties": { "height": 119.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00713892, 40.71421847 ], [ -74.00708547, 40.71428506 ], [ -74.00691084, 40.71420458 ], [ -74.00692692, 40.71418497 ], [ -74.0069642, 40.71413799 ], [ -74.0069987, 40.71415378 ], [ -74.00710452, 40.7142026 ], [ -74.00713892, 40.71421847 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01027431, 40.71455626 ], [ -74.01015187, 40.71471382 ], [ -74.01007623, 40.7146825 ], [ -74.0102002, 40.71452297 ], [ -74.01027431, 40.71455626 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00963705, 40.71462932 ], [ -74.00961522, 40.71465656 ], [ -74.00951622, 40.71478089 ], [ -74.00943978, 40.71474562 ], [ -74.00956051, 40.71459412 ], [ -74.00963705, 40.71462932 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00535505, 40.7179633 ], [ -74.00521743, 40.71813856 ], [ -74.0051514, 40.7181086 ], [ -74.00526998, 40.71795758 ], [ -74.00528911, 40.71793328 ], [ -74.00535505, 40.7179633 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01038499, 40.71495309 ], [ -74.01025967, 40.71511418 ], [ -74.01018727, 40.71508171 ], [ -74.01031258, 40.71492047 ], [ -74.01038499, 40.71495309 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01014019, 40.71927401 ], [ -74.01012888, 40.71934251 ], [ -74.0099034, 40.71932086 ], [ -74.00991472, 40.7192525 ], [ -74.01014019, 40.71927401 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00895532, 40.71508327 ], [ -74.00883683, 40.71523348 ], [ -74.00876083, 40.71519882 ], [ -74.00887923, 40.71504861 ], [ -74.00895532, 40.71508327 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00903122, 40.715118 ], [ -74.00891283, 40.7152682 ], [ -74.00883683, 40.71523348 ], [ -74.00895532, 40.71508327 ], [ -74.00903122, 40.715118 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01294662, 40.71396851 ], [ -74.01290458, 40.71402169 ], [ -74.01269141, 40.71392527 ], [ -74.01273327, 40.71387196 ], [ -74.01294662, 40.71396851 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00458708, 40.71881451 ], [ -74.0044835, 40.71894557 ], [ -74.00447174, 40.71896062 ], [ -74.00439448, 40.71892522 ], [ -74.00451, 40.71877917 ], [ -74.00458708, 40.71881451 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0100315, 40.71884052 ], [ -74.01000994, 40.7189711 ], [ -74.0099873, 40.71896886 ], [ -74.0099838, 40.71898956 ], [ -74.00994858, 40.71898629 ], [ -74.009952, 40.71896552 ], [ -74.00990124, 40.71896069 ], [ -74.00990178, 40.71895667 ], [ -74.00992271, 40.7188301 ], [ -74.0100315, 40.71884052 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0100677, 40.71667892 ], [ -74.00996853, 40.71680522 ], [ -74.00995514, 40.71682217 ], [ -74.00987771, 40.7167869 ], [ -74.00989145, 40.71676947 ], [ -74.00999018, 40.71664372 ], [ -74.0100677, 40.71667892 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01023039, 40.71632779 ], [ -74.0100977, 40.71649726 ], [ -74.01003249, 40.71646771 ], [ -74.01016508, 40.71629817 ], [ -74.01023039, 40.71632779 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00977952, 40.71881648 ], [ -74.0097435, 40.71903422 ], [ -74.00974278, 40.71903878 ], [ -74.00967675, 40.71903252 ], [ -74.00971332, 40.71881008 ], [ -74.00977952, 40.71881648 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01033908, 40.71726589 ], [ -74.01032399, 40.71733909 ], [ -74.01017442, 40.71732268 ], [ -74.01020874, 40.71719747 ], [ -74.01027862, 40.71720591 ], [ -74.01026802, 40.71725738 ], [ -74.01028249, 40.71725909 ], [ -74.01033908, 40.71726589 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00984671, 40.71882288 ], [ -74.00982578, 40.71894939 ], [ -74.00981195, 40.71903402 ], [ -74.00981078, 40.71904069 ], [ -74.0097435, 40.71903422 ], [ -74.00977952, 40.71881648 ], [ -74.00984671, 40.71882288 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00785829, 40.71567156 ], [ -74.0077549, 40.7158044 ], [ -74.00774888, 40.71581196 ], [ -74.00767153, 40.71577709 ], [ -74.00778104, 40.7156367 ], [ -74.00785829, 40.71567156 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00977018, 40.7146042 ], [ -74.00969804, 40.71469475 ], [ -74.00961522, 40.71465656 ], [ -74.00963705, 40.71462932 ], [ -74.00965385, 40.71460821 ], [ -74.0095774, 40.71457287 ], [ -74.00959626, 40.71454918 ], [ -74.009611, 40.71453066 ], [ -74.00968125, 40.71456307 ], [ -74.00977018, 40.7146042 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00994831, 40.718486 ], [ -74.00991238, 40.71866636 ], [ -74.00983297, 40.7186571 ], [ -74.00986944, 40.71847681 ], [ -74.00994831, 40.718486 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00855278, 40.71598476 ], [ -74.00844364, 40.71612489 ], [ -74.00836683, 40.71609016 ], [ -74.00836908, 40.71608717 ], [ -74.00847589, 40.71595011 ], [ -74.00855278, 40.71598476 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0100412, 40.71814986 ], [ -74.01001632, 40.71827337 ], [ -74.01000563, 40.71832647 ], [ -74.00992559, 40.71831721 ], [ -74.00996134, 40.71814046 ], [ -74.0100412, 40.71814986 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00455708, 40.7176128 ], [ -74.00444191, 40.71778601 ], [ -74.00437858, 40.71775721 ], [ -74.00449141, 40.71758747 ], [ -74.00455708, 40.7176128 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00969804, 40.71469475 ], [ -74.00959905, 40.71481902 ], [ -74.00951622, 40.71478089 ], [ -74.00961522, 40.71465656 ], [ -74.00969804, 40.71469475 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00456148, 40.71898118 ], [ -74.0044835, 40.71894557 ], [ -74.00458708, 40.71881451 ], [ -74.00466514, 40.71885019 ], [ -74.00456148, 40.71898118 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00960255, 40.71809866 ], [ -74.00957372, 40.71824171 ], [ -74.00947859, 40.71823061 ], [ -74.00950742, 40.71808756 ], [ -74.00960255, 40.71809866 ] ] ] } }, { "type": "Feature", "properties": { "height": 92.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00667728, 40.71422507 ], [ -74.00666353, 40.7142423 ], [ -74.00650732, 40.71417026 ], [ -74.00659984, 40.71405396 ], [ -74.00667575, 40.71408896 ], [ -74.00661071, 40.71416999 ], [ -74.00659643, 40.71418776 ], [ -74.00667728, 40.71422507 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00977943, 40.71923956 ], [ -74.00976811, 40.71930799 ], [ -74.00969499, 40.71930098 ], [ -74.00972401, 40.71912511 ], [ -74.00974799, 40.71911347 ], [ -74.0097797, 40.7191166 ], [ -74.00979722, 40.71913206 ], [ -74.00977943, 40.71923956 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00793528, 40.71570628 ], [ -74.00783188, 40.71583905 ], [ -74.0077549, 40.7158044 ], [ -74.00785829, 40.71567156 ], [ -74.00793528, 40.71570628 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00462166, 40.71763908 ], [ -74.00449994, 40.71781229 ], [ -74.00444191, 40.71778601 ], [ -74.00455708, 40.7176128 ], [ -74.00462166, 40.71763908 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01022401, 40.71675 ], [ -74.01012483, 40.7168763 ], [ -74.01004461, 40.71683981 ], [ -74.01014379, 40.71671357 ], [ -74.01022401, 40.71675 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01063103, 40.7169787 ], [ -74.01038184, 40.71694888 ], [ -74.01043161, 40.71688556 ], [ -74.01055441, 40.71691266 ], [ -74.0106075, 40.71692451 ], [ -74.01064029, 40.71693942 ], [ -74.01063103, 40.7169787 ] ] ] } }, { "type": "Feature", "properties": { "height": 11.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0096057, 40.7164688 ], [ -74.00950679, 40.71659456 ], [ -74.00942738, 40.71655847 ], [ -74.00949071, 40.71647785 ], [ -74.0095262, 40.71643271 ], [ -74.0096057, 40.7164688 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00713057, 40.71439325 ], [ -74.00710488, 40.71442526 ], [ -74.00709293, 40.71444017 ], [ -74.00688183, 40.71434287 ], [ -74.00689575, 40.71432571 ], [ -74.00690994, 40.71430787 ], [ -74.00691946, 40.71429602 ], [ -74.00697911, 40.71432346 ], [ -74.00705484, 40.71435826 ], [ -74.00713057, 40.71439325 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01030261, 40.71678581 ], [ -74.01020353, 40.71691198 ], [ -74.01012483, 40.7168763 ], [ -74.01022401, 40.71675 ], [ -74.01030261, 40.71678581 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01045541, 40.71685526 ], [ -74.01043161, 40.71688556 ], [ -74.01038184, 40.71694888 ], [ -74.01035624, 40.7169815 ], [ -74.01028725, 40.71695011 ], [ -74.01027773, 40.71694582 ], [ -74.0103769, 40.71681958 ], [ -74.01045541, 40.71685526 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01015187, 40.71471382 ], [ -74.01011648, 40.71475937 ], [ -74.01008171, 40.71480417 ], [ -74.01004668, 40.71484918 ], [ -74.00997257, 40.71481582 ], [ -74.01007623, 40.7146825 ], [ -74.01015187, 40.71471382 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00999018, 40.71664372 ], [ -74.00989145, 40.71676947 ], [ -74.00981285, 40.7167338 ], [ -74.00991157, 40.71660797 ], [ -74.00999018, 40.71664372 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00809042, 40.71671848 ], [ -74.00800993, 40.71668191 ], [ -74.00801694, 40.71667299 ], [ -74.00810515, 40.71656072 ], [ -74.00818564, 40.71659742 ], [ -74.00809042, 40.71671848 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00447542, 40.71909012 ], [ -74.00443841, 40.71913689 ], [ -74.00429513, 40.71907126 ], [ -74.00422614, 40.71903967 ], [ -74.00425758, 40.7189999 ], [ -74.00430195, 40.71902006 ], [ -74.00430743, 40.71901318 ], [ -74.00433654, 40.71902646 ], [ -74.00447542, 40.71909012 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00468419, 40.71766747 ], [ -74.00455187, 40.71783598 ], [ -74.00449994, 40.71781229 ], [ -74.00462166, 40.71763908 ], [ -74.00468419, 40.71766747 ] ] ] } }, { "type": "Feature", "properties": { "height": 53.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01210122, 40.7157297 ], [ -74.01205612, 40.71578738 ], [ -74.01188841, 40.715712 ], [ -74.0119335, 40.71565426 ], [ -74.01210122, 40.7157297 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00855943, 40.71686289 ], [ -74.0085155, 40.71691858 ], [ -74.00850248, 40.71691266 ], [ -74.0083583, 40.71684689 ], [ -74.00840707, 40.71678479 ], [ -74.00848541, 40.71682047 ], [ -74.0085385, 40.71684478 ], [ -74.00853347, 40.71685111 ], [ -74.00855943, 40.71686289 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01014379, 40.71671357 ], [ -74.01004461, 40.71683981 ], [ -74.00996853, 40.71680522 ], [ -74.0100677, 40.71667892 ], [ -74.01014379, 40.71671357 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00725004, 40.7177871 ], [ -74.00716839, 40.7177491 ], [ -74.00726002, 40.71763526 ], [ -74.00734158, 40.71767326 ], [ -74.00725004, 40.7177871 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0103769, 40.71681958 ], [ -74.01027773, 40.71694582 ], [ -74.01020353, 40.71691198 ], [ -74.01030261, 40.71678581 ], [ -74.0103769, 40.71681958 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00417592, 40.7190684 ], [ -74.00404324, 40.71923616 ], [ -74.00398781, 40.71921076 ], [ -74.00412049, 40.719043 ], [ -74.00417592, 40.7190684 ] ] ] } }, { "type": "Feature", "properties": { "height": 11.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00967981, 40.7165025 ], [ -74.00958099, 40.71662826 ], [ -74.00950679, 40.71659456 ], [ -74.0096057, 40.7164688 ], [ -74.00967981, 40.7165025 ] ] ] } }, { "type": "Feature", "properties": { "height": 157.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00592045, 40.7158477 ], [ -74.00587194, 40.71591136 ], [ -74.00585712, 40.71593179 ], [ -74.0057672, 40.71589312 ], [ -74.00578238, 40.71587221 ], [ -74.00583089, 40.71580862 ], [ -74.00584634, 40.71578738 ], [ -74.00593617, 40.71582612 ], [ -74.00592045, 40.7158477 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01326157, 40.71418068 ], [ -74.01325313, 40.71421711 ], [ -74.01294465, 40.71407589 ], [ -74.01296962, 40.71404416 ], [ -74.01326157, 40.71418068 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01143431, 40.71878857 ], [ -74.01137565, 40.71905757 ], [ -74.01133019, 40.71905158 ], [ -74.01135831, 40.71892719 ], [ -74.01138948, 40.71878278 ], [ -74.01143431, 40.71878857 ] ] ] } }, { "type": "Feature", "properties": { "height": 11.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00715419, 40.71790618 ], [ -74.00710631, 40.71796507 ], [ -74.00695468, 40.7178929 ], [ -74.0070013, 40.71783496 ], [ -74.00715419, 40.71790618 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00810515, 40.71656072 ], [ -74.00801694, 40.71667299 ], [ -74.00797732, 40.71665502 ], [ -74.00794058, 40.71663827 ], [ -74.00802879, 40.71652599 ], [ -74.00810515, 40.71656072 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00845657, 40.71697087 ], [ -74.00841049, 40.7170295 ], [ -74.00826622, 40.71696366 ], [ -74.00831239, 40.71690517 ], [ -74.00845657, 40.71697087 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00850248, 40.71691266 ], [ -74.00845657, 40.71697087 ], [ -74.00831239, 40.71690517 ], [ -74.0083583, 40.71684689 ], [ -74.00850248, 40.71691266 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0097011, 40.71538416 ], [ -74.00956024, 40.71532097 ], [ -74.00960669, 40.71526092 ], [ -74.00969292, 40.71529959 ], [ -74.00974772, 40.7153241 ], [ -74.0097011, 40.71538416 ] ] ] } }, { "type": "Feature", "properties": { "height": 117.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00828859, 40.71757079 ], [ -74.00823487, 40.71763989 ], [ -74.00811261, 40.71758529 ], [ -74.00816633, 40.71751618 ], [ -74.00828859, 40.71757079 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01086325, 40.71865356 ], [ -74.01084825, 40.71874881 ], [ -74.01075213, 40.71874009 ], [ -74.01077027, 40.71862476 ], [ -74.01086639, 40.71863361 ], [ -74.01086325, 40.71865356 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00918618, 40.71853141 ], [ -74.00917702, 40.71858302 ], [ -74.00917585, 40.71858969 ], [ -74.00898667, 40.71857029 ], [ -74.008997, 40.71851187 ], [ -74.00918618, 40.71853141 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00841049, 40.7170295 ], [ -74.00836584, 40.71708621 ], [ -74.00822148, 40.71702051 ], [ -74.00826622, 40.71696366 ], [ -74.00841049, 40.7170295 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00452114, 40.71903231 ], [ -74.00447542, 40.71909012 ], [ -74.00433654, 40.71902646 ], [ -74.00438217, 40.71896879 ], [ -74.00444308, 40.71899657 ], [ -74.00452114, 40.71903231 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00443841, 40.71913689 ], [ -74.00439592, 40.71919068 ], [ -74.00425264, 40.71912511 ], [ -74.00429513, 40.71907126 ], [ -74.00443841, 40.71913689 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00957372, 40.71824171 ], [ -74.00955961, 40.71831136 ], [ -74.00955261, 40.71834642 ], [ -74.00945747, 40.71833526 ], [ -74.00947859, 40.71823061 ], [ -74.00957372, 40.71824171 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01032686, 40.71750781 ], [ -74.01029902, 40.71763731 ], [ -74.01022464, 40.71762812 ], [ -74.01025257, 40.71749848 ], [ -74.01032686, 40.71750781 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00439592, 40.71919068 ], [ -74.0043563, 40.71924079 ], [ -74.00421302, 40.71917516 ], [ -74.00425264, 40.71912511 ], [ -74.00439592, 40.71919068 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00992271, 40.7188301 ], [ -74.00990178, 40.71895667 ], [ -74.00982578, 40.71894939 ], [ -74.00984671, 40.71882288 ], [ -74.00992271, 40.7188301 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01077027, 40.71862476 ], [ -74.01075213, 40.71874009 ], [ -74.01066885, 40.71873247 ], [ -74.01066939, 40.71872879 ], [ -74.01068547, 40.71862619 ], [ -74.01068691, 40.71861727 ], [ -74.01077027, 40.71862476 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01025257, 40.71749848 ], [ -74.01022464, 40.71762812 ], [ -74.01015223, 40.71761899 ], [ -74.01018008, 40.71748936 ], [ -74.01025257, 40.71749848 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00799735, 40.71904967 ], [ -74.00793411, 40.71912947 ], [ -74.00783817, 40.71912041 ], [ -74.00791507, 40.71902326 ], [ -74.0079218, 40.71901502 ], [ -74.00799735, 40.71904967 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00991472, 40.7192525 ], [ -74.0099034, 40.71932086 ], [ -74.00976811, 40.71930799 ], [ -74.00977943, 40.71923956 ], [ -74.00980548, 40.71924201 ], [ -74.00991472, 40.7192525 ] ] ] } }, { "type": "Feature", "properties": { "height": 72.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00803005, 40.71737116 ], [ -74.008004, 40.7174037 ], [ -74.00790312, 40.7175298 ], [ -74.00787707, 40.71756228 ], [ -74.0078423, 40.71754587 ], [ -74.00799313, 40.71735386 ], [ -74.00803005, 40.71737116 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01018008, 40.71748936 ], [ -74.01015223, 40.71761899 ], [ -74.01008225, 40.71761028 ], [ -74.0101101, 40.71748071 ], [ -74.01018008, 40.71748936 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00717504, 40.71866241 ], [ -74.00723145, 40.71868828 ], [ -74.00721492, 40.71870918 ], [ -74.00729864, 40.71874758 ], [ -74.00722328, 40.71879361 ], [ -74.00715851, 40.71876392 ], [ -74.00717504, 40.71866241 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01109591, 40.71851051 ], [ -74.0110872, 40.7185662 ], [ -74.01093583, 40.71855238 ], [ -74.01092775, 40.71855156 ], [ -74.01093655, 40.71849601 ], [ -74.01109591, 40.71851051 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01109591, 40.71851051 ], [ -74.01093655, 40.71849601 ], [ -74.01094491, 40.71844235 ], [ -74.01110445, 40.71845699 ], [ -74.01109591, 40.71851051 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0110872, 40.7185662 ], [ -74.01107857, 40.7186204 ], [ -74.0109273, 40.71860658 ], [ -74.01093583, 40.71855238 ], [ -74.0110872, 40.7185662 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00799771, 40.71683661 ], [ -74.00796798, 40.7168744 ], [ -74.00780709, 40.71680127 ], [ -74.00784123, 40.7167579 ], [ -74.00785084, 40.71676981 ], [ -74.00799771, 40.71683661 ] ] ] } }, { "type": "Feature", "properties": { "height": 97.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01502514, 40.71584961 ], [ -74.01486102, 40.7157758 ], [ -74.0148904, 40.71573719 ], [ -74.01505434, 40.71581379 ], [ -74.01502514, 40.71584961 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00619183, 40.71677431 ], [ -74.00622049, 40.71673877 ], [ -74.0062036, 40.71673087 ], [ -74.00621662, 40.7167148 ], [ -74.00623234, 40.71672208 ], [ -74.00625857, 40.71668961 ], [ -74.00624555, 40.71668348 ], [ -74.00625813, 40.71666789 ], [ -74.00627322, 40.7166749 ], [ -74.0063025, 40.71663881 ], [ -74.00628903, 40.71663248 ], [ -74.00629774, 40.71662179 ], [ -74.00630915, 40.7166271 ], [ -74.00633816, 40.71659129 ], [ -74.00636979, 40.71660531 ], [ -74.00634113, 40.71664249 ], [ -74.00632882, 40.71663711 ], [ -74.00632038, 40.71664787 ], [ -74.0063334, 40.71665366 ], [ -74.0063052, 40.71669022 ], [ -74.00628921, 40.71668307 ], [ -74.00627699, 40.71669887 ], [ -74.00628957, 40.71670459 ], [ -74.00626423, 40.71673747 ], [ -74.00624761, 40.71673012 ], [ -74.00623513, 40.71674639 ], [ -74.00625148, 40.71675361 ], [ -74.00622444, 40.71678881 ], [ -74.00619183, 40.71677431 ] ] ] } }, { "type": "Feature", "properties": { "height": 11.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01068547, 40.71862619 ], [ -74.01066939, 40.71872879 ], [ -74.01059429, 40.71872198 ], [ -74.01061055, 40.71861938 ], [ -74.01068547, 40.71862619 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01439713, 40.71719059 ], [ -74.01436201, 40.71723492 ], [ -74.01423238, 40.71717541 ], [ -74.0142675, 40.71713108 ], [ -74.01439713, 40.71719059 ] ] ] } }, { "type": "Feature", "properties": { "height": 73.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00490185, 40.71830026 ], [ -74.00484948, 40.71836617 ], [ -74.00478264, 40.71833566 ], [ -74.00476288, 40.71832668 ], [ -74.00481525, 40.71826091 ], [ -74.00483223, 40.7182686 ], [ -74.00490185, 40.71830026 ] ] ] } }, { "type": "Feature", "properties": { "height": 166.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00592045, 40.7158477 ], [ -74.00587194, 40.71591136 ], [ -74.00578238, 40.71587221 ], [ -74.00583089, 40.71580862 ], [ -74.00592045, 40.7158477 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01492615, 40.71651878 ], [ -74.01489309, 40.71656106 ], [ -74.01476095, 40.71650148 ], [ -74.01479392, 40.71645906 ], [ -74.01492615, 40.71651878 ] ] ] } }, { "type": "Feature", "properties": { "height": 42.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0148056, 40.71618269 ], [ -74.0147402, 40.71626386 ], [ -74.01473642, 40.71626862 ], [ -74.01467211, 40.71623812 ], [ -74.01467615, 40.71623322 ], [ -74.01474208, 40.71615226 ], [ -74.0148056, 40.71618269 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01459314, 40.71694221 ], [ -74.01455955, 40.7169847 ], [ -74.01442983, 40.71692526 ], [ -74.01446343, 40.71688277 ], [ -74.01459314, 40.71694221 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00589341, 40.71630689 ], [ -74.0058599, 40.7163506 ], [ -74.00580241, 40.7163252 ], [ -74.00579343, 40.71633691 ], [ -74.00578238, 40.71633208 ], [ -74.00579172, 40.71631996 ], [ -74.00573162, 40.71629347 ], [ -74.00576531, 40.71624956 ], [ -74.00581633, 40.7162723 ], [ -74.00582415, 40.7162757 ], [ -74.00581427, 40.71628837 ], [ -74.00582532, 40.71629327 ], [ -74.00583484, 40.71628088 ], [ -74.00589341, 40.71630689 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00565652, 40.71662159 ], [ -74.0055975, 40.71659537 ], [ -74.00560739, 40.71658257 ], [ -74.00559652, 40.71657767 ], [ -74.00558717, 40.71658972 ], [ -74.00552869, 40.71656371 ], [ -74.00556202, 40.71652027 ], [ -74.00561978, 40.71654581 ], [ -74.00562868, 40.71653416 ], [ -74.00563972, 40.71653907 ], [ -74.00563029, 40.71655132 ], [ -74.00569012, 40.71657767 ], [ -74.00565652, 40.71662159 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00882856, 40.7176179 ], [ -74.00875877, 40.71758617 ], [ -74.00867639, 40.71754866 ], [ -74.00861144, 40.71751911 ], [ -74.00862959, 40.71749596 ], [ -74.00869427, 40.71752558 ], [ -74.00869714, 40.7175221 ], [ -74.0087805, 40.7175601 ], [ -74.00884941, 40.71759148 ], [ -74.00882856, 40.7176179 ] ] ] } }, { "type": "Feature", "properties": { "height": 122.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00710452, 40.7142026 ], [ -74.00706284, 40.71425456 ], [ -74.00695701, 40.7142058 ], [ -74.0069987, 40.71415378 ], [ -74.00710452, 40.7142026 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0148056, 40.71618269 ], [ -74.0147402, 40.71626386 ], [ -74.01467615, 40.71623322 ], [ -74.01474208, 40.71615226 ], [ -74.0148056, 40.71618269 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01100455, 40.71866636 ], [ -74.01098955, 40.71876168 ], [ -74.01091661, 40.71875507 ], [ -74.01093161, 40.71865982 ], [ -74.01100455, 40.71866636 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00809042, 40.71671848 ], [ -74.00805898, 40.71675858 ], [ -74.00793878, 40.7167039 ], [ -74.00797732, 40.71665502 ], [ -74.00801694, 40.71667299 ], [ -74.00800993, 40.71668191 ], [ -74.00809042, 40.71671848 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00861162, 40.7167965 ], [ -74.00855943, 40.71686289 ], [ -74.00853347, 40.71685111 ], [ -74.0085385, 40.71684478 ], [ -74.00848541, 40.71682047 ], [ -74.00853275, 40.71676049 ], [ -74.00861162, 40.7167965 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01093161, 40.71865982 ], [ -74.01091661, 40.71875507 ], [ -74.01084825, 40.71874881 ], [ -74.01086325, 40.71865356 ], [ -74.01093161, 40.71865982 ] ] ] } }, { "type": "Feature", "properties": { "height": 3.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00730673, 40.71845461 ], [ -74.00724852, 40.71852807 ], [ -74.00720261, 40.71850697 ], [ -74.00722247, 40.71841601 ], [ -74.00730673, 40.71845461 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00853302, 40.71798747 ], [ -74.00851667, 40.7180081 ], [ -74.0084528, 40.71797917 ], [ -74.00845064, 40.71798196 ], [ -74.00836423, 40.71794288 ], [ -74.00830062, 40.71791421 ], [ -74.00831913, 40.71789066 ], [ -74.00838363, 40.71791986 ], [ -74.00846924, 40.71795861 ], [ -74.00853302, 40.71798747 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00853275, 40.71676049 ], [ -74.00848541, 40.71682047 ], [ -74.00840707, 40.71678479 ], [ -74.00845442, 40.71672481 ], [ -74.00853275, 40.71676049 ] ] ] } }, { "type": "Feature", "properties": { "height": 77.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00727484, 40.71445998 ], [ -74.00724942, 40.71449192 ], [ -74.00710488, 40.71442526 ], [ -74.00713057, 40.71439325 ], [ -74.00727484, 40.71445998 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00409103, 40.71512147 ], [ -74.00406399, 40.71515429 ], [ -74.00392861, 40.71508702 ], [ -74.00395619, 40.71505447 ], [ -74.00409103, 40.71512147 ] ] ] } }, { "type": "Feature", "properties": { "height": 66.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00490185, 40.71830026 ], [ -74.00483223, 40.7182686 ], [ -74.00488343, 40.71820406 ], [ -74.00495287, 40.71823578 ], [ -74.00490185, 40.71830026 ] ] ] } }, { "type": "Feature", "properties": { "height": 32.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01461578, 40.71530476 ], [ -74.01443513, 40.7152744 ], [ -74.01445067, 40.715217 ], [ -74.01451957, 40.71524689 ], [ -74.01461578, 40.71530476 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00606112, 40.71929321 ], [ -74.00603867, 40.71932126 ], [ -74.00588496, 40.71925039 ], [ -74.00590742, 40.71922227 ], [ -74.00606112, 40.71929321 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01098955, 40.71876168 ], [ -74.01100455, 40.71866636 ], [ -74.01106375, 40.7186718 ], [ -74.01104875, 40.71876712 ], [ -74.01098955, 40.71876168 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00725004, 40.7177871 ], [ -74.0072098, 40.71783707 ], [ -74.00712823, 40.71779908 ], [ -74.00716839, 40.7177491 ], [ -74.00725004, 40.7177871 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00456148, 40.71898118 ], [ -74.00452114, 40.71903231 ], [ -74.00444308, 40.71899657 ], [ -74.00447174, 40.71896062 ], [ -74.0044835, 40.71894557 ], [ -74.00456148, 40.71898118 ] ] ] } }, { "type": "Feature", "properties": { "height": 63.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00799313, 40.71735386 ], [ -74.0078423, 40.71754587 ], [ -74.007822, 40.71753668 ], [ -74.00797283, 40.71734467 ], [ -74.00799313, 40.71735386 ] ] ] } }, { "type": "Feature", "properties": { "height": 128.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00834527, 40.7177088 ], [ -74.00832461, 40.71773467 ], [ -74.00829029, 40.71774107 ], [ -74.00825652, 40.717725 ], [ -74.00824861, 40.71769988 ], [ -74.00826927, 40.71767401 ], [ -74.0083035, 40.71766788 ], [ -74.00833737, 40.71768401 ], [ -74.00834527, 40.7177088 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00595072, 40.71809096 ], [ -74.00593644, 40.71810921 ], [ -74.00591515, 40.71813638 ], [ -74.00587059, 40.71811656 ], [ -74.00583879, 40.71810206 ], [ -74.00587481, 40.71805651 ], [ -74.00595072, 40.71809096 ] ] ] } }, { "type": "Feature", "properties": { "height": 125.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00708233, 40.71419968 ], [ -74.00705017, 40.71423971 ], [ -74.00698163, 40.71420812 ], [ -74.0070137, 40.71416801 ], [ -74.00708233, 40.71419968 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01055441, 40.71691266 ], [ -74.01043161, 40.71688556 ], [ -74.01045541, 40.71685526 ], [ -74.01045955, 40.71685002 ], [ -74.01056573, 40.71689829 ], [ -74.01055441, 40.71691266 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0049562, 40.71915779 ], [ -74.00492494, 40.71914336 ], [ -74.00488783, 40.71912627 ], [ -74.00491209, 40.71909577 ], [ -74.00492071, 40.71909979 ], [ -74.0049297, 40.71908848 ], [ -74.00497812, 40.71911081 ], [ -74.00496985, 40.71912116 ], [ -74.00498108, 40.71912641 ], [ -74.0049562, 40.71915779 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00866507, 40.71804862 ], [ -74.00865052, 40.71806816 ], [ -74.00851667, 40.7180081 ], [ -74.00853302, 40.71798747 ], [ -74.00866507, 40.71804862 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00802403, 40.71741276 ], [ -74.00792315, 40.71753892 ], [ -74.00790312, 40.7175298 ], [ -74.008004, 40.7174037 ], [ -74.00802403, 40.71741276 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.006829, 40.71427056 ], [ -74.00681481, 40.7142884 ], [ -74.00667728, 40.71422507 ], [ -74.00669165, 40.7142073 ], [ -74.006829, 40.71427056 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01409548, 40.71491366 ], [ -74.01401193, 40.71502308 ], [ -74.01404284, 40.71490522 ], [ -74.01409548, 40.71491366 ] ] ] } }, { "type": "Feature", "properties": { "height": 66.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01331772, 40.71402196 ], [ -74.01327819, 40.71418871 ], [ -74.01326157, 40.71418068 ], [ -74.01329912, 40.71401386 ], [ -74.01331772, 40.71402196 ] ] ] } }, { "type": "Feature", "properties": { "height": 88.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00812734, 40.71770669 ], [ -74.0080791, 40.71771996 ], [ -74.00801999, 40.71769307 ], [ -74.00800472, 40.71765058 ], [ -74.00812734, 40.71770669 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00681481, 40.7142884 ], [ -74.00680089, 40.71430556 ], [ -74.00666353, 40.7142423 ], [ -74.00667728, 40.71422507 ], [ -74.00681481, 40.7142884 ] ] ] } }, { "type": "Feature", "properties": { "height": 97.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01479392, 40.71586929 ], [ -74.01477802, 40.71588869 ], [ -74.01475484, 40.71587541 ], [ -74.01457104, 40.71576511 ], [ -74.01476903, 40.71585771 ], [ -74.01479392, 40.71586929 ] ] ] } }, { "type": "Feature", "properties": { "height": 72.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0087805, 40.7175601 ], [ -74.00875877, 40.71758617 ], [ -74.00867639, 40.71754866 ], [ -74.00869427, 40.71752558 ], [ -74.00869714, 40.7175221 ], [ -74.0087805, 40.7175601 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00724942, 40.71449192 ], [ -74.00723747, 40.71450676 ], [ -74.00709293, 40.71444017 ], [ -74.00710488, 40.71442526 ], [ -74.00724942, 40.71449192 ] ] ] } }, { "type": "Feature", "properties": { "height": 104.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00729846, 40.71443016 ], [ -74.00728661, 40.71444507 ], [ -74.00714234, 40.71437862 ], [ -74.00715428, 40.71436377 ], [ -74.00729846, 40.71443016 ] ] ] } }, { "type": "Feature", "properties": { "height": 95.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00728661, 40.71444507 ], [ -74.00727484, 40.71445998 ], [ -74.00713057, 40.71439325 ], [ -74.00714234, 40.71437862 ], [ -74.00728661, 40.71444507 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00454674, 40.71451997 ], [ -74.00452734, 40.71455742 ], [ -74.00446527, 40.71454278 ], [ -74.00447039, 40.7145327 ], [ -74.0044765, 40.71452058 ], [ -74.00448234, 40.71450887 ], [ -74.00448773, 40.71449832 ], [ -74.00454674, 40.71451997 ] ] ] } }, { "type": "Feature", "properties": { "height": 88.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0083141, 40.71747322 ], [ -74.00819157, 40.71741698 ], [ -74.00824178, 40.7174114 ], [ -74.00830862, 40.71744176 ], [ -74.0083141, 40.71747322 ] ] ] } }, { "type": "Feature", "properties": { "height": 72.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00846924, 40.71795861 ], [ -74.0084528, 40.71797917 ], [ -74.00845064, 40.71798196 ], [ -74.00836423, 40.71794288 ], [ -74.00838363, 40.71791986 ], [ -74.00846924, 40.71795861 ] ] ] } }, { "type": "Feature", "properties": { "height": 3.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00724852, 40.71852807 ], [ -74.00718357, 40.71860991 ], [ -74.00720261, 40.71850697 ], [ -74.00724852, 40.71852807 ] ] ] } }, { "type": "Feature", "properties": { "height": 6.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01081178, 40.71507912 ], [ -74.01079111, 40.71510581 ], [ -74.01071907, 40.7150734 ], [ -74.01073991, 40.71504671 ], [ -74.01081178, 40.71507912 ] ] ] } }, { "type": "Feature", "properties": { "height": 81.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00882856, 40.7176179 ], [ -74.00882255, 40.71762566 ], [ -74.00859599, 40.7175217 ], [ -74.00860165, 40.71751482 ], [ -74.00861144, 40.71751911 ], [ -74.00867639, 40.71754866 ], [ -74.00875877, 40.71758617 ], [ -74.00882856, 40.7176179 ] ] ] } }, { "type": "Feature", "properties": { "height": 81.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00853778, 40.71798067 ], [ -74.00853302, 40.71798747 ], [ -74.00846924, 40.71795861 ], [ -74.00838363, 40.71791986 ], [ -74.00831913, 40.71789066 ], [ -74.00830979, 40.71788562 ], [ -74.00831554, 40.71787826 ], [ -74.00853778, 40.71798067 ] ] ] } }, { "type": "Feature", "properties": { "height": 2.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00764369, 40.71782448 ], [ -74.00760452, 40.71787316 ], [ -74.00757398, 40.7178592 ], [ -74.00761323, 40.71781038 ], [ -74.00764369, 40.71782448 ] ] ] } }, { "type": "Feature", "properties": { "height": 101.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00690994, 40.71430787 ], [ -74.00689575, 40.71432571 ], [ -74.00681481, 40.7142884 ], [ -74.006829, 40.71427056 ], [ -74.00690994, 40.71430787 ] ] ] } }, { "type": "Feature", "properties": { "height": 101.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00669165, 40.7142073 ], [ -74.00667728, 40.71422507 ], [ -74.00659643, 40.71418776 ], [ -74.00661071, 40.71416999 ], [ -74.00669165, 40.7142073 ] ] ] } }, { "type": "Feature", "properties": { "height": 92.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00689575, 40.71432571 ], [ -74.00688183, 40.71434287 ], [ -74.00680089, 40.71430556 ], [ -74.00681481, 40.7142884 ], [ -74.00689575, 40.71432571 ] ] ] } }, { "type": "Feature", "properties": { "height": 116.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0069642, 40.71413799 ], [ -74.00692692, 40.71418497 ], [ -74.00689844, 40.71417196 ], [ -74.00693581, 40.71412498 ], [ -74.0069642, 40.71413799 ] ] ] } }, { "type": "Feature", "properties": { "height": 107.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00715428, 40.71436377 ], [ -74.00714234, 40.71437862 ], [ -74.0070667, 40.71434369 ], [ -74.00707865, 40.71432877 ], [ -74.00715428, 40.71436377 ] ] ] } }, { "type": "Feature", "properties": { "height": 104.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0070667, 40.71434369 ], [ -74.00705484, 40.71435826 ], [ -74.00697911, 40.71432346 ], [ -74.00699097, 40.71430869 ], [ -74.0070667, 40.71434369 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00714234, 40.71437862 ], [ -74.00713057, 40.71439325 ], [ -74.00705484, 40.71435826 ], [ -74.0070667, 40.71434369 ], [ -74.00714234, 40.71437862 ] ] ] } }, { "type": "Feature", "properties": { "height": 2.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00454674, 40.71451997 ], [ -74.00453165, 40.71452548 ], [ -74.0044765, 40.71452058 ], [ -74.00448234, 40.71450887 ], [ -74.00448773, 40.71449832 ], [ -74.00454674, 40.71451997 ] ] ] } }, { "type": "Feature", "properties": { "height": 2.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00452734, 40.71455742 ], [ -74.00446527, 40.71454278 ], [ -74.00447039, 40.7145327 ], [ -74.0044765, 40.71452058 ], [ -74.00452204, 40.71454578 ], [ -74.00452734, 40.71455742 ] ] ] } }, { "type": "Feature", "properties": { "height": 88.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00792315, 40.71753892 ], [ -74.0078971, 40.71757147 ], [ -74.00787707, 40.71756228 ], [ -74.00790312, 40.7175298 ], [ -74.00792315, 40.71753892 ] ] ] } }, { "type": "Feature", "properties": { "height": 88.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00804999, 40.71738042 ], [ -74.00802403, 40.71741276 ], [ -74.008004, 40.7174037 ], [ -74.00803005, 40.71737116 ], [ -74.00804999, 40.71738042 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00453165, 40.71452548 ], [ -74.00452204, 40.71454578 ], [ -74.0044765, 40.71452058 ], [ -74.00453165, 40.71452548 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00454674, 40.71451997 ], [ -74.00453165, 40.71452548 ], [ -74.0044765, 40.71452058 ], [ -74.00448234, 40.71450887 ], [ -74.00454674, 40.71451997 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00452734, 40.71455742 ], [ -74.00447039, 40.7145327 ], [ -74.0044765, 40.71452058 ], [ -74.00452204, 40.71454578 ], [ -74.00452734, 40.71455742 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00454674, 40.71451997 ], [ -74.00452734, 40.71455742 ], [ -74.00452204, 40.71454578 ], [ -74.00453165, 40.71452548 ], [ -74.00454674, 40.71451997 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01577497, 40.71305732 ], [ -74.01507123, 40.71274846 ], [ -74.01505703, 40.71278639 ], [ -74.0149699, 40.71281887 ], [ -74.01487198, 40.71278176 ], [ -74.0148259, 40.712717 ], [ -74.01488977, 40.71254582 ], [ -74.01481152, 40.71251511 ], [ -74.01481691, 40.71250081 ], [ -74.01479733, 40.71249652 ], [ -74.01480452, 40.71247732 ], [ -74.0147879, 40.71247371 ], [ -74.01479239, 40.71246146 ], [ -74.01477505, 40.71245771 ], [ -74.01483542, 40.7122962 ], [ -74.01485168, 40.71229967 ], [ -74.01485617, 40.71228769 ], [ -74.01487387, 40.7122915 ], [ -74.01487989, 40.71227516 ], [ -74.01490261, 40.71228006 ], [ -74.01496945, 40.71210111 ], [ -74.01489875, 40.71205767 ], [ -74.01499182, 40.71180832 ], [ -74.01497151, 40.71180389 ], [ -74.01491061, 40.71166696 ], [ -74.01499128, 40.71153717 ], [ -74.01516771, 40.71148842 ], [ -74.01521002, 40.71150292 ], [ -74.01529185, 40.71153111 ], [ -74.01533704, 40.71154657 ], [ -74.01539938, 40.71168357 ], [ -74.01531449, 40.71182609 ], [ -74.01540351, 40.71185659 ], [ -74.01546397, 40.7118775 ], [ -74.01536632, 40.7121389 ], [ -74.01541438, 40.71214932 ], [ -74.01542085, 40.71213189 ], [ -74.0154655, 40.71213046 ], [ -74.01550628, 40.71213298 ], [ -74.01554392, 40.71213747 ], [ -74.01558578, 40.71214816 ], [ -74.01562657, 40.71216539 ], [ -74.01565855, 40.7121833 ], [ -74.01565163, 40.71220087 ], [ -74.01596748, 40.71226889 ], [ -74.01594448, 40.71233038 ], [ -74.0159514, 40.71233188 ], [ -74.01592849, 40.71239547 ], [ -74.01588061, 40.71252138 ], [ -74.01610007, 40.7126165 ], [ -74.01604051, 40.7126961 ], [ -74.0160335, 40.7126931 ], [ -74.01577497, 40.71305732 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01547511, 40.70703651 ], [ -74.01524137, 40.7076423 ], [ -74.01523328, 40.70766321 ], [ -74.01509467, 40.70761431 ], [ -74.01480047, 40.7075106 ], [ -74.01477173, 40.70750039 ], [ -74.01457311, 40.70748377 ], [ -74.01444762, 40.70779776 ], [ -74.01441025, 40.70778462 ], [ -74.01424855, 40.70772756 ], [ -74.01408964, 40.70767158 ], [ -74.01395875, 40.70762521 ], [ -74.01393423, 40.70761636 ], [ -74.01391914, 40.70761091 ], [ -74.01388231, 40.70759851 ], [ -74.01405757, 40.7071915 ], [ -74.01408353, 40.70713151 ], [ -74.014135, 40.70701186 ], [ -74.01417992, 40.70690767 ], [ -74.01418163, 40.70689957 ], [ -74.01418719, 40.70688377 ], [ -74.01419582, 40.70686872 ], [ -74.01420714, 40.70685469 ], [ -74.0142137, 40.70684829 ], [ -74.0142287, 40.70683651 ], [ -74.01424568, 40.70682636 ], [ -74.01426445, 40.70681826 ], [ -74.01428448, 40.70681227 ], [ -74.0143055, 40.70680859 ], [ -74.01432554, 40.70680716 ], [ -74.01430137, 40.70680137 ], [ -74.01433811, 40.706714 ], [ -74.01437665, 40.7067234 ], [ -74.01445723, 40.70674308 ], [ -74.01442139, 40.7068282 ], [ -74.01447681, 40.70684822 ], [ -74.01449613, 40.70685776 ], [ -74.01451364, 40.7068692 ], [ -74.01452155, 40.7068756 ], [ -74.01453574, 40.70688949 ], [ -74.01454185, 40.70689691 ], [ -74.01455209, 40.70691257 ], [ -74.01455955, 40.70692919 ], [ -74.01456215, 40.7069377 ], [ -74.01456718, 40.70694649 ], [ -74.01464695, 40.70708479 ], [ -74.01465656, 40.70708377 ], [ -74.01470184, 40.70714009 ], [ -74.01466429, 40.70724046 ], [ -74.01463294, 40.7073247 ], [ -74.01486569, 40.70734696 ], [ -74.0149831, 40.70705258 ], [ -74.01509027, 40.7067744 ], [ -74.01511183, 40.70672299 ], [ -74.01514857, 40.70663501 ], [ -74.01517049, 40.70658251 ], [ -74.015272, 40.70660688 ], [ -74.0154107, 40.70664018 ], [ -74.01572709, 40.70671611 ], [ -74.01565253, 40.7068948 ], [ -74.01560617, 40.70701479 ], [ -74.01558973, 40.70702262 ], [ -74.01557213, 40.70702902 ], [ -74.01555389, 40.70703399 ], [ -74.01553548, 40.70703746 ], [ -74.01550835, 40.70703958 ], [ -74.0154911, 40.70703889 ], [ -74.01547511, 40.70703651 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01592849, 40.71239547 ], [ -74.0159001, 40.71238887 ], [ -74.01570598, 40.71288982 ], [ -74.01507123, 40.71274846 ], [ -74.01505703, 40.71278639 ], [ -74.0149699, 40.71281887 ], [ -74.01487198, 40.71278176 ], [ -74.0148259, 40.712717 ], [ -74.01488977, 40.71254582 ], [ -74.01481152, 40.71251511 ], [ -74.01481691, 40.71250081 ], [ -74.01479733, 40.71249652 ], [ -74.01480452, 40.71247732 ], [ -74.0147879, 40.71247371 ], [ -74.01479239, 40.71246146 ], [ -74.01477505, 40.71245771 ], [ -74.01483542, 40.7122962 ], [ -74.01485168, 40.71229967 ], [ -74.01485617, 40.71228769 ], [ -74.01487387, 40.7122915 ], [ -74.01487989, 40.71227516 ], [ -74.01490261, 40.71228006 ], [ -74.01496945, 40.71210111 ], [ -74.01489875, 40.71205767 ], [ -74.01499182, 40.71180832 ], [ -74.01497151, 40.71180389 ], [ -74.01491061, 40.71166696 ], [ -74.01499128, 40.71153717 ], [ -74.01516771, 40.71148842 ], [ -74.01521002, 40.71150292 ], [ -74.01529185, 40.71153111 ], [ -74.01533704, 40.71154657 ], [ -74.01539938, 40.71168357 ], [ -74.01531449, 40.71182609 ], [ -74.01540351, 40.71185659 ], [ -74.01530802, 40.71211841 ], [ -74.01536632, 40.7121389 ], [ -74.01541438, 40.71214932 ], [ -74.01565163, 40.71220087 ], [ -74.01596748, 40.71226889 ], [ -74.01594448, 40.71233038 ], [ -74.0159514, 40.71233188 ], [ -74.01592849, 40.71239547 ] ] ] } }, { "type": "Feature", "properties": { "height": 36.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01143224, 40.71276977 ], [ -74.01095847, 40.71320596 ], [ -74.0098716, 40.71271271 ], [ -74.01005548, 40.71247821 ], [ -74.01024808, 40.71223239 ], [ -74.01143224, 40.71276977 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00561242, 40.71161139 ], [ -74.00555861, 40.71164408 ], [ -74.00553471, 40.71162147 ], [ -74.00551881, 40.71163121 ], [ -74.00552393, 40.71163611 ], [ -74.00532954, 40.71175439 ], [ -74.00532397, 40.71174921 ], [ -74.00530645, 40.71175997 ], [ -74.00532999, 40.71178237 ], [ -74.00527582, 40.7118154 ], [ -74.00522111, 40.71176331 ], [ -74.00519371, 40.71177999 ], [ -74.00494649, 40.7115448 ], [ -74.00486502, 40.71159437 ], [ -74.0046982, 40.71143572 ], [ -74.00477995, 40.71138587 ], [ -74.00402581, 40.71066851 ], [ -74.00405465, 40.71065101 ], [ -74.00400012, 40.71059919 ], [ -74.00405213, 40.71056746 ], [ -74.00407468, 40.71058911 ], [ -74.00409229, 40.71057835 ], [ -74.00408672, 40.71057298 ], [ -74.00427914, 40.71045592 ], [ -74.00428372, 40.71046021 ], [ -74.00430231, 40.71044898 ], [ -74.00428138, 40.71042909 ], [ -74.00433438, 40.71039682 ], [ -74.00438684, 40.71044666 ], [ -74.00441658, 40.71042862 ], [ -74.00558601, 40.71154119 ], [ -74.00555708, 40.71155876 ], [ -74.00561242, 40.71161139 ] ], [ [ -74.00501791, 40.71112276 ], [ -74.00490239, 40.71101 ], [ -74.00470745, 40.71112548 ], [ -74.00475003, 40.71116716 ], [ -74.00470179, 40.71119576 ], [ -74.00481849, 40.71130988 ], [ -74.0049305, 40.71124349 ], [ -74.00489844, 40.71121217 ], [ -74.00495206, 40.71118037 ], [ -74.00497237, 40.71120032 ], [ -74.00500363, 40.7111818 ], [ -74.00497138, 40.71115027 ], [ -74.00501791, 40.71112276 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01543981, 40.71340956 ], [ -74.01541034, 40.71345021 ], [ -74.01536264, 40.71351571 ], [ -74.01530874, 40.71359129 ], [ -74.01525457, 40.71366612 ], [ -74.01510608, 40.71387291 ], [ -74.01516043, 40.71389497 ], [ -74.01517211, 40.71395557 ], [ -74.01514318, 40.71399527 ], [ -74.01512504, 40.71402026 ], [ -74.01503341, 40.7140432 ], [ -74.01499262, 40.71402611 ], [ -74.01497223, 40.7140541 ], [ -74.01468432, 40.71393297 ], [ -74.0146898, 40.71392541 ], [ -74.01460338, 40.71388912 ], [ -74.01460087, 40.71389252 ], [ -74.01432104, 40.71375866 ], [ -74.01441231, 40.71352402 ], [ -74.0143974, 40.71352068 ], [ -74.01440243, 40.71350706 ], [ -74.01438429, 40.71350318 ], [ -74.01439012, 40.71348766 ], [ -74.01437045, 40.7134835 ], [ -74.01443073, 40.71332158 ], [ -74.0144504, 40.7133258 ], [ -74.01445543, 40.71331225 ], [ -74.01447358, 40.71331627 ], [ -74.01447915, 40.71330136 ], [ -74.01449981, 40.71330592 ], [ -74.01450421, 40.71329407 ], [ -74.01459647, 40.7132983 ], [ -74.0146651, 40.71312671 ], [ -74.01475861, 40.71308558 ], [ -74.01492633, 40.71314366 ], [ -74.01504473, 40.71318479 ], [ -74.01502739, 40.71320869 ], [ -74.01516663, 40.71326731 ], [ -74.01515091, 40.7132889 ], [ -74.01543981, 40.71340956 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00392475, 40.71026928 ], [ -74.00340597, 40.71066517 ], [ -74.00258743, 40.71004879 ], [ -74.00310621, 40.70965289 ], [ -74.00392475, 40.71026928 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00412283, 40.71285829 ], [ -74.00394038, 40.7130497 ], [ -74.0038422, 40.7131536 ], [ -74.00367538, 40.7133369 ], [ -74.00349311, 40.71353198 ], [ -74.00323143, 40.71339029 ], [ -74.00324095, 40.71338007 ], [ -74.00320439, 40.71304398 ], [ -74.00318795, 40.71303506 ], [ -74.00327284, 40.71294429 ], [ -74.00326152, 40.71293809 ], [ -74.00328264, 40.71291556 ], [ -74.00330428, 40.71289138 ], [ -74.00339933, 40.71278108 ], [ -74.00345853, 40.71272742 ], [ -74.00347155, 40.71273437 ], [ -74.00355572, 40.71264428 ], [ -74.00357171, 40.71265286 ], [ -74.00404225, 40.7125303 ], [ -74.00404917, 40.71252287 ], [ -74.00408052, 40.7125399 ], [ -74.00430627, 40.71266198 ], [ -74.00412283, 40.71285829 ] ] ] } }, { "type": "Feature", "properties": { "height": 320.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01222851, 40.71090772 ], [ -74.01205082, 40.71141059 ], [ -74.01107669, 40.71103621 ], [ -74.01114882, 40.71091698 ], [ -74.01110463, 40.71090282 ], [ -74.01134304, 40.71054036 ], [ -74.01222851, 40.71090772 ] ] ] } }, { "type": "Feature", "properties": { "height": 39.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01023892, 40.71359129 ], [ -74.00972742, 40.71335896 ], [ -74.00945981, 40.71323749 ], [ -74.00975158, 40.71286837 ], [ -74.01001901, 40.71298991 ], [ -74.01053105, 40.71322237 ], [ -74.01078959, 40.71333976 ], [ -74.0104979, 40.71370888 ], [ -74.01023892, 40.71359129 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00908863, 40.7062602 ], [ -74.00904919, 40.70630671 ], [ -74.00901263, 40.70634988 ], [ -74.00898191, 40.70638611 ], [ -74.00897517, 40.70639408 ], [ -74.00895118, 40.70642241 ], [ -74.00887141, 40.70651659 ], [ -74.00879829, 40.706603 ], [ -74.00871897, 40.70669657 ], [ -74.00870442, 40.7067138 ], [ -74.00799394, 40.70629867 ], [ -74.00817414, 40.70608587 ], [ -74.00821403, 40.70603888 ], [ -74.00804047, 40.70595376 ], [ -74.00821475, 40.70577418 ], [ -74.00908863, 40.7062602 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01338662, 40.71372488 ], [ -74.01334853, 40.71388701 ], [ -74.01331772, 40.71402196 ], [ -74.01327819, 40.71418871 ], [ -74.01326642, 40.71423917 ], [ -74.0124653, 40.71387986 ], [ -74.01248165, 40.7138166 ], [ -74.01250752, 40.7137163 ], [ -74.01252298, 40.71365638 ], [ -74.01255541, 40.71353089 ], [ -74.01260122, 40.71335359 ], [ -74.01261559, 40.71330231 ], [ -74.01339991, 40.71366878 ], [ -74.01338662, 40.71372488 ] ] ] } }, { "type": "Feature", "properties": { "height": 41.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00550013, 40.71042099 ], [ -74.005192, 40.71060648 ], [ -74.00520548, 40.71061942 ], [ -74.00515571, 40.71067137 ], [ -74.00520737, 40.71072108 ], [ -74.00508178, 40.71079666 ], [ -74.00502285, 40.71073987 ], [ -74.00491362, 40.71063501 ], [ -74.00489314, 40.7106474 ], [ -74.00442341, 40.71019567 ], [ -74.00454189, 40.71012431 ], [ -74.00451153, 40.71009509 ], [ -74.00485343, 40.70979596 ], [ -74.00550013, 40.71042099 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01463294, 40.7073247 ], [ -74.01460518, 40.70739851 ], [ -74.01457311, 40.70748377 ], [ -74.01444762, 40.70779776 ], [ -74.01441025, 40.70778462 ], [ -74.01424855, 40.70772756 ], [ -74.01408964, 40.70767158 ], [ -74.01395875, 40.70762521 ], [ -74.01393423, 40.70761636 ], [ -74.01391914, 40.70761091 ], [ -74.01388231, 40.70759851 ], [ -74.01405757, 40.7071915 ], [ -74.01408353, 40.70713151 ], [ -74.014135, 40.70701186 ], [ -74.01417992, 40.70690767 ], [ -74.01418163, 40.70689957 ], [ -74.01418719, 40.70688377 ], [ -74.01419582, 40.70686872 ], [ -74.01420714, 40.70685469 ], [ -74.0142137, 40.70684829 ], [ -74.0142287, 40.70683651 ], [ -74.01424568, 40.70682636 ], [ -74.01426445, 40.70681826 ], [ -74.01428448, 40.70681227 ], [ -74.0143055, 40.70680859 ], [ -74.01432554, 40.70680716 ], [ -74.01442139, 40.7068282 ], [ -74.01447681, 40.70684822 ], [ -74.01449613, 40.70685776 ], [ -74.01451364, 40.7068692 ], [ -74.01452155, 40.7068756 ], [ -74.01453574, 40.70688949 ], [ -74.01454185, 40.70689691 ], [ -74.01455209, 40.70691257 ], [ -74.01455955, 40.70692919 ], [ -74.01456215, 40.7069377 ], [ -74.01456718, 40.70694649 ], [ -74.01464695, 40.70708479 ], [ -74.01465656, 40.70708377 ], [ -74.01470184, 40.70714009 ], [ -74.01466429, 40.70724046 ], [ -74.01463294, 40.7073247 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01247725, 40.71025831 ], [ -74.0123107, 40.71070562 ], [ -74.01217614, 40.71064679 ], [ -74.01214685, 40.7106822 ], [ -74.01144248, 40.71037898 ], [ -74.01176174, 40.70989367 ], [ -74.01187484, 40.70994297 ], [ -74.01246405, 40.7101939 ], [ -74.01249432, 40.71020772 ], [ -74.01247725, 40.71025831 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01177962, 40.71214816 ], [ -74.01157301, 40.7125128 ], [ -74.01117308, 40.71242578 ], [ -74.01082624, 40.712271 ], [ -74.01050832, 40.7121293 ], [ -74.01056465, 40.71206516 ], [ -74.01059133, 40.71207326 ], [ -74.01071494, 40.71183739 ], [ -74.01104219, 40.71189929 ], [ -74.01142568, 40.71198631 ], [ -74.01177962, 40.71214816 ] ] ] } }, { "type": "Feature", "properties": { "height": 107.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00412283, 40.71285829 ], [ -74.00402321, 40.71280436 ], [ -74.00392017, 40.71284106 ], [ -74.00379081, 40.71297486 ], [ -74.00369173, 40.71308306 ], [ -74.00358932, 40.71319507 ], [ -74.00357567, 40.71328298 ], [ -74.00367538, 40.7133369 ], [ -74.00349311, 40.71353198 ], [ -74.00323143, 40.71339029 ], [ -74.00324095, 40.71338007 ], [ -74.00320439, 40.71304398 ], [ -74.00318795, 40.71303506 ], [ -74.00327284, 40.71294429 ], [ -74.00326152, 40.71293809 ], [ -74.00328264, 40.71291556 ], [ -74.00330428, 40.71289138 ], [ -74.00339933, 40.71278108 ], [ -74.00345853, 40.71272742 ], [ -74.00347155, 40.71273437 ], [ -74.00355572, 40.71264428 ], [ -74.00357171, 40.71265286 ], [ -74.00404225, 40.7125303 ], [ -74.00404917, 40.71252287 ], [ -74.00408052, 40.7125399 ], [ -74.00430627, 40.71266198 ], [ -74.00412283, 40.71285829 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00735515, 40.70604889 ], [ -74.0068043, 40.7065917 ], [ -74.00623477, 40.70616888 ], [ -74.00684347, 40.70574701 ], [ -74.00735515, 40.70604889 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00926829, 40.70863167 ], [ -74.00891741, 40.70892441 ], [ -74.00886405, 40.70892141 ], [ -74.00811, 40.70798966 ], [ -74.00810551, 40.70796726 ], [ -74.00825301, 40.70780798 ], [ -74.0082761, 40.70780566 ], [ -74.00926829, 40.70863167 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00926164, 40.70862472 ], [ -74.00889055, 40.7089462 ], [ -74.00845747, 40.70844046 ], [ -74.00809527, 40.7079917 ], [ -74.00826757, 40.70782092 ], [ -74.00926164, 40.70862472 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01450152, 40.70556042 ], [ -74.014431, 40.70572052 ], [ -74.01424038, 40.70615288 ], [ -74.01396289, 40.70605849 ], [ -74.0137605, 40.70598958 ], [ -74.01343135, 40.70587755 ], [ -74.01350367, 40.7057878 ], [ -74.01351687, 40.70579441 ], [ -74.01374073, 40.70551677 ], [ -74.01372699, 40.70551078 ], [ -74.01381502, 40.70540161 ], [ -74.01391905, 40.70542572 ], [ -74.0140776, 40.70546229 ], [ -74.01416357, 40.70548217 ], [ -74.01432212, 40.70551888 ], [ -74.01450152, 40.70556042 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01023892, 40.71359129 ], [ -74.01027683, 40.71354322 ], [ -74.00976542, 40.71331096 ], [ -74.00972742, 40.71335896 ], [ -74.00945981, 40.71323749 ], [ -74.00975158, 40.71286837 ], [ -74.01001901, 40.71298991 ], [ -74.00998874, 40.71302832 ], [ -74.01050069, 40.71326078 ], [ -74.01053105, 40.71322237 ], [ -74.01078959, 40.71333976 ], [ -74.0104979, 40.71370888 ], [ -74.01023892, 40.71359129 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01096646, 40.70843412 ], [ -74.01092128, 40.70848771 ], [ -74.01089442, 40.70851958 ], [ -74.01077405, 40.70866599 ], [ -74.0103363, 40.70837788 ], [ -74.01028159, 40.70834199 ], [ -74.00993834, 40.70811598 ], [ -74.01005, 40.70799068 ], [ -74.01008728, 40.70794928 ], [ -74.01012465, 40.70790788 ], [ -74.0102356, 40.70778326 ], [ -74.01068547, 40.70805108 ], [ -74.01108873, 40.70829098 ], [ -74.01096646, 40.70843412 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01333218, 40.71337449 ], [ -74.01329625, 40.71338062 ], [ -74.01271773, 40.71314999 ], [ -74.0127039, 40.71312698 ], [ -74.01268997, 40.7131039 ], [ -74.01300465, 40.71264081 ], [ -74.01304238, 40.71263386 ], [ -74.01308038, 40.71262699 ], [ -74.01365899, 40.71285761 ], [ -74.01367084, 40.71288151 ], [ -74.0136827, 40.71290548 ], [ -74.0133682, 40.7133685 ], [ -74.01333218, 40.71337449 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01228914, 40.70555068 ], [ -74.0122409, 40.70564977 ], [ -74.01220147, 40.70564568 ], [ -74.0121323, 40.70563839 ], [ -74.01200132, 40.70562471 ], [ -74.01179318, 40.7056275 ], [ -74.01164748, 40.70562968 ], [ -74.01157723, 40.70562988 ], [ -74.01156861, 40.70563002 ], [ -74.01163975, 40.70504546 ], [ -74.01232014, 40.70507147 ], [ -74.01248408, 40.70507848 ], [ -74.01248049, 40.7051442 ], [ -74.01228914, 40.70555068 ] ] ] } }, { "type": "Feature", "properties": { "height": 72.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01135723, 40.71279177 ], [ -74.01095479, 40.71314986 ], [ -74.01071619, 40.71303969 ], [ -74.01079821, 40.7129366 ], [ -74.01040753, 40.71275799 ], [ -74.01032651, 40.71285979 ], [ -74.00998245, 40.712701 ], [ -74.01029695, 40.71231118 ], [ -74.0106393, 40.71246636 ], [ -74.01055432, 40.71257326 ], [ -74.010945, 40.71275187 ], [ -74.01103096, 40.71264387 ], [ -74.01135723, 40.71279177 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00734086, 40.70604712 ], [ -74.00681724, 40.70656657 ], [ -74.0062822, 40.70616779 ], [ -74.00686188, 40.70577166 ], [ -74.00734086, 40.70604712 ] ] ] } }, { "type": "Feature", "properties": { "height": 47.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01195326, 40.71177652 ], [ -74.01190098, 40.71185687 ], [ -74.0118187, 40.71188969 ], [ -74.01169814, 40.71188261 ], [ -74.01156501, 40.71184332 ], [ -74.01144455, 40.71179449 ], [ -74.01131609, 40.7117313 ], [ -74.01119554, 40.71165511 ], [ -74.01098228, 40.71148141 ], [ -74.01090592, 40.71138471 ], [ -74.01086981, 40.71129061 ], [ -74.01090673, 40.71122926 ], [ -74.01098883, 40.71119167 ], [ -74.01112035, 40.7112012 ], [ -74.01136532, 40.71126916 ], [ -74.01158271, 40.71138281 ], [ -74.01169176, 40.71145247 ], [ -74.01179363, 40.71153111 ], [ -74.01187188, 40.7116086 ], [ -74.01193925, 40.71169426 ], [ -74.01195326, 40.71177652 ] ] ] } }, { "type": "Feature", "properties": { "height": 155.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01096646, 40.70843412 ], [ -74.01077432, 40.70831516 ], [ -74.01076605, 40.70832326 ], [ -74.01074764, 40.70831237 ], [ -74.0107029, 40.70829997 ], [ -74.01065403, 40.70834471 ], [ -74.01067793, 40.70837168 ], [ -74.01070011, 40.70838496 ], [ -74.01068942, 40.70839538 ], [ -74.01089442, 40.70851958 ], [ -74.01077405, 40.70866599 ], [ -74.0103363, 40.70837788 ], [ -74.01028159, 40.70834199 ], [ -74.00993834, 40.70811598 ], [ -74.01005, 40.70799068 ], [ -74.01024458, 40.70811482 ], [ -74.01025212, 40.70810747 ], [ -74.01026973, 40.70811802 ], [ -74.01031995, 40.70812967 ], [ -74.01036325, 40.7080901 ], [ -74.01033567, 40.70805381 ], [ -74.0103204, 40.70804468 ], [ -74.01033019, 40.70803522 ], [ -74.01012465, 40.70790788 ], [ -74.0102356, 40.70778326 ], [ -74.01068547, 40.70805108 ], [ -74.01108873, 40.70829098 ], [ -74.01096646, 40.70843412 ] ] ] } }, { "type": "Feature", "properties": { "height": 226.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01137924, 40.70970566 ], [ -74.01107588, 40.71009251 ], [ -74.01033908, 40.70975789 ], [ -74.01061972, 40.70939999 ], [ -74.01064244, 40.70937111 ], [ -74.01137924, 40.70970566 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00548405, 40.71360947 ], [ -74.00540526, 40.71357318 ], [ -74.00531705, 40.71353246 ], [ -74.00534589, 40.71349637 ], [ -74.00522605, 40.71344108 ], [ -74.00519075, 40.71348507 ], [ -74.00500399, 40.71339907 ], [ -74.00509903, 40.71328059 ], [ -74.00509193, 40.71327726 ], [ -74.00512948, 40.71323048 ], [ -74.0051947, 40.71314931 ], [ -74.00520063, 40.71315197 ], [ -74.00529567, 40.71303349 ], [ -74.0054792, 40.71311806 ], [ -74.00544695, 40.7131583 ], [ -74.00557127, 40.7132157 ], [ -74.00565994, 40.71310519 ], [ -74.00582702, 40.7131822 ], [ -74.00573827, 40.71329271 ], [ -74.00585891, 40.71334827 ], [ -74.00589458, 40.71330381 ], [ -74.006079, 40.71338886 ], [ -74.00597974, 40.71351251 ], [ -74.00598378, 40.71351442 ], [ -74.00588191, 40.71364147 ], [ -74.00587769, 40.71363957 ], [ -74.00578579, 40.71375416 ], [ -74.00560137, 40.71366919 ], [ -74.00563398, 40.71362847 ], [ -74.00551342, 40.71357291 ], [ -74.00548405, 40.71360947 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01027683, 40.71354322 ], [ -74.00976542, 40.71331096 ], [ -74.00953482, 40.71320631 ], [ -74.00975814, 40.71292359 ], [ -74.00998874, 40.71302832 ], [ -74.01050069, 40.71326078 ], [ -74.0107338, 40.71336659 ], [ -74.01051048, 40.7136493 ], [ -74.01027683, 40.71354322 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01577497, 40.71305732 ], [ -74.01574218, 40.71310526 ], [ -74.01564795, 40.71323082 ], [ -74.01555802, 40.71335032 ], [ -74.01549847, 40.71343107 ], [ -74.01543981, 40.71340956 ], [ -74.01515091, 40.7132889 ], [ -74.01516663, 40.71326731 ], [ -74.01502739, 40.71320869 ], [ -74.01504473, 40.71318479 ], [ -74.01492633, 40.71314366 ], [ -74.01475861, 40.71308558 ], [ -74.01487198, 40.71278176 ], [ -74.0149699, 40.71281887 ], [ -74.01505703, 40.71278639 ], [ -74.01507123, 40.71274846 ], [ -74.01577497, 40.71305732 ] ] ] } }, { "type": "Feature", "properties": { "height": 114.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01036971, 40.71095069 ], [ -74.01025473, 40.71109498 ], [ -74.0100253, 40.71098991 ], [ -74.00991076, 40.71113359 ], [ -74.00988579, 40.71116491 ], [ -74.0098769, 40.71117608 ], [ -74.00924996, 40.71088906 ], [ -74.00949565, 40.71058101 ], [ -74.00953859, 40.71052701 ], [ -74.01039487, 40.71091909 ], [ -74.01036971, 40.71095069 ] ] ] } }, { "type": "Feature", "properties": { "height": 181.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01529616, 40.71353178 ], [ -74.01526679, 40.71357311 ], [ -74.01521289, 40.71364801 ], [ -74.01506045, 40.71386052 ], [ -74.01501445, 40.71392466 ], [ -74.01491761, 40.71388476 ], [ -74.01451122, 40.71371739 ], [ -74.01442561, 40.71368212 ], [ -74.01447385, 40.71361492 ], [ -74.01471118, 40.71328386 ], [ -74.01475771, 40.71321911 ], [ -74.01484225, 40.7132539 ], [ -74.01510105, 40.71336142 ], [ -74.01520139, 40.7134022 ], [ -74.01525125, 40.71342236 ], [ -74.01530048, 40.71344299 ], [ -74.01534674, 40.71346178 ], [ -74.01532033, 40.71349801 ], [ -74.01529616, 40.71353178 ] ] ] } }, { "type": "Feature", "properties": { "height": 69.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00921718, 40.70863609 ], [ -74.00892109, 40.70887838 ], [ -74.00888875, 40.70887838 ], [ -74.00817944, 40.70801472 ], [ -74.00816399, 40.70801819 ], [ -74.008148, 40.70801717 ], [ -74.00813354, 40.70801186 ], [ -74.00812249, 40.70800301 ], [ -74.00811665, 40.7079917 ], [ -74.00811638, 40.70797951 ], [ -74.00812204, 40.70796807 ], [ -74.00813273, 40.70795902 ], [ -74.00814701, 40.70795336 ], [ -74.008163, 40.70795221 ], [ -74.00817854, 40.70795541 ], [ -74.00826802, 40.7078711 ], [ -74.00829892, 40.70787029 ], [ -74.00921718, 40.70863609 ] ] ] } }, { "type": "Feature", "properties": { "height": 32.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00513182, 40.71421786 ], [ -74.00540589, 40.71388551 ], [ -74.00541173, 40.71387849 ], [ -74.00548647, 40.71391397 ], [ -74.00549222, 40.71390709 ], [ -74.00611637, 40.71420288 ], [ -74.00583089, 40.71454918 ], [ -74.00513182, 40.71421786 ] ] ] } }, { "type": "Feature", "properties": { "height": 115.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01122302, 40.70755691 ], [ -74.0111852, 40.70759627 ], [ -74.01116535, 40.70761717 ], [ -74.01113382, 40.70765006 ], [ -74.01105531, 40.70773226 ], [ -74.0109123, 40.70788207 ], [ -74.01083423, 40.70796392 ], [ -74.01080782, 40.70799157 ], [ -74.0103098, 40.70769228 ], [ -74.01051237, 40.7074741 ], [ -74.01054507, 40.70749222 ], [ -74.01076318, 40.70726348 ], [ -74.01122302, 40.70755691 ] ] ] } }, { "type": "Feature", "properties": { "height": 191.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01529616, 40.71353178 ], [ -74.01526679, 40.71357311 ], [ -74.01521289, 40.71364801 ], [ -74.01506045, 40.71386052 ], [ -74.01496352, 40.71382069 ], [ -74.01491761, 40.71388476 ], [ -74.01451122, 40.71371739 ], [ -74.01455928, 40.71365012 ], [ -74.01447385, 40.71361492 ], [ -74.01471118, 40.71328386 ], [ -74.01479571, 40.71331866 ], [ -74.01484225, 40.7132539 ], [ -74.01510105, 40.71336142 ], [ -74.01520139, 40.7134022 ], [ -74.01525125, 40.71342236 ], [ -74.01520103, 40.71349256 ], [ -74.01529616, 40.71353178 ] ] ] } }, { "type": "Feature", "properties": { "height": 228.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01240799, 40.7132524 ], [ -74.01227253, 40.7137959 ], [ -74.01173982, 40.71355847 ], [ -74.01183693, 40.71316879 ], [ -74.01187529, 40.7130149 ], [ -74.01240799, 40.7132524 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01010399, 40.70687927 ], [ -74.0100907, 40.70689262 ], [ -74.01006536, 40.70691809 ], [ -74.0099741, 40.70700968 ], [ -74.00984061, 40.7071437 ], [ -74.01007264, 40.70727417 ], [ -74.0100112, 40.70733661 ], [ -74.00999422, 40.70735412 ], [ -74.00997455, 40.70737461 ], [ -74.00995379, 40.70739416 ], [ -74.00991445, 40.70743678 ], [ -74.00959626, 40.70724618 ], [ -74.00944122, 40.70715296 ], [ -74.0093194, 40.70707982 ], [ -74.00934393, 40.70705156 ], [ -74.0093601, 40.70703331 ], [ -74.00938318, 40.70701036 ], [ -74.00941993, 40.70697318 ], [ -74.00957524, 40.70681499 ], [ -74.00955099, 40.70680062 ], [ -74.0095279, 40.70678741 ], [ -74.00963974, 40.70666906 ], [ -74.00967657, 40.70663242 ], [ -74.00968888, 40.70662016 ], [ -74.00982731, 40.70670658 ], [ -74.00995891, 40.70679027 ], [ -74.01010399, 40.70687927 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01547511, 40.70703651 ], [ -74.01524137, 40.7076423 ], [ -74.01523328, 40.70766321 ], [ -74.01509467, 40.70761431 ], [ -74.01480047, 40.7075106 ], [ -74.01486569, 40.70734696 ], [ -74.01509027, 40.7067744 ], [ -74.01525403, 40.70697195 ], [ -74.01547511, 40.70703651 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01441761, 40.70571698 ], [ -74.01423175, 40.70613558 ], [ -74.01397151, 40.706048 ], [ -74.01401975, 40.7059893 ], [ -74.01399954, 40.70594586 ], [ -74.01387692, 40.7058939 ], [ -74.01382931, 40.70590309 ], [ -74.01376894, 40.70597936 ], [ -74.01353753, 40.70589887 ], [ -74.01358631, 40.70582907 ], [ -74.01351687, 40.70579441 ], [ -74.01374073, 40.70551677 ], [ -74.01382275, 40.70555266 ], [ -74.01391905, 40.70542572 ], [ -74.0140776, 40.70546229 ], [ -74.01416357, 40.70548217 ], [ -74.01400915, 40.70567871 ], [ -74.01402523, 40.70572032 ], [ -74.01414785, 40.70577411 ], [ -74.01419779, 40.70576546 ], [ -74.014264, 40.70567748 ], [ -74.01441761, 40.70571698 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0069801, 40.7089161 ], [ -74.00676873, 40.70912427 ], [ -74.00674582, 40.70911228 ], [ -74.00672282, 40.70910016 ], [ -74.00670737, 40.70909206 ], [ -74.00669992, 40.70908818 ], [ -74.00667683, 40.70907619 ], [ -74.00665383, 40.70906428 ], [ -74.00664054, 40.7090574 ], [ -74.00663075, 40.70905229 ], [ -74.00660775, 40.70904038 ], [ -74.0064916, 40.70898011 ], [ -74.00629523, 40.70887851 ], [ -74.00637149, 40.70881457 ], [ -74.00640734, 40.70878468 ], [ -74.00642961, 40.70876629 ], [ -74.0065251, 40.70868601 ], [ -74.00647094, 40.70864726 ], [ -74.00649555, 40.70862561 ], [ -74.00652394, 40.70859878 ], [ -74.00658251, 40.70854457 ], [ -74.00659248, 40.70853531 ], [ -74.00661305, 40.70851638 ], [ -74.00663039, 40.70850031 ], [ -74.00663344, 40.70849759 ], [ -74.00665419, 40.70847886 ], [ -74.00667494, 40.7084602 ], [ -74.0066921, 40.70844488 ], [ -74.00669569, 40.70844161 ], [ -74.0067036, 40.70843446 ], [ -74.00671654, 40.70842289 ], [ -74.00686754, 40.70851822 ], [ -74.00718007, 40.70871447 ], [ -74.0069801, 40.7089161 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00467493, 40.70689609 ], [ -74.00436663, 40.7070867 ], [ -74.00419937, 40.7071917 ], [ -74.00414825, 40.70722391 ], [ -74.00392673, 40.70693859 ], [ -74.0039058, 40.70691407 ], [ -74.00412481, 40.70677556 ], [ -74.00431435, 40.70665231 ], [ -74.00455564, 40.70651032 ], [ -74.00457603, 40.70653 ], [ -74.00482037, 40.7067584 ], [ -74.00480447, 40.70676821 ], [ -74.00483609, 40.7067981 ], [ -74.00467493, 40.70689609 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00821421, 40.70653477 ], [ -74.00819597, 40.706552 ], [ -74.00817881, 40.70656848 ], [ -74.00816139, 40.70658509 ], [ -74.00814405, 40.70660191 ], [ -74.00812761, 40.70661792 ], [ -74.00810973, 40.70663487 ], [ -74.0080314, 40.70670951 ], [ -74.00804883, 40.70671911 ], [ -74.0080287, 40.70673852 ], [ -74.00801262, 40.70675418 ], [ -74.00799628, 40.70676977 ], [ -74.00797957, 40.70678591 ], [ -74.00795917, 40.70680539 ], [ -74.00793258, 40.70683038 ], [ -74.00747364, 40.7065347 ], [ -74.00722363, 40.70637392 ], [ -74.00748837, 40.70612782 ], [ -74.00774232, 40.70627048 ], [ -74.00787105, 40.70634246 ], [ -74.00821421, 40.70653477 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00604513, 40.71093741 ], [ -74.00600246, 40.71096329 ], [ -74.00601208, 40.710972 ], [ -74.00553283, 40.71124206 ], [ -74.00520773, 40.71093176 ], [ -74.00560505, 40.71050849 ], [ -74.00604513, 40.71093741 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00728463, 40.70604848 ], [ -74.00681984, 40.70650549 ], [ -74.0063697, 40.70616929 ], [ -74.00688838, 40.70581688 ], [ -74.00728463, 40.70604848 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00863255, 40.71112501 ], [ -74.00859015, 40.71117546 ], [ -74.00852107, 40.71113958 ], [ -74.00850769, 40.71115449 ], [ -74.00828742, 40.71104078 ], [ -74.0083008, 40.71102586 ], [ -74.00824161, 40.71099509 ], [ -74.00790653, 40.71081151 ], [ -74.00792702, 40.71079026 ], [ -74.00796591, 40.71075002 ], [ -74.00807425, 40.7106408 ], [ -74.00808844, 40.7106265 ], [ -74.0081021, 40.71061267 ], [ -74.00812015, 40.71059449 ], [ -74.00814342, 40.710571 ], [ -74.00816004, 40.71055432 ], [ -74.00817971, 40.71053437 ], [ -74.00857605, 40.71073551 ], [ -74.00888552, 40.71089247 ], [ -74.0086666, 40.7111423 ], [ -74.00863255, 40.71112501 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00978114, 40.70583309 ], [ -74.00951784, 40.70626238 ], [ -74.00890905, 40.70597316 ], [ -74.00904344, 40.7057515 ], [ -74.00912231, 40.7056211 ], [ -74.00978114, 40.70583309 ] ] ] } }, { "type": "Feature", "properties": { "height": 205.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00886513, 40.70622758 ], [ -74.00854658, 40.70655241 ], [ -74.00849834, 40.7065251 ], [ -74.00846493, 40.70655799 ], [ -74.0080455, 40.70631611 ], [ -74.00807218, 40.70628499 ], [ -74.00802772, 40.70625986 ], [ -74.00834635, 40.70593517 ], [ -74.00839082, 40.70596016 ], [ -74.00842271, 40.70592781 ], [ -74.00884869, 40.70616786 ], [ -74.0088168, 40.70620041 ], [ -74.00886513, 40.70622758 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00922284, 40.70819851 ], [ -74.00921448, 40.70820587 ], [ -74.00920631, 40.70820062 ], [ -74.00921475, 40.7081932 ], [ -74.00914235, 40.70814628 ], [ -74.00913399, 40.7081537 ], [ -74.00912582, 40.70814839 ], [ -74.00913408, 40.70814111 ], [ -74.00906159, 40.70809398 ], [ -74.00905323, 40.70810147 ], [ -74.00904497, 40.70809616 ], [ -74.00905341, 40.70808867 ], [ -74.0089811, 40.70804189 ], [ -74.00897274, 40.70804931 ], [ -74.00896448, 40.70804407 ], [ -74.00897301, 40.70803658 ], [ -74.00890052, 40.70798959 ], [ -74.00889208, 40.70799701 ], [ -74.00888399, 40.7079917 ], [ -74.00889234, 40.70798428 ], [ -74.00881994, 40.70793736 ], [ -74.00881159, 40.70794478 ], [ -74.0088035, 40.70793947 ], [ -74.00881177, 40.70793212 ], [ -74.00873945, 40.7078852 ], [ -74.00873101, 40.70789255 ], [ -74.00872283, 40.70788731 ], [ -74.00873119, 40.70787989 ], [ -74.00865869, 40.7078329 ], [ -74.00865043, 40.70784026 ], [ -74.00864216, 40.70783501 ], [ -74.00865061, 40.70782759 ], [ -74.0085782, 40.70778067 ], [ -74.00856985, 40.70778809 ], [ -74.00856167, 40.70778278 ], [ -74.00857003, 40.70777536 ], [ -74.00849771, 40.70772851 ], [ -74.00848927, 40.70773586 ], [ -74.00848119, 40.70773069 ], [ -74.00848954, 40.70772327 ], [ -74.00846951, 40.70771026 ], [ -74.00872068, 40.70748758 ], [ -74.00874071, 40.70750046 ], [ -74.00874897, 40.7074931 ], [ -74.00875724, 40.70749828 ], [ -74.00874879, 40.7075057 ], [ -74.00882129, 40.70755269 ], [ -74.00882964, 40.70754526 ], [ -74.00883782, 40.70755057 ], [ -74.00882937, 40.707558 ], [ -74.00890187, 40.70760498 ], [ -74.00891022, 40.70759756 ], [ -74.00891831, 40.70760287 ], [ -74.00891004, 40.70761016 ], [ -74.00898245, 40.70765721 ], [ -74.0089908, 40.70764965 ], [ -74.00899889, 40.70765497 ], [ -74.00899062, 40.70766239 ], [ -74.00906302, 40.70770938 ], [ -74.00907138, 40.70770202 ], [ -74.00907955, 40.70770726 ], [ -74.0090712, 40.70771469 ], [ -74.0091436, 40.70776161 ], [ -74.00915187, 40.70775418 ], [ -74.00916013, 40.70775949 ], [ -74.00915169, 40.70776692 ], [ -74.00922409, 40.70781377 ], [ -74.00923254, 40.70780641 ], [ -74.00924071, 40.70781159 ], [ -74.00923227, 40.70781908 ], [ -74.00930467, 40.707866 ], [ -74.00931312, 40.70785857 ], [ -74.0093212, 40.70786389 ], [ -74.00931285, 40.70787131 ], [ -74.00938543, 40.7079183 ], [ -74.00939369, 40.70791087 ], [ -74.00940187, 40.70791618 ], [ -74.00939351, 40.70792361 ], [ -74.00946592, 40.70797046 ], [ -74.00947418, 40.7079631 ], [ -74.00948245, 40.70796841 ], [ -74.009474, 40.70797577 ], [ -74.00949404, 40.70798871 ], [ -74.00924278, 40.70821152 ], [ -74.00922284, 40.70819851 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00922284, 40.70819851 ], [ -74.00921475, 40.7081932 ], [ -74.00914235, 40.70814628 ], [ -74.00913408, 40.70814111 ], [ -74.00906159, 40.70809398 ], [ -74.00905341, 40.70808867 ], [ -74.0089811, 40.70804189 ], [ -74.00897301, 40.70803658 ], [ -74.00890052, 40.70798959 ], [ -74.00889234, 40.70798428 ], [ -74.00881994, 40.70793736 ], [ -74.00881177, 40.70793212 ], [ -74.00873945, 40.7078852 ], [ -74.00873119, 40.70787989 ], [ -74.00865869, 40.7078329 ], [ -74.00865061, 40.70782759 ], [ -74.0085782, 40.70778067 ], [ -74.00857003, 40.70777536 ], [ -74.00849771, 40.70772851 ], [ -74.00848954, 40.70772327 ], [ -74.00846951, 40.70771026 ], [ -74.00872068, 40.70748758 ], [ -74.00874071, 40.70750046 ], [ -74.00874879, 40.7075057 ], [ -74.00882129, 40.70755269 ], [ -74.00882937, 40.707558 ], [ -74.00890187, 40.70760498 ], [ -74.00891004, 40.70761016 ], [ -74.00898245, 40.70765721 ], [ -74.00899062, 40.70766239 ], [ -74.00906302, 40.70770938 ], [ -74.0090712, 40.70771469 ], [ -74.0091436, 40.70776161 ], [ -74.00915169, 40.70776692 ], [ -74.00922409, 40.70781377 ], [ -74.00923227, 40.70781908 ], [ -74.00930467, 40.707866 ], [ -74.00931285, 40.70787131 ], [ -74.00938543, 40.7079183 ], [ -74.00939351, 40.70792361 ], [ -74.00946592, 40.70797046 ], [ -74.009474, 40.70797577 ], [ -74.00949404, 40.70798871 ], [ -74.00924278, 40.70821152 ], [ -74.00922284, 40.70819851 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01158738, 40.70688077 ], [ -74.01124881, 40.70739232 ], [ -74.01121665, 40.70739266 ], [ -74.01083298, 40.70713777 ], [ -74.01093179, 40.70699306 ], [ -74.01114487, 40.7066568 ], [ -74.01136469, 40.70675377 ], [ -74.01133864, 40.70679272 ], [ -74.01157912, 40.70687778 ], [ -74.01158738, 40.70688077 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00630035, 40.70958956 ], [ -74.00605232, 40.70983838 ], [ -74.00527375, 40.70944432 ], [ -74.00553597, 40.70920326 ], [ -74.00630035, 40.70958956 ] ] ] } }, { "type": "Feature", "properties": { "height": 34.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01158738, 40.70688077 ], [ -74.01124881, 40.70739232 ], [ -74.01121665, 40.70739266 ], [ -74.01083298, 40.70713777 ], [ -74.01085705, 40.70714601 ], [ -74.01095452, 40.70700212 ], [ -74.01093179, 40.70699306 ], [ -74.01114487, 40.7066568 ], [ -74.01136469, 40.70675377 ], [ -74.01133864, 40.70679272 ], [ -74.01157912, 40.70687778 ], [ -74.01158738, 40.70688077 ] ] ] } }, { "type": "Feature", "properties": { "height": 128.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00467493, 40.70689609 ], [ -74.00436663, 40.7070867 ], [ -74.00419937, 40.7071917 ], [ -74.00392673, 40.70693859 ], [ -74.00415229, 40.70679946 ], [ -74.00412481, 40.70677556 ], [ -74.00431435, 40.70665231 ], [ -74.00433887, 40.70667519 ], [ -74.00457603, 40.70653 ], [ -74.00482037, 40.7067584 ], [ -74.00480447, 40.70676821 ], [ -74.00483609, 40.7067981 ], [ -74.00467493, 40.70689609 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00859132, 40.71280368 ], [ -74.00875634, 40.71260159 ], [ -74.00887052, 40.71246159 ], [ -74.00946879, 40.71274206 ], [ -74.00918969, 40.71308422 ], [ -74.00859132, 40.71280368 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01261092, 40.7124955 ], [ -74.01258972, 40.71258327 ], [ -74.01257759, 40.71257816 ], [ -74.01235185, 40.7128873 ], [ -74.01219302, 40.71283037 ], [ -74.01218144, 40.71284597 ], [ -74.01190655, 40.71272722 ], [ -74.01165673, 40.7126769 ], [ -74.01174629, 40.71241897 ], [ -74.01176031, 40.71239976 ], [ -74.01197024, 40.71248896 ], [ -74.01199611, 40.71246077 ], [ -74.012127, 40.71248706 ], [ -74.01213481, 40.71249659 ], [ -74.01219123, 40.71250401 ], [ -74.01222941, 40.71233487 ], [ -74.01224423, 40.71233017 ], [ -74.01232705, 40.71236681 ], [ -74.01230621, 40.71245281 ], [ -74.01261092, 40.7124955 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00936549, 40.71045701 ], [ -74.00922562, 40.71062541 ], [ -74.00911414, 40.71076609 ], [ -74.00903239, 40.71072619 ], [ -74.00900517, 40.71075438 ], [ -74.00856221, 40.71054526 ], [ -74.00890268, 40.71014487 ], [ -74.00901407, 40.71020112 ], [ -74.00912681, 40.71025818 ], [ -74.00934402, 40.71036992 ], [ -74.00929713, 40.71042528 ], [ -74.00936549, 40.71045701 ] ] ] } }, { "type": "Feature", "properties": { "height": 47.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0046761, 40.71354077 ], [ -74.00439655, 40.71389722 ], [ -74.00423377, 40.71382327 ], [ -74.00422623, 40.71383287 ], [ -74.00393957, 40.71370269 ], [ -74.00394712, 40.71369302 ], [ -74.00379854, 40.71362547 ], [ -74.00407818, 40.71326908 ], [ -74.00423871, 40.71334208 ], [ -74.00425192, 40.71332519 ], [ -74.00453839, 40.71345538 ], [ -74.00452519, 40.7134722 ], [ -74.0046761, 40.71354077 ] ], [ [ -74.00436313, 40.71359279 ], [ -74.00418607, 40.7135074 ], [ -74.00411501, 40.71360089 ], [ -74.00429468, 40.71368022 ], [ -74.00436313, 40.71359279 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00623594, 40.70842731 ], [ -74.00599528, 40.7086333 ], [ -74.00581211, 40.70848438 ], [ -74.00582163, 40.70845816 ], [ -74.00586924, 40.7084284 ], [ -74.0058272, 40.70838932 ], [ -74.00569623, 40.70826797 ], [ -74.00566901, 40.7082427 ], [ -74.00565751, 40.70823188 ], [ -74.00563694, 40.70821281 ], [ -74.00560954, 40.70818748 ], [ -74.0055825, 40.70816249 ], [ -74.005973, 40.70799831 ], [ -74.00605034, 40.70800321 ], [ -74.0064023, 40.70822486 ], [ -74.00641398, 40.70827491 ], [ -74.00623594, 40.70842731 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00374706, 40.70963532 ], [ -74.00371122, 40.70961176 ], [ -74.00373907, 40.70958711 ], [ -74.0036487, 40.70952787 ], [ -74.00363019, 40.7095436 ], [ -74.00358348, 40.70951186 ], [ -74.00360127, 40.70949682 ], [ -74.0035913, 40.70949021 ], [ -74.00360064, 40.70948197 ], [ -74.00357917, 40.70946801 ], [ -74.0035701, 40.70947598 ], [ -74.00356192, 40.7094706 ], [ -74.00354387, 40.70948647 ], [ -74.00349616, 40.70945541 ], [ -74.00351431, 40.70943941 ], [ -74.00345215, 40.70939856 ], [ -74.00343391, 40.70941408 ], [ -74.00338765, 40.70938262 ], [ -74.00340508, 40.70936778 ], [ -74.0033077, 40.7093039 ], [ -74.00326835, 40.7093387 ], [ -74.00328955, 40.70935259 ], [ -74.00320098, 40.70943056 ], [ -74.00317987, 40.70941667 ], [ -74.00312741, 40.70946311 ], [ -74.00314879, 40.70947741 ], [ -74.00310791, 40.70951316 ], [ -74.00308662, 40.70949906 ], [ -74.00301107, 40.7095658 ], [ -74.00294577, 40.7095229 ], [ -74.00288549, 40.70957608 ], [ -74.00281497, 40.70952977 ], [ -74.00282692, 40.70951929 ], [ -74.0027573, 40.7094736 ], [ -74.00277733, 40.70945596 ], [ -74.00284695, 40.70950158 ], [ -74.00287714, 40.70947496 ], [ -74.00285791, 40.70946209 ], [ -74.00289888, 40.70942681 ], [ -74.00291747, 40.70943928 ], [ -74.00292475, 40.70943301 ], [ -74.00293598, 40.70944037 ], [ -74.00295322, 40.70942518 ], [ -74.00294235, 40.7094181 ], [ -74.00299814, 40.7093688 ], [ -74.00297999, 40.70935688 ], [ -74.00306857, 40.70927891 ], [ -74.00308653, 40.70929069 ], [ -74.00319226, 40.70919727 ], [ -74.00317403, 40.70918501 ], [ -74.00326638, 40.70910541 ], [ -74.00328353, 40.70911678 ], [ -74.00334067, 40.70906618 ], [ -74.00332288, 40.70905386 ], [ -74.00336438, 40.70901927 ], [ -74.00338091, 40.70903077 ], [ -74.0034428, 40.70897609 ], [ -74.00357827, 40.70906496 ], [ -74.00351665, 40.70911937 ], [ -74.00353803, 40.70913319 ], [ -74.00349769, 40.70916928 ], [ -74.00347604, 40.70915532 ], [ -74.00342277, 40.70920217 ], [ -74.0035197, 40.7092657 ], [ -74.00353767, 40.7092495 ], [ -74.0035851, 40.70928007 ], [ -74.00356668, 40.70929662 ], [ -74.00363397, 40.70934067 ], [ -74.0036522, 40.7093246 ], [ -74.00369802, 40.70935457 ], [ -74.00367978, 40.7093707 ], [ -74.00371571, 40.70939427 ], [ -74.00373467, 40.70937785 ], [ -74.00378084, 40.70940891 ], [ -74.00376234, 40.70942477 ], [ -74.00378758, 40.70944139 ], [ -74.00385594, 40.70938106 ], [ -74.00383654, 40.70936832 ], [ -74.00387723, 40.70933257 ], [ -74.00389636, 40.70934531 ], [ -74.00396967, 40.70928062 ], [ -74.00407881, 40.70935218 ], [ -74.00405438, 40.7093737 ], [ -74.00407971, 40.70939032 ], [ -74.00402653, 40.7094373 ], [ -74.00404845, 40.70945181 ], [ -74.00395943, 40.7095295 ], [ -74.00393814, 40.70951541 ], [ -74.00388208, 40.70956477 ], [ -74.00382692, 40.70952862 ], [ -74.00380294, 40.70954979 ], [ -74.00383932, 40.70957369 ], [ -74.00378794, 40.70961911 ], [ -74.003775, 40.70961067 ], [ -74.00374706, 40.70963532 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01157912, 40.70687778 ], [ -74.01137897, 40.70718142 ], [ -74.01126363, 40.70735091 ], [ -74.0111746, 40.70731727 ], [ -74.01115754, 40.70734227 ], [ -74.01085705, 40.70714601 ], [ -74.01095452, 40.70700212 ], [ -74.01093179, 40.70699306 ], [ -74.01114487, 40.7066568 ], [ -74.01136469, 40.70675377 ], [ -74.01133864, 40.70679272 ], [ -74.01157912, 40.70687778 ] ] ] } }, { "type": "Feature", "properties": { "height": 310.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01247725, 40.71025831 ], [ -74.01200618, 40.71057679 ], [ -74.0117303, 40.71045531 ], [ -74.01175905, 40.71041786 ], [ -74.01170811, 40.71040696 ], [ -74.01187484, 40.70994297 ], [ -74.01246405, 40.7101939 ], [ -74.0124291, 40.71024367 ], [ -74.01247725, 40.71025831 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00443598, 40.70766028 ], [ -74.00432324, 40.70750018 ], [ -74.00429423, 40.70745469 ], [ -74.00483304, 40.7071392 ], [ -74.00491478, 40.70725531 ], [ -74.00492592, 40.70725081 ], [ -74.00493652, 40.70726361 ], [ -74.00504495, 40.7072184 ], [ -74.00512113, 40.70718816 ], [ -74.00526019, 40.70738592 ], [ -74.00447183, 40.70770706 ], [ -74.00443598, 40.70766028 ] ] ] } }, { "type": "Feature", "properties": { "height": 198.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01528574, 40.713466 ], [ -74.01498948, 40.71387489 ], [ -74.01448238, 40.71366387 ], [ -74.01477865, 40.71325492 ], [ -74.01528574, 40.713466 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01458138, 40.70882499 ], [ -74.01439075, 40.70878039 ], [ -74.01435554, 40.70877208 ], [ -74.01432724, 40.70876548 ], [ -74.01442911, 40.70851332 ], [ -74.01436991, 40.70849936 ], [ -74.01444232, 40.70832081 ], [ -74.01455164, 40.70835248 ], [ -74.01504859, 40.70849711 ], [ -74.01488725, 40.70889649 ], [ -74.01458138, 40.70882499 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01111639, 40.71398887 ], [ -74.01075294, 40.713826 ], [ -74.01104094, 40.71345388 ], [ -74.01140475, 40.71361689 ], [ -74.01138194, 40.71364638 ], [ -74.01144787, 40.71367048 ], [ -74.01140745, 40.71411926 ], [ -74.01111639, 40.71398887 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00725094, 40.70604467 ], [ -74.00681634, 40.70646681 ], [ -74.0064191, 40.70617017 ], [ -74.00690141, 40.7058418 ], [ -74.00725094, 40.70604467 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01087798, 40.71029277 ], [ -74.01083935, 40.71034221 ], [ -74.01081375, 40.71037475 ], [ -74.01080243, 40.71038987 ], [ -74.01079354, 40.71040131 ], [ -74.01078429, 40.71041289 ], [ -74.01075779, 40.71044687 ], [ -74.01074889, 40.71045831 ], [ -74.01071215, 40.71050481 ], [ -74.01070317, 40.71051612 ], [ -74.01066679, 40.71056256 ], [ -74.01065789, 40.710574 ], [ -74.01062834, 40.71061186 ], [ -74.01065098, 40.71062262 ], [ -74.01058827, 40.71070228 ], [ -74.01055827, 40.71074049 ], [ -74.0105368, 40.71076779 ], [ -74.01050814, 40.71080429 ], [ -74.01047086, 40.7107874 ], [ -74.01041697, 40.71076296 ], [ -74.01040187, 40.71075621 ], [ -74.01034797, 40.7107317 ], [ -74.01033297, 40.71072489 ], [ -74.01027943, 40.71070058 ], [ -74.01026443, 40.71069377 ], [ -74.01021062, 40.7106694 ], [ -74.01019562, 40.71066259 ], [ -74.01014208, 40.71063828 ], [ -74.01012699, 40.71063147 ], [ -74.01014037, 40.71061451 ], [ -74.01020847, 40.71052701 ], [ -74.01029524, 40.71041636 ], [ -74.0104432, 40.71022788 ], [ -74.01051964, 40.71013016 ], [ -74.01053464, 40.71013711 ], [ -74.01058836, 40.71016128 ], [ -74.01060328, 40.71016829 ], [ -74.01065691, 40.7101924 ], [ -74.01067182, 40.71019928 ], [ -74.01072572, 40.71022359 ], [ -74.01074063, 40.71023046 ], [ -74.01079435, 40.71025477 ], [ -74.01080917, 40.71026172 ], [ -74.01086307, 40.71028596 ], [ -74.01087798, 40.71029277 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01122168, 40.70591828 ], [ -74.0110739, 40.70619728 ], [ -74.01030198, 40.70590799 ], [ -74.01039945, 40.7057575 ], [ -74.01044347, 40.70577398 ], [ -74.01050437, 40.70568 ], [ -74.01062987, 40.70572699 ], [ -74.01056995, 40.70581967 ], [ -74.01067047, 40.70585747 ], [ -74.01069895, 40.70581361 ], [ -74.01071467, 40.70581947 ], [ -74.01076857, 40.70575259 ], [ -74.01077027, 40.70571187 ], [ -74.01074593, 40.7057148 ], [ -74.01068664, 40.70542177 ], [ -74.01079812, 40.7054087 ], [ -74.0108063, 40.70544908 ], [ -74.01084124, 40.7056213 ], [ -74.01084528, 40.70564146 ], [ -74.0108575, 40.70570166 ], [ -74.0108478, 40.70578167 ], [ -74.01087241, 40.70579161 ], [ -74.01084133, 40.70586496 ], [ -74.01085831, 40.70587129 ], [ -74.01083549, 40.70590656 ], [ -74.01097428, 40.70595859 ], [ -74.01101938, 40.70588886 ], [ -74.01122168, 40.70591828 ] ] ] } }, { "type": "Feature", "properties": { "height": 168.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01075868, 40.70669752 ], [ -74.01034241, 40.70655098 ], [ -74.01036558, 40.7065155 ], [ -74.01030189, 40.70649309 ], [ -74.01041319, 40.70640967 ], [ -74.01043808, 40.70637699 ], [ -74.0103707, 40.70635077 ], [ -74.01039199, 40.70631549 ], [ -74.01052171, 40.70610051 ], [ -74.01100869, 40.70628458 ], [ -74.01075868, 40.70669752 ] ] ] } }, { "type": "Feature", "properties": { "height": 120.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00876883, 40.7124204 ], [ -74.00866983, 40.7125448 ], [ -74.00837501, 40.71240998 ], [ -74.00830224, 40.71250136 ], [ -74.00859779, 40.71263652 ], [ -74.00850014, 40.71275922 ], [ -74.00790555, 40.71248726 ], [ -74.00797121, 40.7124048 ], [ -74.0081083, 40.71223246 ], [ -74.00817495, 40.71214878 ], [ -74.00876883, 40.7124204 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01444762, 40.70779776 ], [ -74.01442192, 40.70786409 ], [ -74.01434108, 40.70807246 ], [ -74.01431503, 40.70813961 ], [ -74.01430559, 40.70814451 ], [ -74.01421675, 40.70811645 ], [ -74.01404194, 40.7080615 ], [ -74.01395552, 40.70803426 ], [ -74.01387871, 40.70801009 ], [ -74.01372205, 40.70796079 ], [ -74.01377622, 40.70783821 ], [ -74.01388231, 40.70759851 ], [ -74.01391914, 40.70761091 ], [ -74.01393423, 40.70761636 ], [ -74.01395875, 40.70762521 ], [ -74.01408964, 40.70767158 ], [ -74.01424855, 40.70772756 ], [ -74.01441025, 40.70778462 ], [ -74.01444762, 40.70779776 ] ] ] } }, { "type": "Feature", "properties": { "height": 53.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00625947, 40.7095948 ], [ -74.00604585, 40.70980917 ], [ -74.00531561, 40.70943962 ], [ -74.00554163, 40.709232 ], [ -74.00613335, 40.709531 ], [ -74.00622803, 40.70957887 ], [ -74.00625947, 40.7095948 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00992352, 40.7053472 ], [ -74.00983378, 40.70567176 ], [ -74.00976605, 40.70570758 ], [ -74.0091277, 40.70549988 ], [ -74.00911818, 40.70535701 ], [ -74.00987959, 40.7052633 ], [ -74.00992352, 40.7053472 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00822157, 40.71292536 ], [ -74.00820621, 40.71294388 ], [ -74.00817603, 40.71298222 ], [ -74.00813731, 40.71303131 ], [ -74.00809455, 40.71308572 ], [ -74.00804254, 40.71306209 ], [ -74.00788749, 40.7132618 ], [ -74.00775472, 40.71320161 ], [ -74.00743995, 40.71305787 ], [ -74.00772283, 40.71269828 ], [ -74.00822157, 40.71292536 ] ] ] } }, { "type": "Feature", "properties": { "height": 57.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01458138, 40.70882499 ], [ -74.01439075, 40.70878039 ], [ -74.01448454, 40.7085266 ], [ -74.01455164, 40.70835248 ], [ -74.01504859, 40.70849711 ], [ -74.01488725, 40.70889649 ], [ -74.01458138, 40.70882499 ] ] ] } }, { "type": "Feature", "properties": { "height": 39.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00700409, 40.70993997 ], [ -74.00676954, 40.71020867 ], [ -74.00619327, 40.7099175 ], [ -74.00618958, 40.70991069 ], [ -74.00618878, 40.709903 ], [ -74.00619102, 40.70989551 ], [ -74.0064165, 40.70966562 ], [ -74.00642431, 40.70966099 ], [ -74.0064288, 40.70965949 ], [ -74.0064386, 40.7096584 ], [ -74.00644354, 40.70965868 ], [ -74.00645279, 40.70966126 ], [ -74.00700409, 40.70993997 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01305559, 40.70738238 ], [ -74.01295444, 40.70733512 ], [ -74.01284008, 40.70728159 ], [ -74.01264362, 40.70718966 ], [ -74.01252917, 40.7071362 ], [ -74.01240314, 40.70707716 ], [ -74.01260517, 40.70682677 ], [ -74.01281798, 40.70692306 ], [ -74.013014, 40.70701179 ], [ -74.01324423, 40.70711598 ], [ -74.01305559, 40.70738238 ] ] ] } }, { "type": "Feature", "properties": { "height": 61.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00938291, 40.70771639 ], [ -74.0094078, 40.7076901 ], [ -74.00943187, 40.70766457 ], [ -74.0094458, 40.70764986 ], [ -74.0095058, 40.70758646 ], [ -74.00959213, 40.70749528 ], [ -74.00962672, 40.70745871 ], [ -74.00965214, 40.70743181 ], [ -74.01009411, 40.70769766 ], [ -74.00979237, 40.70802616 ], [ -74.0096763, 40.70795159 ], [ -74.00935552, 40.70774526 ], [ -74.00938291, 40.70771639 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00821475, 40.70577418 ], [ -74.00804047, 40.70595376 ], [ -74.0080031, 40.70599237 ], [ -74.00817414, 40.70608587 ], [ -74.00799394, 40.70629867 ], [ -74.00754694, 40.7060619 ], [ -74.00787321, 40.70572556 ], [ -74.00786548, 40.7057212 ], [ -74.0079289, 40.70565576 ], [ -74.00793663, 40.70566018 ], [ -74.00796313, 40.70563288 ], [ -74.00821475, 40.70577418 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01008378, 40.7139745 ], [ -74.00991822, 40.71418687 ], [ -74.00902799, 40.71378521 ], [ -74.0091675, 40.71360607 ], [ -74.00943762, 40.71372802 ], [ -74.00998218, 40.71397382 ], [ -74.00999341, 40.71395939 ], [ -74.01000823, 40.71394039 ], [ -74.01008378, 40.7139745 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01482706, 40.70904576 ], [ -74.01473768, 40.70926591 ], [ -74.0147234, 40.70930186 ], [ -74.01471549, 40.70930772 ], [ -74.0147101, 40.7093086 ], [ -74.01452802, 40.70923036 ], [ -74.01435428, 40.70915587 ], [ -74.01415683, 40.70907115 ], [ -74.01417857, 40.70901586 ], [ -74.01425735, 40.70881198 ], [ -74.01427972, 40.70875438 ], [ -74.01432724, 40.70876548 ], [ -74.01435554, 40.70877208 ], [ -74.01439075, 40.70878039 ], [ -74.01458138, 40.70882499 ], [ -74.01455227, 40.70889649 ], [ -74.0147499, 40.70894116 ], [ -74.01485913, 40.70896588 ], [ -74.01482706, 40.70904576 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00452725, 40.70841901 ], [ -74.00439035, 40.7084837 ], [ -74.00438891, 40.70848199 ], [ -74.00420251, 40.70825558 ], [ -74.00405932, 40.70832326 ], [ -74.00409283, 40.70836398 ], [ -74.00384705, 40.70848029 ], [ -74.00383923, 40.70847076 ], [ -74.00375057, 40.7083631 ], [ -74.00376647, 40.70835561 ], [ -74.00374679, 40.70833171 ], [ -74.00370457, 40.70828036 ], [ -74.0036814, 40.70829139 ], [ -74.003616, 40.70821186 ], [ -74.00418383, 40.70794329 ], [ -74.0042344, 40.70800471 ], [ -74.00427159, 40.70804986 ], [ -74.00425183, 40.70805932 ], [ -74.00427168, 40.70808336 ], [ -74.00420008, 40.7081172 ], [ -74.00416523, 40.70813382 ], [ -74.0042468, 40.70823297 ], [ -74.00433843, 40.70818959 ], [ -74.00452725, 40.70841901 ] ] ] } }, { "type": "Feature", "properties": { "height": 94.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01361901, 40.70582301 ], [ -74.01354634, 40.70578869 ], [ -74.01375133, 40.70553951 ], [ -74.01382589, 40.70557472 ], [ -74.01392543, 40.7054486 ], [ -74.01397043, 40.7054706 ], [ -74.0139804, 40.70546461 ], [ -74.01399684, 40.7054642 ], [ -74.01401714, 40.70547087 ], [ -74.01403134, 40.70548129 ], [ -74.01403915, 40.70549212 ], [ -74.01403655, 40.70550301 ], [ -74.01408757, 40.70552801 ], [ -74.01405038, 40.7055769 ], [ -74.01402298, 40.70556512 ], [ -74.01390953, 40.70570002 ], [ -74.01413653, 40.70580306 ], [ -74.01421873, 40.7057861 ], [ -74.01425978, 40.70573189 ], [ -74.01427352, 40.70571861 ], [ -74.01428915, 40.70571337 ], [ -74.01431161, 40.70571262 ], [ -74.01433119, 40.70571711 ], [ -74.01434593, 40.70573421 ], [ -74.01434979, 40.70575198 ], [ -74.01419914, 40.70609309 ], [ -74.01405918, 40.70602928 ], [ -74.01411398, 40.70597078 ], [ -74.01384592, 40.70584991 ], [ -74.01376283, 40.70596111 ], [ -74.01356808, 40.70589506 ], [ -74.01361901, 40.70582301 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00597938, 40.71261521 ], [ -74.00600435, 40.71258681 ], [ -74.00617584, 40.7126737 ], [ -74.00615105, 40.71270209 ], [ -74.00627447, 40.71276467 ], [ -74.0063193, 40.71271346 ], [ -74.00643824, 40.71277365 ], [ -74.00622588, 40.7130164 ], [ -74.00598998, 40.71289697 ], [ -74.0059677, 40.71292237 ], [ -74.00578822, 40.71283146 ], [ -74.00581049, 40.712806 ], [ -74.00557154, 40.712685 ], [ -74.00578408, 40.71244198 ], [ -74.00590069, 40.71250108 ], [ -74.00585568, 40.71255249 ], [ -74.00597938, 40.71261521 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01262053, 40.70796317 ], [ -74.01255576, 40.70804257 ], [ -74.01253474, 40.7080327 ], [ -74.01240269, 40.70819449 ], [ -74.01243647, 40.70821036 ], [ -74.01240134, 40.70825346 ], [ -74.01244644, 40.70827471 ], [ -74.01241042, 40.7083189 ], [ -74.01238517, 40.70830706 ], [ -74.01240278, 40.70828547 ], [ -74.0123567, 40.70826388 ], [ -74.01233235, 40.70829378 ], [ -74.01207777, 40.70817447 ], [ -74.0121146, 40.70812939 ], [ -74.0119777, 40.70806518 ], [ -74.01194284, 40.70810801 ], [ -74.0118584, 40.70806852 ], [ -74.01192892, 40.70798197 ], [ -74.01179795, 40.70792061 ], [ -74.01188841, 40.70780961 ], [ -74.01202279, 40.7078726 ], [ -74.01209565, 40.7077834 ], [ -74.01217614, 40.70782112 ], [ -74.01214038, 40.70786477 ], [ -74.01229337, 40.70793648 ], [ -74.0123046, 40.70792272 ], [ -74.01236802, 40.70784489 ], [ -74.01262053, 40.70796317 ] ] ] } }, { "type": "Feature", "properties": { "height": 120.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0100253, 40.71098991 ], [ -74.00988148, 40.71092406 ], [ -74.00975814, 40.71107898 ], [ -74.00937519, 40.71090227 ], [ -74.00934905, 40.71089036 ], [ -74.00931473, 40.71087599 ], [ -74.00955584, 40.71057338 ], [ -74.01014298, 40.71084222 ], [ -74.0100253, 40.71098991 ] ] ] } }, { "type": "Feature", "properties": { "height": 82.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01321118, 40.70555988 ], [ -74.01312314, 40.70577765 ], [ -74.01312943, 40.7057799 ], [ -74.01307849, 40.70585617 ], [ -74.01242389, 40.70560891 ], [ -74.01254498, 40.7053566 ], [ -74.01258074, 40.70536716 ], [ -74.01265341, 40.70539079 ], [ -74.01277325, 40.70542647 ], [ -74.01299019, 40.705493 ], [ -74.01312224, 40.7055327 ], [ -74.01321118, 40.70555988 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01297294, 40.70597977 ], [ -74.01276112, 40.70625557 ], [ -74.01272438, 40.70623916 ], [ -74.01264425, 40.70620327 ], [ -74.01258945, 40.70617882 ], [ -74.01242021, 40.7061031 ], [ -74.0123637, 40.70607776 ], [ -74.01232319, 40.70605972 ], [ -74.01227989, 40.70604031 ], [ -74.01222779, 40.70601702 ], [ -74.01237188, 40.70571711 ], [ -74.01297294, 40.70597977 ] ] ] } }, { "type": "Feature", "properties": { "height": 210.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01042927, 40.70869786 ], [ -74.01024323, 40.70888662 ], [ -74.00960749, 40.70857597 ], [ -74.0098566, 40.70832347 ], [ -74.01042927, 40.70869786 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00623657, 40.7095978 ], [ -74.00604208, 40.70979289 ], [ -74.00533744, 40.70943846 ], [ -74.00554594, 40.709245 ], [ -74.00623657, 40.7095978 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00593752, 40.71340799 ], [ -74.00573342, 40.71366238 ], [ -74.00514233, 40.71338981 ], [ -74.00534642, 40.71313549 ], [ -74.00593752, 40.71340799 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00754011, 40.70930458 ], [ -74.00729047, 40.70956001 ], [ -74.00727071, 40.70954891 ], [ -74.00725454, 40.70953978 ], [ -74.00722669, 40.70952378 ], [ -74.00720809, 40.70951309 ], [ -74.00716345, 40.70948769 ], [ -74.007102, 40.70945249 ], [ -74.00707263, 40.70943628 ], [ -74.00702987, 40.70948006 ], [ -74.0069898, 40.70945739 ], [ -74.00697112, 40.70947659 ], [ -74.00691479, 40.70944466 ], [ -74.00686404, 40.70941592 ], [ -74.0068626, 40.70941517 ], [ -74.00681813, 40.7093895 ], [ -74.00680439, 40.7093818 ], [ -74.00677546, 40.70936567 ], [ -74.00675777, 40.70935566 ], [ -74.00673783, 40.70934456 ], [ -74.00701451, 40.70906162 ], [ -74.00703571, 40.70907381 ], [ -74.00705412, 40.7090843 ], [ -74.00708125, 40.70909948 ], [ -74.00709527, 40.70910752 ], [ -74.00713991, 40.7091323 ], [ -74.00722741, 40.70918208 ], [ -74.0072778, 40.70921048 ], [ -74.00731203, 40.70917548 ], [ -74.00739827, 40.7092243 ], [ -74.00741201, 40.709232 ], [ -74.00745809, 40.70925842 ], [ -74.0074784, 40.70926979 ], [ -74.00750678, 40.70928579 ], [ -74.00752214, 40.70929437 ], [ -74.00754011, 40.70930458 ] ] ] } }, { "type": "Feature", "properties": { "height": 225.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01523283, 40.7134816 ], [ -74.01497619, 40.71383716 ], [ -74.01453412, 40.713654 ], [ -74.01479077, 40.7132983 ], [ -74.01523283, 40.7134816 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01122168, 40.70591828 ], [ -74.0110739, 40.70619728 ], [ -74.01030198, 40.70590799 ], [ -74.01039945, 40.7057575 ], [ -74.01044347, 40.70577398 ], [ -74.01050437, 40.70568 ], [ -74.01062987, 40.70572699 ], [ -74.01056995, 40.70581967 ], [ -74.01067047, 40.70585747 ], [ -74.01069895, 40.70581361 ], [ -74.01071467, 40.70581947 ], [ -74.01076857, 40.70575259 ], [ -74.0108478, 40.70578167 ], [ -74.01087241, 40.70579161 ], [ -74.01084133, 40.70586496 ], [ -74.01085831, 40.70587129 ], [ -74.01083549, 40.70590656 ], [ -74.01097428, 40.70595859 ], [ -74.01101938, 40.70588886 ], [ -74.01122168, 40.70591828 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01468495, 40.70939447 ], [ -74.0145661, 40.70970137 ], [ -74.01455389, 40.70969606 ], [ -74.01441375, 40.70963648 ], [ -74.01400079, 40.70945896 ], [ -74.01412117, 40.70915546 ], [ -74.01464471, 40.70937581 ], [ -74.0146395, 40.70939352 ], [ -74.01468495, 40.70939447 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.010202, 40.70598066 ], [ -74.01017882, 40.7060192 ], [ -74.01016059, 40.7060493 ], [ -74.0101313, 40.70609778 ], [ -74.01011405, 40.70612652 ], [ -74.0101022, 40.706146 ], [ -74.01005719, 40.7062205 ], [ -74.01016921, 40.70625959 ], [ -74.01003743, 40.706403 ], [ -74.01001254, 40.7064301 ], [ -74.01000365, 40.70643977 ], [ -74.00996619, 40.70648049 ], [ -74.00994113, 40.7065078 ], [ -74.00992783, 40.70652231 ], [ -74.00963462, 40.7063364 ], [ -74.00979928, 40.70606367 ], [ -74.00991364, 40.70587422 ], [ -74.010202, 40.70598066 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00624384, 40.70676147 ], [ -74.00605789, 40.70661478 ], [ -74.00583673, 40.70644011 ], [ -74.00605214, 40.70629166 ], [ -74.00665365, 40.70674396 ], [ -74.00645468, 40.70692796 ], [ -74.00624384, 40.70676147 ] ] ] } }, { "type": "Feature", "properties": { "height": 129.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01305559, 40.70738238 ], [ -74.01295444, 40.70733512 ], [ -74.01284008, 40.70728159 ], [ -74.01264362, 40.70718966 ], [ -74.01252917, 40.7071362 ], [ -74.01240314, 40.70707716 ], [ -74.01260517, 40.70682677 ], [ -74.01281798, 40.70692306 ], [ -74.01273803, 40.70702766 ], [ -74.01293189, 40.70711687 ], [ -74.013014, 40.70701179 ], [ -74.01324423, 40.70711598 ], [ -74.01305559, 40.70738238 ] ] ] } }, { "type": "Feature", "properties": { "height": 400.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01350151, 40.71312807 ], [ -74.01302199, 40.71325227 ], [ -74.01287314, 40.71288049 ], [ -74.0133567, 40.71275772 ], [ -74.01350151, 40.71312807 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00945604, 40.70559849 ], [ -74.00913588, 40.70549498 ], [ -74.00912734, 40.70538806 ], [ -74.00952772, 40.70533746 ], [ -74.00987843, 40.70529347 ], [ -74.00991014, 40.70535428 ], [ -74.00981914, 40.70567026 ], [ -74.00976784, 40.70569982 ], [ -74.00945604, 40.70559849 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00793519, 40.70726082 ], [ -74.00785263, 40.70733532 ], [ -74.00782928, 40.70735636 ], [ -74.00744489, 40.707101 ], [ -74.00754334, 40.70699286 ], [ -74.00760919, 40.7069204 ], [ -74.0077107, 40.70680879 ], [ -74.0081913, 40.7071108 ], [ -74.00810084, 40.70721418 ], [ -74.00808736, 40.70722957 ], [ -74.00794211, 40.70713832 ], [ -74.00787464, 40.70720049 ], [ -74.0079484, 40.70724877 ], [ -74.00793519, 40.70726082 ] ] ] } }, { "type": "Feature", "properties": { "height": 113.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00876299, 40.70908491 ], [ -74.00868349, 40.7091637 ], [ -74.00868717, 40.70916812 ], [ -74.00869022, 40.70917432 ], [ -74.0086913, 40.70918099 ], [ -74.00869013, 40.7091876 ], [ -74.00868681, 40.70919386 ], [ -74.00868178, 40.70919917 ], [ -74.00867513, 40.7092036 ], [ -74.00866714, 40.7092066 ], [ -74.00865851, 40.70920809 ], [ -74.00864971, 40.70920789 ], [ -74.00864091, 40.70920612 ], [ -74.00856931, 40.70927707 ], [ -74.00857299, 40.70928157 ], [ -74.00857587, 40.7092879 ], [ -74.00857677, 40.7092943 ], [ -74.00857551, 40.70930077 ], [ -74.00857228, 40.7093069 ], [ -74.00856698, 40.70931248 ], [ -74.00856069, 40.70931657 ], [ -74.0085526, 40.7093197 ], [ -74.00854425, 40.70932106 ], [ -74.0085358, 40.709321 ], [ -74.00852691, 40.70931916 ], [ -74.00845208, 40.70939338 ], [ -74.00845702, 40.70939978 ], [ -74.00845855, 40.70940346 ], [ -74.00845963, 40.70941081 ], [ -74.0084581, 40.70941796 ], [ -74.00845424, 40.7094247 ], [ -74.00844804, 40.70943029 ], [ -74.00844418, 40.70943267 ], [ -74.00843555, 40.70943608 ], [ -74.00842585, 40.70943757 ], [ -74.00841543, 40.70943696 ], [ -74.00840573, 40.70943417 ], [ -74.00840133, 40.70943199 ], [ -74.00839414, 40.70942641 ], [ -74.0083892, 40.70941926 ], [ -74.00838722, 40.70941129 ], [ -74.0083883, 40.70940319 ], [ -74.00822867, 40.7092892 ], [ -74.00822184, 40.70929171 ], [ -74.00821322, 40.70929321 ], [ -74.00820441, 40.70929301 ], [ -74.00819561, 40.7092911 ], [ -74.00818842, 40.70928811 ], [ -74.00818232, 40.70928388 ], [ -74.00817774, 40.70927871 ], [ -74.00817468, 40.70927292 ], [ -74.00817342, 40.70926679 ], [ -74.00817414, 40.70926046 ], [ -74.00817765, 40.70925297 ], [ -74.00828095, 40.70915069 ], [ -74.00834356, 40.70908852 ], [ -74.00829721, 40.70904058 ], [ -74.00828742, 40.7090305 ], [ -74.00833485, 40.70898358 ], [ -74.00834931, 40.70896942 ], [ -74.00841004, 40.70891011 ], [ -74.00848532, 40.70883636 ], [ -74.00849107, 40.7088318 ], [ -74.00849798, 40.7088284 ], [ -74.00850328, 40.70882669 ], [ -74.00851379, 40.7088254 ], [ -74.00852224, 40.70882608 ], [ -74.00853014, 40.70882819 ], [ -74.00853419, 40.70882989 ], [ -74.0085385, 40.70883241 ], [ -74.0085429, 40.70883602 ], [ -74.00854703, 40.70884099 ], [ -74.00854955, 40.7088461 ], [ -74.00855063, 40.70885332 ], [ -74.00854937, 40.70885986 ], [ -74.00854631, 40.70886598 ], [ -74.00864558, 40.70891386 ], [ -74.00865609, 40.70891086 ], [ -74.00866435, 40.70891011 ], [ -74.00867253, 40.70891079 ], [ -74.00868034, 40.70891277 ], [ -74.00868717, 40.7089161 ], [ -74.0086931, 40.7089206 ], [ -74.00869678, 40.70892489 ], [ -74.00869993, 40.70893122 ], [ -74.00870118, 40.70893762 ], [ -74.00869975, 40.7089445 ], [ -74.00869651, 40.70895069 ], [ -74.00869481, 40.7089526 ], [ -74.00876011, 40.70903091 ], [ -74.00876398, 40.7090303 ], [ -74.00877278, 40.70903037 ], [ -74.00878122, 40.70903207 ], [ -74.00878895, 40.7090352 ], [ -74.00879667, 40.70904072 ], [ -74.00880018, 40.70904521 ], [ -74.00880323, 40.70905141 ], [ -74.00880413, 40.70905801 ], [ -74.00880287, 40.70906462 ], [ -74.00879973, 40.70907081 ], [ -74.00879461, 40.70907606 ], [ -74.00878805, 40.70908048 ], [ -74.00878024, 40.70908348 ], [ -74.0087717, 40.70908498 ], [ -74.00876299, 40.70908491 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01577497, 40.71305732 ], [ -74.01574218, 40.71310526 ], [ -74.01566142, 40.71306672 ], [ -74.01567984, 40.7130435 ], [ -74.01553188, 40.71297616 ], [ -74.01551589, 40.71299638 ], [ -74.01537126, 40.71293047 ], [ -74.01534593, 40.71296261 ], [ -74.01521253, 40.7129018 ], [ -74.01518918, 40.71293108 ], [ -74.01516384, 40.71292407 ], [ -74.01512845, 40.71292237 ], [ -74.01509027, 40.71293067 ], [ -74.01505631, 40.71295069 ], [ -74.01503673, 40.71297561 ], [ -74.01502963, 40.71301088 ], [ -74.01503449, 40.71303029 ], [ -74.01504724, 40.71305072 ], [ -74.01507635, 40.7130736 ], [ -74.01505802, 40.71309661 ], [ -74.01519151, 40.71315728 ], [ -74.01517489, 40.71317818 ], [ -74.01531952, 40.7132441 ], [ -74.01530254, 40.71326541 ], [ -74.01545041, 40.71333282 ], [ -74.01546729, 40.71331137 ], [ -74.01555802, 40.71335032 ], [ -74.01549847, 40.71343107 ], [ -74.01543981, 40.71340956 ], [ -74.01515091, 40.7132889 ], [ -74.01516663, 40.71326731 ], [ -74.01502739, 40.71320869 ], [ -74.01504473, 40.71318479 ], [ -74.01492633, 40.71314366 ], [ -74.01475861, 40.71308558 ], [ -74.01487198, 40.71278176 ], [ -74.0149699, 40.71281887 ], [ -74.01505703, 40.71278639 ], [ -74.01507123, 40.71274846 ], [ -74.01577497, 40.71305732 ] ] ] } }, { "type": "Feature", "properties": { "height": 66.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01265763, 40.70892877 ], [ -74.01260284, 40.708905 ], [ -74.01280379, 40.70859537 ], [ -74.01278178, 40.70858638 ], [ -74.01284538, 40.70849037 ], [ -74.01318674, 40.7086205 ], [ -74.01299513, 40.70907517 ], [ -74.01265763, 40.70892877 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00621968, 40.70960216 ], [ -74.00604055, 40.70978526 ], [ -74.00535002, 40.7094358 ], [ -74.00554621, 40.70925549 ], [ -74.00621968, 40.70960216 ] ] ] } }, { "type": "Feature", "properties": { "height": 33.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0065251, 40.70868601 ], [ -74.00640734, 40.70878468 ], [ -74.00637149, 40.70881457 ], [ -74.00633682, 40.70879067 ], [ -74.00627385, 40.70884351 ], [ -74.00618599, 40.70878277 ], [ -74.0061391, 40.70882206 ], [ -74.00623189, 40.70888628 ], [ -74.00623423, 40.7088843 ], [ -74.00626783, 40.70890759 ], [ -74.00611044, 40.70905141 ], [ -74.00598198, 40.70896261 ], [ -74.00594201, 40.70899509 ], [ -74.00607613, 40.70908266 ], [ -74.00593491, 40.70921157 ], [ -74.00562409, 40.70905079 ], [ -74.0058458, 40.70886517 ], [ -74.00584167, 40.70886238 ], [ -74.005905, 40.7088094 ], [ -74.00592853, 40.7088256 ], [ -74.00611107, 40.70867266 ], [ -74.00608745, 40.70865632 ], [ -74.00614808, 40.70860538 ], [ -74.0061594, 40.70861321 ], [ -74.00617054, 40.70862091 ], [ -74.00637401, 40.70876159 ], [ -74.00646555, 40.70868751 ], [ -74.00644255, 40.70867048 ], [ -74.00647094, 40.70864726 ], [ -74.0065251, 40.70868601 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00539987, 40.70624937 ], [ -74.00540805, 40.70625836 ], [ -74.00541569, 40.70627171 ], [ -74.00542063, 40.7062858 ], [ -74.00542197, 40.70629302 ], [ -74.0054226, 40.70630759 ], [ -74.00542179, 40.70631481 ], [ -74.00541802, 40.70632911 ], [ -74.00541128, 40.70634266 ], [ -74.00540203, 40.70635547 ], [ -74.00539017, 40.70636691 ], [ -74.00538344, 40.70637208 ], [ -74.00541533, 40.70639857 ], [ -74.00504881, 40.70665387 ], [ -74.00486879, 40.7065044 ], [ -74.00490167, 40.70648138 ], [ -74.0048917, 40.70647001 ], [ -74.00488433, 40.70645741 ], [ -74.00487975, 40.70644406 ], [ -74.00487849, 40.70643718 ], [ -74.00487831, 40.7064235 ], [ -74.00488101, 40.70640988 ], [ -74.00488343, 40.7064032 ], [ -74.00489044, 40.70639047 ], [ -74.00489817, 40.70637726 ], [ -74.00490769, 40.70636718 ], [ -74.00492098, 40.70635506 ], [ -74.00489188, 40.7063315 ], [ -74.0052539, 40.70607919 ], [ -74.00543239, 40.70622731 ], [ -74.00539987, 40.70624937 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01158738, 40.70688077 ], [ -74.01157912, 40.70687778 ], [ -74.01157004, 40.70687458 ], [ -74.01155262, 40.70686851 ], [ -74.01153519, 40.70686232 ], [ -74.01151785, 40.70685612 ], [ -74.01150042, 40.70684999 ], [ -74.011483, 40.7068438 ], [ -74.01146557, 40.7068376 ], [ -74.01143494, 40.70682677 ], [ -74.01133864, 40.70679272 ], [ -74.01136469, 40.70675377 ], [ -74.01126659, 40.7067106 ], [ -74.01121889, 40.70668949 ], [ -74.01116499, 40.70666572 ], [ -74.01114487, 40.7066568 ], [ -74.01113202, 40.70665196 ], [ -74.01132058, 40.70635976 ], [ -74.01163849, 40.70649697 ], [ -74.01178339, 40.70655949 ], [ -74.01158738, 40.70688077 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.005776, 40.71013609 ], [ -74.00563981, 40.71004457 ], [ -74.00560442, 40.71002087 ], [ -74.00567665, 40.7099619 ], [ -74.00571824, 40.70992799 ], [ -74.00558133, 40.70984941 ], [ -74.00556292, 40.70986466 ], [ -74.00554271, 40.70988148 ], [ -74.00550857, 40.70985772 ], [ -74.00553498, 40.70983579 ], [ -74.00550552, 40.70981516 ], [ -74.00545458, 40.70985751 ], [ -74.00529154, 40.70999288 ], [ -74.00513361, 40.7098426 ], [ -74.00514305, 40.70983491 ], [ -74.00520871, 40.70978097 ], [ -74.00532217, 40.70968796 ], [ -74.00537921, 40.70964118 ], [ -74.0054182, 40.70960917 ], [ -74.00600732, 40.70990259 ], [ -74.005776, 40.71013609 ] ] ] } }, { "type": "Feature", "properties": { "height": 103.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00591712, 40.70704257 ], [ -74.00562975, 40.70724598 ], [ -74.00521329, 40.70690522 ], [ -74.00550067, 40.70670188 ], [ -74.00591712, 40.70704257 ] ] ] } }, { "type": "Feature", "properties": { "height": 59.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01138194, 40.71364638 ], [ -74.0113434, 40.7136952 ], [ -74.01122913, 40.71384302 ], [ -74.01118017, 40.71390628 ], [ -74.01115044, 40.71394488 ], [ -74.01111639, 40.71398887 ], [ -74.01075294, 40.713826 ], [ -74.01104094, 40.71345388 ], [ -74.01140475, 40.71361689 ], [ -74.01138194, 40.71364638 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01184735, 40.70737727 ], [ -74.01169284, 40.70756596 ], [ -74.01165664, 40.70761016 ], [ -74.01160858, 40.7076184 ], [ -74.01151938, 40.70758619 ], [ -74.01145677, 40.7075565 ], [ -74.01136424, 40.7075025 ], [ -74.01136172, 40.70747036 ], [ -74.0113929, 40.70742378 ], [ -74.0115254, 40.70722609 ], [ -74.01163715, 40.70705939 ], [ -74.01168305, 40.70708091 ], [ -74.0116888, 40.7070837 ], [ -74.01170704, 40.70709221 ], [ -74.01172204, 40.70709916 ], [ -74.0117559, 40.70711509 ], [ -74.01178214, 40.70712742 ], [ -74.01186685, 40.70716739 ], [ -74.01187493, 40.70717107 ], [ -74.01193233, 40.70719688 ], [ -74.01194545, 40.70720328 ], [ -74.01195883, 40.70720968 ], [ -74.01197725, 40.70721847 ], [ -74.01184735, 40.70737727 ] ] ] } }, { "type": "Feature", "properties": { "height": 92.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00793519, 40.70726082 ], [ -74.00785263, 40.70733532 ], [ -74.00782928, 40.70735636 ], [ -74.00744489, 40.707101 ], [ -74.00754334, 40.70699286 ], [ -74.00764908, 40.70706232 ], [ -74.00772498, 40.70699667 ], [ -74.00760919, 40.7069204 ], [ -74.0077107, 40.70680879 ], [ -74.0081913, 40.7071108 ], [ -74.00810084, 40.70721418 ], [ -74.00808736, 40.70722957 ], [ -74.00794211, 40.70713832 ], [ -74.00787464, 40.70720049 ], [ -74.0079484, 40.70724877 ], [ -74.00793519, 40.70726082 ] ] ] } }, { "type": "Feature", "properties": { "height": 103.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00622507, 40.70693477 ], [ -74.00598935, 40.70710168 ], [ -74.00591712, 40.70704257 ], [ -74.00550067, 40.70670188 ], [ -74.00574779, 40.70652687 ], [ -74.00613919, 40.70686136 ], [ -74.00622507, 40.70693477 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00540589, 40.71388551 ], [ -74.00513182, 40.71421786 ], [ -74.00512292, 40.71422861 ], [ -74.00497165, 40.71415691 ], [ -74.00486133, 40.71410462 ], [ -74.00474851, 40.71405117 ], [ -74.00503148, 40.71370806 ], [ -74.00512903, 40.71375437 ], [ -74.00524752, 40.71381047 ], [ -74.00540589, 40.71388551 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01261299, 40.7064429 ], [ -74.01257409, 40.7064888 ], [ -74.01254355, 40.7065251 ], [ -74.01240584, 40.70668772 ], [ -74.01237089, 40.70672898 ], [ -74.01195955, 40.706546 ], [ -74.01198524, 40.70649711 ], [ -74.01208172, 40.70631277 ], [ -74.01210373, 40.70627082 ], [ -74.0121296, 40.70622152 ], [ -74.01214083, 40.70622656 ], [ -74.01218027, 40.70624481 ], [ -74.0123054, 40.70630242 ], [ -74.0124388, 40.70636269 ], [ -74.01257508, 40.70642547 ], [ -74.01261299, 40.7064429 ] ] ] } }, { "type": "Feature", "properties": { "height": 86.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0121058, 40.70879857 ], [ -74.01198965, 40.708975 ], [ -74.01177037, 40.70887729 ], [ -74.0111861, 40.70861689 ], [ -74.01117901, 40.70858931 ], [ -74.01128752, 40.70844842 ], [ -74.01197402, 40.70875438 ], [ -74.01198237, 40.70874362 ], [ -74.0121058, 40.70879857 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01246827, 40.70799838 ], [ -74.01245399, 40.70801826 ], [ -74.01241805, 40.70806232 ], [ -74.01233199, 40.70816719 ], [ -74.01229489, 40.7082124 ], [ -74.01234762, 40.70823712 ], [ -74.01231079, 40.70828186 ], [ -74.0120837, 40.70817488 ], [ -74.01212044, 40.70813021 ], [ -74.0119715, 40.70806 ], [ -74.01194123, 40.70809712 ], [ -74.01194338, 40.70809807 ], [ -74.01194455, 40.70810202 ], [ -74.01194248, 40.7081044 ], [ -74.01193727, 40.70810536 ], [ -74.01193269, 40.70810318 ], [ -74.01193161, 40.70809929 ], [ -74.01193233, 40.70809848 ], [ -74.01187709, 40.70807246 ], [ -74.01187619, 40.70807349 ], [ -74.01187107, 40.7080741 ], [ -74.01186658, 40.70807199 ], [ -74.01186541, 40.70806831 ], [ -74.0118673, 40.708066 ], [ -74.0118726, 40.70806497 ], [ -74.01187475, 40.708066 ], [ -74.01190529, 40.70802882 ], [ -74.01194141, 40.70798469 ], [ -74.01193377, 40.70798122 ], [ -74.0118019, 40.70791959 ], [ -74.01188688, 40.70781499 ], [ -74.01201884, 40.70787662 ], [ -74.01202702, 40.70788037 ], [ -74.01206142, 40.70783842 ], [ -74.01205945, 40.7078374 ], [ -74.01205828, 40.70783352 ], [ -74.01206025, 40.70783106 ], [ -74.01206555, 40.70783018 ], [ -74.01206744, 40.70783106 ], [ -74.01209529, 40.70779708 ], [ -74.01209322, 40.70779606 ], [ -74.01209214, 40.70779211 ], [ -74.01209412, 40.7077898 ], [ -74.01209942, 40.70778878 ], [ -74.01210391, 40.70779095 ], [ -74.01210499, 40.7077949 ], [ -74.01210391, 40.70779606 ], [ -74.01216464, 40.70782466 ], [ -74.01213068, 40.707866 ], [ -74.01213868, 40.70786981 ], [ -74.01229642, 40.7079441 ], [ -74.01231043, 40.70792402 ], [ -74.01237089, 40.70785027 ], [ -74.0126085, 40.70796222 ], [ -74.01254813, 40.7080359 ], [ -74.01246827, 40.70799838 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00812653, 40.70893149 ], [ -74.00794992, 40.7090941 ], [ -74.00739225, 40.70869398 ], [ -74.0075402, 40.70854818 ], [ -74.00756832, 40.70856466 ], [ -74.00761548, 40.70851808 ], [ -74.00782173, 40.70863929 ], [ -74.00777852, 40.70868179 ], [ -74.00801487, 40.70882016 ], [ -74.0079855, 40.70884896 ], [ -74.00812653, 40.70893149 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01329068, 40.7083202 ], [ -74.01315225, 40.70828159 ], [ -74.01299324, 40.7082378 ], [ -74.01285778, 40.70819946 ], [ -74.01284107, 40.70819477 ], [ -74.0130678, 40.70785401 ], [ -74.01345758, 40.70797679 ], [ -74.0133064, 40.70832456 ], [ -74.01329068, 40.7083202 ] ] ] } }, { "type": "Feature", "properties": { "height": 89.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00687949, 40.70836106 ], [ -74.00688704, 40.7083505 ], [ -74.00689997, 40.70833211 ], [ -74.00691255, 40.70831216 ], [ -74.00701576, 40.70816828 ], [ -74.00704352, 40.70812926 ], [ -74.0070561, 40.70811148 ], [ -74.00707092, 40.70809071 ], [ -74.00708395, 40.7080724 ], [ -74.00745495, 40.70830386 ], [ -74.0074536, 40.7084346 ], [ -74.00727008, 40.70860491 ], [ -74.00687949, 40.70836106 ] ] ] } }, { "type": "Feature", "properties": { "height": 89.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01305559, 40.70738238 ], [ -74.01300573, 40.70745279 ], [ -74.01296872, 40.70750522 ], [ -74.01292138, 40.70757196 ], [ -74.01291213, 40.7075678 ], [ -74.01272294, 40.70748241 ], [ -74.01260876, 40.70743086 ], [ -74.01225384, 40.70727056 ], [ -74.01224881, 40.70726838 ], [ -74.01230091, 40.70720376 ], [ -74.01234322, 40.70715139 ], [ -74.01240314, 40.70707716 ], [ -74.01252917, 40.7071362 ], [ -74.01264362, 40.70718966 ], [ -74.01284008, 40.70728159 ], [ -74.01295444, 40.70733512 ], [ -74.01305559, 40.70738238 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01223102, 40.70682868 ], [ -74.0121597, 40.70691659 ], [ -74.01193233, 40.70719688 ], [ -74.01187493, 40.70717107 ], [ -74.01186685, 40.70716739 ], [ -74.01178214, 40.70712742 ], [ -74.0117559, 40.70711509 ], [ -74.01172204, 40.70709916 ], [ -74.01170704, 40.70709221 ], [ -74.0116888, 40.7070837 ], [ -74.01168305, 40.70708091 ], [ -74.01163715, 40.70705939 ], [ -74.01189353, 40.70665721 ], [ -74.01194734, 40.70668091 ], [ -74.01224647, 40.70680961 ], [ -74.01223102, 40.70682868 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01055234, 40.70722991 ], [ -74.01022518, 40.70756637 ], [ -74.01018798, 40.70760471 ], [ -74.00991642, 40.70745299 ], [ -74.00995361, 40.70741472 ], [ -74.0102806, 40.70707819 ], [ -74.010308, 40.70705006 ], [ -74.01057965, 40.70720178 ], [ -74.01055234, 40.70722991 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0139742, 40.71010136 ], [ -74.01401508, 40.70999942 ], [ -74.01402083, 40.70998526 ], [ -74.01421378, 40.7100302 ], [ -74.01425277, 40.70993296 ], [ -74.01411183, 40.70990021 ], [ -74.01418773, 40.70971131 ], [ -74.0142207, 40.70969947 ], [ -74.01451167, 40.7098298 ], [ -74.01452694, 40.70985887 ], [ -74.01436767, 40.71025927 ], [ -74.01433191, 40.71027112 ], [ -74.01397789, 40.71011668 ], [ -74.01397295, 40.71010442 ], [ -74.0139742, 40.71010136 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00938291, 40.70771639 ], [ -74.0094078, 40.7076901 ], [ -74.00943187, 40.70766457 ], [ -74.0094458, 40.70764986 ], [ -74.0095058, 40.70758646 ], [ -74.00959213, 40.70749528 ], [ -74.00962672, 40.70745871 ], [ -74.0100306, 40.70770747 ], [ -74.00978078, 40.70797352 ], [ -74.00938291, 40.70771639 ] ] ] } }, { "type": "Feature", "properties": { "height": 136.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00644704, 40.7055897 ], [ -74.00592269, 40.70595246 ], [ -74.00571644, 40.70577977 ], [ -74.00601064, 40.70557629 ], [ -74.0062407, 40.70541707 ], [ -74.00644704, 40.7055897 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00918358, 40.71176229 ], [ -74.00914306, 40.71181097 ], [ -74.0090491, 40.71192401 ], [ -74.00899098, 40.71199366 ], [ -74.00872193, 40.71186429 ], [ -74.00862141, 40.71181588 ], [ -74.00855395, 40.7117834 ], [ -74.00850607, 40.71176038 ], [ -74.00870729, 40.71151852 ], [ -74.00919211, 40.71175207 ], [ -74.00918358, 40.71176229 ] ] ] } }, { "type": "Feature", "properties": { "height": 42.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00855988, 40.71376921 ], [ -74.00822867, 40.71419191 ], [ -74.00783952, 40.71401529 ], [ -74.0079731, 40.71384472 ], [ -74.00812833, 40.7139152 ], [ -74.00813884, 40.71390178 ], [ -74.00832587, 40.71366299 ], [ -74.00855988, 40.71376921 ] ], [ [ -74.00833602, 40.71391451 ], [ -74.00826316, 40.71388135 ], [ -74.00821699, 40.71394039 ], [ -74.00828984, 40.71397341 ], [ -74.00833602, 40.71391451 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00899978, 40.70554517 ], [ -74.0088919, 40.70576397 ], [ -74.00882794, 40.7058939 ], [ -74.00878554, 40.7059052 ], [ -74.00848011, 40.70575906 ], [ -74.00849601, 40.70573748 ], [ -74.00852898, 40.70569301 ], [ -74.0085367, 40.70568252 ], [ -74.00854542, 40.70567081 ], [ -74.00858054, 40.70562328 ], [ -74.00863615, 40.70554809 ], [ -74.00868358, 40.70556839 ], [ -74.00870199, 40.70553468 ], [ -74.00869894, 40.70551922 ], [ -74.00869633, 40.70550601 ], [ -74.00869103, 40.70547952 ], [ -74.00868223, 40.70543498 ], [ -74.0086754, 40.7054008 ], [ -74.00898047, 40.70537199 ], [ -74.00899978, 40.70554517 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00848532, 40.70883636 ], [ -74.00841004, 40.70891011 ], [ -74.00834931, 40.70896942 ], [ -74.00833485, 40.70898358 ], [ -74.00827942, 40.7089511 ], [ -74.00829667, 40.70893408 ], [ -74.00818842, 40.70887068 ], [ -74.00813938, 40.70891876 ], [ -74.00812653, 40.70893149 ], [ -74.0079855, 40.70884896 ], [ -74.00801487, 40.70882016 ], [ -74.00777852, 40.70868179 ], [ -74.00782173, 40.70863929 ], [ -74.00798559, 40.70847852 ], [ -74.00833701, 40.70868417 ], [ -74.00829523, 40.70872516 ], [ -74.0083521, 40.70875846 ], [ -74.00844705, 40.70881396 ], [ -74.00848532, 40.70883636 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01379993, 40.70637161 ], [ -74.01376597, 40.70641349 ], [ -74.01366608, 40.70653688 ], [ -74.01363347, 40.70657719 ], [ -74.01360652, 40.70656548 ], [ -74.01356188, 40.70654621 ], [ -74.01355703, 40.7065441 ], [ -74.01353951, 40.7065364 ], [ -74.01347321, 40.70650726 ], [ -74.01344492, 40.706495 ], [ -74.01342102, 40.70648458 ], [ -74.01325771, 40.70641328 ], [ -74.01322932, 40.70640089 ], [ -74.01322348, 40.7063983 ], [ -74.01315611, 40.70636881 ], [ -74.01313814, 40.70636098 ], [ -74.01307158, 40.7063317 ], [ -74.01304481, 40.70631992 ], [ -74.01307858, 40.70628022 ], [ -74.01318153, 40.70615826 ], [ -74.01321513, 40.70611849 ], [ -74.01324181, 40.7061302 ], [ -74.01342399, 40.7062096 ], [ -74.01357921, 40.70627729 ], [ -74.01359619, 40.70628471 ], [ -74.01368773, 40.70632462 ], [ -74.01373947, 40.70634736 ], [ -74.01375367, 40.70635308 ], [ -74.01376705, 40.7063588 ], [ -74.01377747, 40.70636262 ], [ -74.01379993, 40.70637161 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00709455, 40.70707526 ], [ -74.00706203, 40.707101 ], [ -74.0069351, 40.70719702 ], [ -74.00691785, 40.70718387 ], [ -74.00682209, 40.70724897 ], [ -74.00683502, 40.70725919 ], [ -74.00675912, 40.70730127 ], [ -74.00674501, 40.70728697 ], [ -74.00667692, 40.70732511 ], [ -74.0065667, 40.70721036 ], [ -74.0064359, 40.70707417 ], [ -74.00658933, 40.70698462 ], [ -74.00666731, 40.70692599 ], [ -74.00678508, 40.70684441 ], [ -74.00709455, 40.70707526 ] ] ] } }, { "type": "Feature", "properties": { "height": 86.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01195093, 40.70905699 ], [ -74.01184169, 40.70919877 ], [ -74.01099341, 40.7088207 ], [ -74.01110265, 40.70867879 ], [ -74.01195093, 40.70905699 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01475861, 40.71308558 ], [ -74.01492633, 40.71314366 ], [ -74.01494474, 40.71320699 ], [ -74.01491627, 40.71324662 ], [ -74.01473804, 40.7131728 ], [ -74.01436165, 40.71369622 ], [ -74.01503368, 40.71397382 ], [ -74.01510608, 40.71387291 ], [ -74.01516043, 40.71389497 ], [ -74.01517211, 40.71395557 ], [ -74.01514318, 40.71399527 ], [ -74.01512504, 40.71402026 ], [ -74.01503341, 40.7140432 ], [ -74.01499262, 40.71402611 ], [ -74.01497223, 40.7140541 ], [ -74.01468432, 40.71393297 ], [ -74.0146898, 40.71392541 ], [ -74.01460338, 40.71388912 ], [ -74.01460087, 40.71389252 ], [ -74.01432104, 40.71375866 ], [ -74.01441231, 40.71352402 ], [ -74.0143974, 40.71352068 ], [ -74.01440243, 40.71350706 ], [ -74.01438429, 40.71350318 ], [ -74.01439012, 40.71348766 ], [ -74.01437045, 40.7134835 ], [ -74.01443073, 40.71332158 ], [ -74.0144504, 40.7133258 ], [ -74.01445543, 40.71331225 ], [ -74.01447358, 40.71331627 ], [ -74.01447915, 40.71330136 ], [ -74.01449981, 40.71330592 ], [ -74.01450421, 40.71329407 ], [ -74.01459647, 40.7132983 ], [ -74.0146651, 40.71312671 ], [ -74.01475861, 40.71308558 ] ] ] } }, { "type": "Feature", "properties": { "height": 84.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0042335, 40.71418851 ], [ -74.0040471, 40.71410319 ], [ -74.00407693, 40.71406547 ], [ -74.00395709, 40.71401059 ], [ -74.00389708, 40.71408637 ], [ -74.0037724, 40.71424421 ], [ -74.00356821, 40.71409631 ], [ -74.00367727, 40.71383512 ], [ -74.00376961, 40.71380632 ], [ -74.00433681, 40.71406601 ], [ -74.0042335, 40.71418851 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00899098, 40.71199366 ], [ -74.00879892, 40.7122247 ], [ -74.0083141, 40.71199121 ], [ -74.00850607, 40.71176038 ], [ -74.00855395, 40.7117834 ], [ -74.00862141, 40.71181588 ], [ -74.00872193, 40.71186429 ], [ -74.00899098, 40.71199366 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00942352, 40.7122723 ], [ -74.00943439, 40.71227747 ], [ -74.00943825, 40.7122898 ], [ -74.00934438, 40.71240256 ], [ -74.00932695, 40.7124048 ], [ -74.00931913, 40.71240119 ], [ -74.00928644, 40.71244089 ], [ -74.00881994, 40.71222361 ], [ -74.00885659, 40.71217976 ], [ -74.00885291, 40.71216737 ], [ -74.00897238, 40.71202322 ], [ -74.00898981, 40.71202097 ], [ -74.00900562, 40.71200027 ], [ -74.00922005, 40.71210418 ], [ -74.00925248, 40.71206509 ], [ -74.00925302, 40.71206448 ], [ -74.00932812, 40.7121007 ], [ -74.00930422, 40.71212937 ], [ -74.00942567, 40.71218786 ], [ -74.00947553, 40.7122121 ], [ -74.00942352, 40.7122723 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00550722, 40.70800798 ], [ -74.00549393, 40.70798305 ], [ -74.00548773, 40.70797127 ], [ -74.0054694, 40.70793947 ], [ -74.00543365, 40.70787778 ], [ -74.00547291, 40.70785476 ], [ -74.00542152, 40.70779947 ], [ -74.00537634, 40.70775078 ], [ -74.00535074, 40.70769841 ], [ -74.00532307, 40.70764189 ], [ -74.00531723, 40.70762861 ], [ -74.00530519, 40.70760171 ], [ -74.00528992, 40.70756658 ], [ -74.00527995, 40.7075437 ], [ -74.00545647, 40.70748166 ], [ -74.00562454, 40.70764802 ], [ -74.00572533, 40.70774846 ], [ -74.00583978, 40.70786212 ], [ -74.0058723, 40.70789439 ], [ -74.00552708, 40.7080442 ], [ -74.00550722, 40.70800798 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01463878, 40.70866279 ], [ -74.01460868, 40.70874341 ], [ -74.01458578, 40.70881682 ], [ -74.01440495, 40.70877528 ], [ -74.01455353, 40.70838271 ], [ -74.01491995, 40.70848846 ], [ -74.0149063, 40.7085285 ], [ -74.01485644, 40.70865829 ], [ -74.01488671, 40.70866517 ], [ -74.01493944, 40.70867906 ], [ -74.01487027, 40.70885209 ], [ -74.01468181, 40.70881171 ], [ -74.01472789, 40.70868192 ], [ -74.01463878, 40.70866279 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01363347, 40.70657719 ], [ -74.01353124, 40.70671339 ], [ -74.01348929, 40.70676916 ], [ -74.01341761, 40.70673777 ], [ -74.01336488, 40.70671461 ], [ -74.01331601, 40.70669337 ], [ -74.01304948, 40.70657651 ], [ -74.01300088, 40.7065552 ], [ -74.01294815, 40.70653211 ], [ -74.01288949, 40.7065059 ], [ -74.01297267, 40.70640627 ], [ -74.01304481, 40.70631992 ], [ -74.01307158, 40.7063317 ], [ -74.01313814, 40.70636098 ], [ -74.01315611, 40.70636881 ], [ -74.01322348, 40.7063983 ], [ -74.01322932, 40.70640089 ], [ -74.01325771, 40.70641328 ], [ -74.01342102, 40.70648458 ], [ -74.01344492, 40.706495 ], [ -74.01347321, 40.70650726 ], [ -74.01353951, 40.7065364 ], [ -74.01355703, 40.7065441 ], [ -74.01356188, 40.70654621 ], [ -74.01360652, 40.70656548 ], [ -74.01363347, 40.70657719 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00619929, 40.7096138 ], [ -74.00604253, 40.70977192 ], [ -74.00539718, 40.70944397 ], [ -74.00555403, 40.70929137 ], [ -74.00619929, 40.7096138 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01080782, 40.70799157 ], [ -74.01083423, 40.70796392 ], [ -74.0109123, 40.70788207 ], [ -74.01105531, 40.70773226 ], [ -74.01113041, 40.70777019 ], [ -74.01117981, 40.70779511 ], [ -74.01119697, 40.70780376 ], [ -74.011263, 40.70783706 ], [ -74.01134771, 40.70787989 ], [ -74.0113575, 40.70788479 ], [ -74.01141374, 40.70791319 ], [ -74.01141922, 40.70791598 ], [ -74.01116697, 40.7082075 ], [ -74.01080782, 40.70799157 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01028159, 40.71341459 ], [ -74.01013795, 40.71334936 ], [ -74.01009932, 40.71339812 ], [ -74.00972499, 40.71322782 ], [ -74.00986998, 40.71304466 ], [ -74.01024, 40.71321311 ], [ -74.01020874, 40.71325261 ], [ -74.01035893, 40.71332077 ], [ -74.0103902, 40.71328121 ], [ -74.01053941, 40.71334909 ], [ -74.01039442, 40.71353212 ], [ -74.01024314, 40.71346321 ], [ -74.01028159, 40.71341459 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01500987, 40.70826606 ], [ -74.01482383, 40.70820008 ], [ -74.01457473, 40.70811176 ], [ -74.01474702, 40.70783038 ], [ -74.0147976, 40.70784836 ], [ -74.01480955, 40.70785258 ], [ -74.01496487, 40.70790767 ], [ -74.01504814, 40.70793709 ], [ -74.01509548, 40.70795418 ], [ -74.01512935, 40.70796589 ], [ -74.01518217, 40.70798469 ], [ -74.01500987, 40.70826606 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01310392, 40.71152267 ], [ -74.01299118, 40.71162161 ], [ -74.01276893, 40.71158348 ], [ -74.01257795, 40.71158708 ], [ -74.01235095, 40.71157762 ], [ -74.0124698, 40.71126419 ], [ -74.01253986, 40.71128986 ], [ -74.01285661, 40.71140589 ], [ -74.01310392, 40.71152267 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01379993, 40.70637161 ], [ -74.01377747, 40.70636262 ], [ -74.01376705, 40.7063588 ], [ -74.01375367, 40.70635308 ], [ -74.01373947, 40.70634736 ], [ -74.01368773, 40.70632462 ], [ -74.01359619, 40.70628471 ], [ -74.01357921, 40.70627729 ], [ -74.01342399, 40.7062096 ], [ -74.01324181, 40.7061302 ], [ -74.01321513, 40.70611849 ], [ -74.01329858, 40.70601961 ], [ -74.01335652, 40.7059511 ], [ -74.01346908, 40.70598992 ], [ -74.01395058, 40.7061558 ], [ -74.01379993, 40.70637161 ] ] ] } }, { "type": "Feature", "properties": { "height": 142.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01080243, 40.71038987 ], [ -74.01079354, 40.71040131 ], [ -74.01078429, 40.71041289 ], [ -74.01075779, 40.71044687 ], [ -74.01074889, 40.71045831 ], [ -74.01071215, 40.71050481 ], [ -74.01070317, 40.71051612 ], [ -74.01066679, 40.71056256 ], [ -74.01065789, 40.710574 ], [ -74.01062834, 40.71061186 ], [ -74.01062178, 40.71062037 ], [ -74.0106128, 40.71063181 ], [ -74.01057615, 40.71067832 ], [ -74.01056734, 40.71068962 ], [ -74.01055234, 40.71068281 ], [ -74.01049844, 40.7106583 ], [ -74.01048344, 40.71065149 ], [ -74.01042972, 40.71062718 ], [ -74.01041472, 40.71062037 ], [ -74.01036091, 40.71059599 ], [ -74.01034591, 40.71058918 ], [ -74.01029237, 40.71056501 ], [ -74.01027737, 40.7105582 ], [ -74.01022338, 40.71053369 ], [ -74.01020847, 40.71052701 ], [ -74.01029524, 40.71041636 ], [ -74.0104432, 40.71022788 ], [ -74.01045811, 40.71023462 ], [ -74.01051192, 40.71025886 ], [ -74.01052692, 40.7102656 ], [ -74.01058055, 40.71028977 ], [ -74.01059555, 40.71029658 ], [ -74.01064945, 40.71032089 ], [ -74.01066445, 40.71032757 ], [ -74.01071808, 40.71035188 ], [ -74.01073317, 40.71035868 ], [ -74.01078698, 40.71038286 ], [ -74.01080243, 40.71038987 ] ] ] } }, { "type": "Feature", "properties": { "height": 77.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01305559, 40.70738238 ], [ -74.01300573, 40.70745279 ], [ -74.01297294, 40.70743849 ], [ -74.01283784, 40.70737972 ], [ -74.01279831, 40.7074295 ], [ -74.0129362, 40.70749072 ], [ -74.01296872, 40.70750522 ], [ -74.01292138, 40.70757196 ], [ -74.01291213, 40.7075678 ], [ -74.01272294, 40.70748241 ], [ -74.01225384, 40.70727056 ], [ -74.01224881, 40.70726838 ], [ -74.01230091, 40.70720376 ], [ -74.01232669, 40.70721608 ], [ -74.01248067, 40.70728929 ], [ -74.01252235, 40.70723692 ], [ -74.01236891, 40.70716372 ], [ -74.01234322, 40.70715139 ], [ -74.01240314, 40.70707716 ], [ -74.01252917, 40.7071362 ], [ -74.01264362, 40.70718966 ], [ -74.01284008, 40.70728159 ], [ -74.01295444, 40.70733512 ], [ -74.01305559, 40.70738238 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00599429, 40.7135151 ], [ -74.0058882, 40.71364726 ], [ -74.00508564, 40.71327726 ], [ -74.00519182, 40.71314509 ], [ -74.00599429, 40.7135151 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00968888, 40.70662016 ], [ -74.00967657, 40.70663242 ], [ -74.00963974, 40.70666906 ], [ -74.0095279, 40.70678741 ], [ -74.00955099, 40.70680062 ], [ -74.00957524, 40.70681499 ], [ -74.00941993, 40.70697318 ], [ -74.00938318, 40.70701036 ], [ -74.0093601, 40.70703331 ], [ -74.00934393, 40.70705156 ], [ -74.0093194, 40.70707982 ], [ -74.00909761, 40.70694138 ], [ -74.00949547, 40.7065029 ], [ -74.00968888, 40.70662016 ] ] ] } }, { "type": "Feature", "properties": { "height": 108.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00618644, 40.7079266 ], [ -74.00630708, 40.70783522 ], [ -74.00642207, 40.70774826 ], [ -74.00637311, 40.70771081 ], [ -74.00644938, 40.70765306 ], [ -74.00676531, 40.70788139 ], [ -74.00655538, 40.70815711 ], [ -74.00618644, 40.7079266 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00540589, 40.71388551 ], [ -74.00513182, 40.71421786 ], [ -74.00512292, 40.71422861 ], [ -74.00497165, 40.71415691 ], [ -74.00505447, 40.7140509 ], [ -74.00494299, 40.7139999 ], [ -74.00486133, 40.71410462 ], [ -74.00474851, 40.71405117 ], [ -74.00503148, 40.71370806 ], [ -74.00512903, 40.71375437 ], [ -74.00502671, 40.71388292 ], [ -74.00514628, 40.7139376 ], [ -74.00524752, 40.71381047 ], [ -74.00540589, 40.71388551 ] ] ] } }, { "type": "Feature", "properties": { "height": 82.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01329068, 40.7083202 ], [ -74.01315225, 40.70828159 ], [ -74.01315961, 40.70826327 ], [ -74.01323121, 40.7080852 ], [ -74.0131217, 40.70805176 ], [ -74.01300402, 40.7082235 ], [ -74.01299324, 40.7082378 ], [ -74.01285778, 40.70819946 ], [ -74.01284107, 40.70819477 ], [ -74.0130678, 40.70785401 ], [ -74.01345758, 40.70797679 ], [ -74.0133064, 40.70832456 ], [ -74.01329068, 40.7083202 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01055234, 40.70722991 ], [ -74.01022518, 40.70756637 ], [ -74.00995361, 40.70741472 ], [ -74.0102806, 40.70707819 ], [ -74.01055234, 40.70722991 ] ] ] } }, { "type": "Feature", "properties": { "height": 107.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00482962, 40.70749678 ], [ -74.00462544, 40.70757849 ], [ -74.00443598, 40.70766028 ], [ -74.00432324, 40.70750018 ], [ -74.00493652, 40.70726361 ], [ -74.00504495, 40.7072184 ], [ -74.00514924, 40.70736896 ], [ -74.00482962, 40.70749678 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01017819, 40.7093957 ], [ -74.01015762, 40.709385 ], [ -74.01013507, 40.70937288 ], [ -74.01011019, 40.70936042 ], [ -74.00997437, 40.70928988 ], [ -74.00992235, 40.70926291 ], [ -74.00986262, 40.70923186 ], [ -74.00981069, 40.70928981 ], [ -74.00979812, 40.7092832 ], [ -74.00980809, 40.7092721 ], [ -74.00975051, 40.70924221 ], [ -74.00972805, 40.7092305 ], [ -74.00976793, 40.70918276 ], [ -74.00982255, 40.70912189 ], [ -74.00992505, 40.70900762 ], [ -74.0099308, 40.70900102 ], [ -74.00994149, 40.7089891 ], [ -74.00995793, 40.70897078 ], [ -74.0103849, 40.70916492 ], [ -74.01017819, 40.7093957 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00918358, 40.71176229 ], [ -74.00914306, 40.71181097 ], [ -74.0090491, 40.71192401 ], [ -74.0089855, 40.71189459 ], [ -74.00877925, 40.71179572 ], [ -74.00872193, 40.71186429 ], [ -74.00862141, 40.71181588 ], [ -74.00855395, 40.7117834 ], [ -74.00850607, 40.71176038 ], [ -74.00870729, 40.71151852 ], [ -74.00919211, 40.71175207 ], [ -74.00918358, 40.71176229 ] ] ] } }, { "type": "Feature", "properties": { "height": 77.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01292138, 40.70757196 ], [ -74.01285239, 40.70769671 ], [ -74.01210921, 40.70745279 ], [ -74.01224881, 40.70726838 ], [ -74.01225384, 40.70727056 ], [ -74.01260876, 40.70743086 ], [ -74.01272294, 40.70748241 ], [ -74.01291213, 40.7075678 ], [ -74.01292138, 40.70757196 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01079354, 40.71040131 ], [ -74.01078429, 40.71041289 ], [ -74.01075779, 40.71044687 ], [ -74.01074907, 40.71044298 ], [ -74.01074018, 40.71045436 ], [ -74.01074889, 40.71045831 ], [ -74.01071215, 40.71050481 ], [ -74.01070335, 40.7105008 ], [ -74.01069437, 40.71051217 ], [ -74.01070317, 40.71051612 ], [ -74.01066679, 40.71056256 ], [ -74.01065798, 40.71055868 ], [ -74.01064909, 40.71056998 ], [ -74.01065789, 40.710574 ], [ -74.01062834, 40.71061186 ], [ -74.01062178, 40.71062037 ], [ -74.01061298, 40.71061649 ], [ -74.01060408, 40.71062786 ], [ -74.0106128, 40.71063181 ], [ -74.01057615, 40.71067832 ], [ -74.01055234, 40.71068281 ], [ -74.01049844, 40.7106583 ], [ -74.01050347, 40.7106519 ], [ -74.01048847, 40.71064502 ], [ -74.01048344, 40.71065149 ], [ -74.01042972, 40.71062718 ], [ -74.01043484, 40.71062071 ], [ -74.01041993, 40.71061376 ], [ -74.01041472, 40.71062037 ], [ -74.01036091, 40.71059599 ], [ -74.01036603, 40.71058952 ], [ -74.01035112, 40.71058258 ], [ -74.01034591, 40.71058918 ], [ -74.01029237, 40.71056501 ], [ -74.01029749, 40.7105584 ], [ -74.01028258, 40.71055146 ], [ -74.01027737, 40.7105582 ], [ -74.01022338, 40.71053369 ], [ -74.01045811, 40.71023462 ], [ -74.01051192, 40.71025886 ], [ -74.01050698, 40.71026506 ], [ -74.01052198, 40.71027186 ], [ -74.01052692, 40.7102656 ], [ -74.01058055, 40.71028977 ], [ -74.01057552, 40.71029611 ], [ -74.01059052, 40.71030292 ], [ -74.01059555, 40.71029658 ], [ -74.01064945, 40.71032089 ], [ -74.01064433, 40.71032736 ], [ -74.01065933, 40.71033417 ], [ -74.01066445, 40.71032757 ], [ -74.01071808, 40.71035188 ], [ -74.01071287, 40.71035848 ], [ -74.01072805, 40.71036529 ], [ -74.01073317, 40.71035868 ], [ -74.01078698, 40.71038286 ], [ -74.01079354, 40.71040131 ] ] ] } }, { "type": "Feature", "properties": { "height": 133.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00467493, 40.70689609 ], [ -74.00436663, 40.7070867 ], [ -74.0041151, 40.70685728 ], [ -74.00417493, 40.70682051 ], [ -74.00415229, 40.70679946 ], [ -74.00412481, 40.70677556 ], [ -74.00431435, 40.70665231 ], [ -74.00433887, 40.70667519 ], [ -74.00436124, 40.70669596 ], [ -74.00442098, 40.70665918 ], [ -74.00467493, 40.70689609 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00440158, 40.70906026 ], [ -74.0043775, 40.70908171 ], [ -74.00439188, 40.70909111 ], [ -74.00433564, 40.70914088 ], [ -74.00429719, 40.70911569 ], [ -74.00427617, 40.70913428 ], [ -74.0043333, 40.70917166 ], [ -74.0042777, 40.70922069 ], [ -74.00429647, 40.70923322 ], [ -74.00420655, 40.70931146 ], [ -74.0041885, 40.70929948 ], [ -74.00413271, 40.70934878 ], [ -74.00410388, 40.70932998 ], [ -74.00407881, 40.70935218 ], [ -74.00396967, 40.70928062 ], [ -74.00404692, 40.70921238 ], [ -74.00402851, 40.7092002 ], [ -74.00406902, 40.70916492 ], [ -74.00408708, 40.70917691 ], [ -74.00415427, 40.70911746 ], [ -74.00413154, 40.70910261 ], [ -74.00411403, 40.7091176 ], [ -74.00406615, 40.70908532 ], [ -74.00408303, 40.70907081 ], [ -74.00404917, 40.70904862 ], [ -74.00403228, 40.70906346 ], [ -74.00398512, 40.70903261 ], [ -74.00400201, 40.7090177 ], [ -74.00393472, 40.70897351 ], [ -74.00391774, 40.70898801 ], [ -74.00387139, 40.70895669 ], [ -74.00388783, 40.70894266 ], [ -74.00381228, 40.70889329 ], [ -74.00393068, 40.7087887 ], [ -74.00400533, 40.70883759 ], [ -74.00402123, 40.7088237 ], [ -74.00406758, 40.70885448 ], [ -74.00405204, 40.70886816 ], [ -74.0041487, 40.70893156 ], [ -74.00416361, 40.70891821 ], [ -74.00426557, 40.70898399 ], [ -74.00424994, 40.70899802 ], [ -74.00434094, 40.70905767 ], [ -74.00436511, 40.70903629 ], [ -74.00440158, 40.70906026 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00945604, 40.70559849 ], [ -74.00943187, 40.70556069 ], [ -74.00917109, 40.70547618 ], [ -74.00916588, 40.70541142 ], [ -74.00947311, 40.70537267 ], [ -74.00952772, 40.70533746 ], [ -74.00982237, 40.70538411 ], [ -74.00984797, 40.70541489 ], [ -74.00979039, 40.70562471 ], [ -74.00975329, 40.70564541 ], [ -74.00945604, 40.70559849 ] ] ] } }, { "type": "Feature", "properties": { "height": 118.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0080641, 40.71130879 ], [ -74.00770073, 40.71140351 ], [ -74.00752457, 40.71101218 ], [ -74.00765572, 40.71092127 ], [ -74.00772705, 40.7109639 ], [ -74.00771187, 40.71097847 ], [ -74.00773855, 40.71103669 ], [ -74.00776622, 40.71109729 ], [ -74.00778975, 40.71107448 ], [ -74.00780224, 40.7110819 ], [ -74.0078706, 40.71101551 ], [ -74.00785838, 40.7110083 ], [ -74.00790357, 40.71096438 ], [ -74.00796241, 40.71099992 ], [ -74.00793833, 40.71102927 ], [ -74.0079828, 40.71112807 ], [ -74.0078079, 40.71117369 ], [ -74.00783799, 40.7112407 ], [ -74.00801298, 40.71119508 ], [ -74.0080641, 40.71130879 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00471563, 40.70901539 ], [ -74.00452267, 40.70889111 ], [ -74.0045471, 40.70886932 ], [ -74.00436528, 40.70864529 ], [ -74.00461565, 40.70852762 ], [ -74.00482019, 40.70877957 ], [ -74.00492988, 40.70891467 ], [ -74.00471563, 40.70901539 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01217614, 40.71064679 ], [ -74.01214685, 40.7106822 ], [ -74.01144248, 40.71037898 ], [ -74.01176174, 40.70989367 ], [ -74.01187484, 40.70994297 ], [ -74.01170811, 40.71040696 ], [ -74.01175905, 40.71041786 ], [ -74.0117303, 40.71045531 ], [ -74.01200618, 40.71057679 ], [ -74.01217614, 40.71064679 ] ] ] } }, { "type": "Feature", "properties": { "height": 117.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01203923, 40.70592938 ], [ -74.01188544, 40.70624297 ], [ -74.01187969, 40.70624059 ], [ -74.0118178, 40.7062143 ], [ -74.01156681, 40.70610759 ], [ -74.01154282, 40.70609717 ], [ -74.01153743, 40.70609479 ], [ -74.01151569, 40.70608539 ], [ -74.01149153, 40.70607477 ], [ -74.01154462, 40.70584841 ], [ -74.0115863, 40.70585522 ], [ -74.01161819, 40.70586046 ], [ -74.01171647, 40.7058766 ], [ -74.01196602, 40.70591739 ], [ -74.01203923, 40.70592938 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00627573, 40.70673681 ], [ -74.0062098, 40.70668731 ], [ -74.00614745, 40.70664039 ], [ -74.00608331, 40.70659218 ], [ -74.00589278, 40.70644468 ], [ -74.0060463, 40.70632659 ], [ -74.00660523, 40.70674778 ], [ -74.00644731, 40.70686749 ], [ -74.00627573, 40.70673681 ] ] ] } }, { "type": "Feature", "properties": { "height": 83.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01291213, 40.7075678 ], [ -74.01284619, 40.70768677 ], [ -74.0121199, 40.70744931 ], [ -74.01225384, 40.70727056 ], [ -74.01260876, 40.70743086 ], [ -74.01272294, 40.70748241 ], [ -74.01291213, 40.7075678 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01276112, 40.70625557 ], [ -74.01261299, 40.7064429 ], [ -74.01257508, 40.70642547 ], [ -74.0124388, 40.70636269 ], [ -74.0123054, 40.70630242 ], [ -74.01218027, 40.70624481 ], [ -74.01214083, 40.70622656 ], [ -74.0121296, 40.70622152 ], [ -74.01222779, 40.70601702 ], [ -74.01227989, 40.70604031 ], [ -74.01232319, 40.70605972 ], [ -74.0123637, 40.70607776 ], [ -74.01242021, 40.7061031 ], [ -74.01258945, 40.70617882 ], [ -74.01264425, 40.70620327 ], [ -74.01272438, 40.70623916 ], [ -74.01276112, 40.70625557 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01339443, 40.70689487 ], [ -74.01326651, 40.70706498 ], [ -74.01325924, 40.70707029 ], [ -74.01324998, 40.70707322 ], [ -74.01324504, 40.70707369 ], [ -74.01323507, 40.7070726 ], [ -74.01308209, 40.70700587 ], [ -74.01311739, 40.70695888 ], [ -74.01310724, 40.70696201 ], [ -74.01309619, 40.70696222 ], [ -74.0130908, 40.70696126 ], [ -74.01267928, 40.70678189 ], [ -74.01267632, 40.70677917 ], [ -74.01267255, 40.70677291 ], [ -74.01267174, 40.70676936 ], [ -74.01267174, 40.70676589 ], [ -74.01267407, 40.70675908 ], [ -74.01268674, 40.70674519 ], [ -74.01275591, 40.70666218 ], [ -74.01276031, 40.70665912 ], [ -74.01277073, 40.70665442 ], [ -74.01277639, 40.70665292 ], [ -74.01285832, 40.70668881 ], [ -74.01287395, 40.70666797 ], [ -74.01314434, 40.70678666 ], [ -74.01339443, 40.70689487 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726217, 40.70725367 ], [ -74.00715357, 40.70733491 ], [ -74.00679882, 40.70760396 ], [ -74.00666973, 40.70750597 ], [ -74.00674277, 40.70745061 ], [ -74.00671186, 40.70742711 ], [ -74.00697543, 40.70722759 ], [ -74.0069351, 40.70719702 ], [ -74.00706203, 40.707101 ], [ -74.00709455, 40.70707526 ], [ -74.00729532, 40.7072282 ], [ -74.00726217, 40.70725367 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0146395, 40.70939352 ], [ -74.01449711, 40.70939209 ], [ -74.01435266, 40.70935797 ], [ -74.01429221, 40.70951207 ], [ -74.01436955, 40.70952719 ], [ -74.01436443, 40.70953842 ], [ -74.01444241, 40.70955878 ], [ -74.01443495, 40.70958221 ], [ -74.01441375, 40.70963648 ], [ -74.01400079, 40.70945896 ], [ -74.01412117, 40.70915546 ], [ -74.01464471, 40.70937581 ], [ -74.0146395, 40.70939352 ] ] ] } }, { "type": "Feature", "properties": { "height": 151.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00663497, 40.70626912 ], [ -74.0069598, 40.7059445 ], [ -74.00698468, 40.70591937 ], [ -74.00719686, 40.70604188 ], [ -74.00682343, 40.70641607 ], [ -74.00661017, 40.70629411 ], [ -74.00663497, 40.70626912 ] ] ] } }, { "type": "Feature", "properties": { "height": 132.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01315755, 40.71379651 ], [ -74.01306762, 40.71391077 ], [ -74.01300241, 40.7139935 ], [ -74.01294662, 40.71396851 ], [ -74.01273327, 40.71387196 ], [ -74.01267785, 40.71384676 ], [ -74.01274324, 40.71376186 ], [ -74.01282634, 40.71365809 ], [ -74.01290045, 40.71356412 ], [ -74.01295605, 40.71358857 ], [ -74.01316931, 40.71368498 ], [ -74.01322492, 40.71371079 ], [ -74.01315755, 40.71379651 ] ] ] } }, { "type": "Feature", "properties": { "height": 82.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01039945, 40.7057575 ], [ -74.01030198, 40.70590799 ], [ -74.00994301, 40.70577336 ], [ -74.01, 40.70558208 ], [ -74.0101755, 40.70556526 ], [ -74.0102921, 40.7055549 ], [ -74.0106313, 40.70554946 ], [ -74.01065053, 40.70562859 ], [ -74.01019517, 40.70563458 ], [ -74.01018313, 40.70567197 ], [ -74.01026695, 40.70570336 ], [ -74.01028312, 40.7056783 ], [ -74.01040151, 40.7057227 ], [ -74.01038301, 40.7057513 ], [ -74.01039945, 40.7057575 ] ] ] } }, { "type": "Feature", "properties": { "height": 93.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01329068, 40.7083202 ], [ -74.01315225, 40.70828159 ], [ -74.01315961, 40.70826327 ], [ -74.01323121, 40.7080852 ], [ -74.0131217, 40.70805176 ], [ -74.01300402, 40.7082235 ], [ -74.01299324, 40.7082378 ], [ -74.01285778, 40.70819946 ], [ -74.01307355, 40.70786899 ], [ -74.01343647, 40.70798326 ], [ -74.01329068, 40.7083202 ] ] ] } }, { "type": "Feature", "properties": { "height": 51.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00776909, 40.70780621 ], [ -74.00766731, 40.70788758 ], [ -74.00760829, 40.70780989 ], [ -74.00751127, 40.70785136 ], [ -74.00754218, 40.70789358 ], [ -74.00753059, 40.70790658 ], [ -74.0074739, 40.70796426 ], [ -74.00732245, 40.70786579 ], [ -74.00732793, 40.70786021 ], [ -74.00727448, 40.70782541 ], [ -74.00729739, 40.70780219 ], [ -74.00727053, 40.7077868 ], [ -74.00726505, 40.70779967 ], [ -74.0070075, 40.70769671 ], [ -74.00709383, 40.70758517 ], [ -74.00710443, 40.70759062 ], [ -74.0072752, 40.70767717 ], [ -74.00725058, 40.70770216 ], [ -74.0073653, 40.7077503 ], [ -74.00751604, 40.70768438 ], [ -74.00748415, 40.70764727 ], [ -74.00759733, 40.7075614 ], [ -74.00776909, 40.70780621 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00849349, 40.71304936 ], [ -74.0082107, 40.71340901 ], [ -74.00796852, 40.7132987 ], [ -74.00812527, 40.71309927 ], [ -74.00816812, 40.71304486 ], [ -74.00813731, 40.71303131 ], [ -74.00817603, 40.71298222 ], [ -74.00820621, 40.71294388 ], [ -74.00822157, 40.71292536 ], [ -74.00849349, 40.71304936 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01063678, 40.71086271 ], [ -74.01056689, 40.71083098 ], [ -74.01050814, 40.71080429 ], [ -74.0105368, 40.71076779 ], [ -74.01055827, 40.71074049 ], [ -74.01058827, 40.71070228 ], [ -74.01065098, 40.71062262 ], [ -74.01062834, 40.71061186 ], [ -74.01065789, 40.710574 ], [ -74.01066679, 40.71056256 ], [ -74.01070317, 40.71051612 ], [ -74.01071215, 40.71050481 ], [ -74.01074889, 40.71045831 ], [ -74.01075779, 40.71044687 ], [ -74.01078429, 40.71041289 ], [ -74.01079354, 40.71040131 ], [ -74.01080243, 40.71038987 ], [ -74.01081375, 40.71037475 ], [ -74.01083935, 40.71034221 ], [ -74.01087798, 40.71029277 ], [ -74.01092568, 40.71031449 ], [ -74.0109953, 40.71034602 ], [ -74.01104291, 40.7103676 ], [ -74.01069544, 40.71088927 ], [ -74.01063678, 40.71086271 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01149153, 40.70607477 ], [ -74.01151569, 40.70608539 ], [ -74.01153743, 40.70609479 ], [ -74.01154282, 40.70609717 ], [ -74.01156681, 40.70610759 ], [ -74.0118178, 40.7062143 ], [ -74.01187969, 40.70624059 ], [ -74.01188544, 40.70624297 ], [ -74.01189874, 40.70624842 ], [ -74.01191922, 40.70625659 ], [ -74.01193665, 40.7062636 ], [ -74.01182516, 40.70648247 ], [ -74.01136487, 40.70628689 ], [ -74.01149153, 40.70607477 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00385127, 40.70990021 ], [ -74.00378012, 40.70985377 ], [ -74.0037414, 40.70988809 ], [ -74.00353695, 40.70975401 ], [ -74.00357387, 40.70972139 ], [ -74.0035595, 40.70971199 ], [ -74.00365337, 40.70962899 ], [ -74.00366918, 40.70963941 ], [ -74.00370511, 40.70960767 ], [ -74.00371122, 40.70961176 ], [ -74.00374706, 40.70963532 ], [ -74.00390813, 40.70974087 ], [ -74.00388639, 40.70976021 ], [ -74.00395763, 40.70980658 ], [ -74.00400874, 40.70976136 ], [ -74.00421293, 40.7098953 ], [ -74.00417772, 40.70992636 ], [ -74.00419065, 40.70993487 ], [ -74.00409678, 40.71001767 ], [ -74.00408393, 40.71000929 ], [ -74.00404818, 40.71004082 ], [ -74.0038439, 40.70990681 ], [ -74.00385127, 40.70990021 ] ] ] } }, { "type": "Feature", "properties": { "height": 51.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01482706, 40.70904576 ], [ -74.01473768, 40.70926591 ], [ -74.01453278, 40.70921817 ], [ -74.01454589, 40.7091859 ], [ -74.01455541, 40.7091624 ], [ -74.01459764, 40.70905427 ], [ -74.01460725, 40.70903077 ], [ -74.01461677, 40.70900578 ], [ -74.01442794, 40.70895941 ], [ -74.01440378, 40.70902369 ], [ -74.01439489, 40.70904732 ], [ -74.01438923, 40.70906257 ], [ -74.01424972, 40.70903077 ], [ -74.01425565, 40.70901579 ], [ -74.01426481, 40.70899216 ], [ -74.01430981, 40.70887702 ], [ -74.01431898, 40.70885345 ], [ -74.0143285, 40.70882792 ], [ -74.01436767, 40.7088367 ], [ -74.01439075, 40.70878039 ], [ -74.01458138, 40.70882499 ], [ -74.01455227, 40.70889649 ], [ -74.0147499, 40.70894116 ], [ -74.01471873, 40.70902049 ], [ -74.01482706, 40.70904576 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00721789, 40.71116157 ], [ -74.00704379, 40.7112821 ], [ -74.00702708, 40.71126807 ], [ -74.0069642, 40.71121727 ], [ -74.00693644, 40.71123716 ], [ -74.00695495, 40.71125118 ], [ -74.00676882, 40.71138281 ], [ -74.00658367, 40.7112281 ], [ -74.0069739, 40.7109577 ], [ -74.00721789, 40.71116157 ] ], [ [ -74.00708781, 40.711099 ], [ -74.00704244, 40.7110642 ], [ -74.00696115, 40.71112562 ], [ -74.00700651, 40.71116042 ], [ -74.00708781, 40.711099 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0122409, 40.70564977 ], [ -74.01219473, 40.70574721 ], [ -74.01199647, 40.70572651 ], [ -74.01193287, 40.70571977 ], [ -74.01194177, 40.70586836 ], [ -74.01171647, 40.7058766 ], [ -74.01161819, 40.70586046 ], [ -74.0115863, 40.70585522 ], [ -74.01154462, 40.70584841 ], [ -74.0115545, 40.70578167 ], [ -74.01156537, 40.70570908 ], [ -74.01157723, 40.70562988 ], [ -74.01164748, 40.70562968 ], [ -74.01179318, 40.7056275 ], [ -74.01200132, 40.70562471 ], [ -74.0121323, 40.70563839 ], [ -74.01220147, 40.70564568 ], [ -74.0122409, 40.70564977 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00671654, 40.70842289 ], [ -74.0067036, 40.70843446 ], [ -74.00669569, 40.70844161 ], [ -74.0066921, 40.70844488 ], [ -74.00667494, 40.7084602 ], [ -74.00665419, 40.70847886 ], [ -74.00663344, 40.70849759 ], [ -74.00663039, 40.70850031 ], [ -74.00661305, 40.70851638 ], [ -74.00659248, 40.70853531 ], [ -74.00658251, 40.70854457 ], [ -74.00652394, 40.70859878 ], [ -74.00649555, 40.70862561 ], [ -74.00647094, 40.70864726 ], [ -74.00644255, 40.70867048 ], [ -74.00646555, 40.70868751 ], [ -74.00637401, 40.70876159 ], [ -74.00617054, 40.70862091 ], [ -74.0061594, 40.70861321 ], [ -74.00614808, 40.70860538 ], [ -74.00641389, 40.70837549 ], [ -74.00651109, 40.70829139 ], [ -74.00657478, 40.70833218 ], [ -74.00665338, 40.70838251 ], [ -74.00671654, 40.70842289 ] ] ] } }, { "type": "Feature", "properties": { "height": 267.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00595728, 40.71094191 ], [ -74.00576971, 40.71105828 ], [ -74.00569874, 40.71099257 ], [ -74.00551297, 40.71110778 ], [ -74.00537499, 40.71097997 ], [ -74.00557424, 40.71085638 ], [ -74.00550525, 40.71079251 ], [ -74.00567934, 40.71068451 ], [ -74.00595728, 40.71094191 ] ] ] } }, { "type": "Feature", "properties": { "height": 73.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00465149, 40.70919407 ], [ -74.0045816, 40.70914817 ], [ -74.00456211, 40.70916547 ], [ -74.00440158, 40.70906026 ], [ -74.00436511, 40.70903629 ], [ -74.00436133, 40.70903391 ], [ -74.00439538, 40.70900367 ], [ -74.00437553, 40.70899067 ], [ -74.00447147, 40.70890589 ], [ -74.00449141, 40.70891896 ], [ -74.00452267, 40.70889111 ], [ -74.00471563, 40.70901539 ], [ -74.00472434, 40.70902111 ], [ -74.00468769, 40.70905338 ], [ -74.00476162, 40.70910187 ], [ -74.00476881, 40.70909546 ], [ -74.00497057, 40.70922777 ], [ -74.00493616, 40.70925821 ], [ -74.00495269, 40.70926897 ], [ -74.00485612, 40.70935429 ], [ -74.0048396, 40.70934347 ], [ -74.00480627, 40.70937288 ], [ -74.00480034, 40.709369 ], [ -74.00476611, 40.7093466 ], [ -74.00460118, 40.70923846 ], [ -74.00465149, 40.70919407 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00452725, 40.70841901 ], [ -74.00438891, 40.70848199 ], [ -74.00420251, 40.70825558 ], [ -74.00405932, 40.70832326 ], [ -74.00409283, 40.70836398 ], [ -74.00384705, 40.70848029 ], [ -74.00383923, 40.70847076 ], [ -74.00375057, 40.7083631 ], [ -74.00376647, 40.70835561 ], [ -74.00374679, 40.70833171 ], [ -74.00416523, 40.70813382 ], [ -74.0042468, 40.70823297 ], [ -74.00433843, 40.70818959 ], [ -74.00452725, 40.70841901 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01063678, 40.71086271 ], [ -74.01063912, 40.71085978 ], [ -74.01064361, 40.71085209 ], [ -74.01064514, 40.71084371 ], [ -74.01064361, 40.71083527 ], [ -74.01063921, 40.71082758 ], [ -74.0106322, 40.71082097 ], [ -74.01062313, 40.71081607 ], [ -74.01061262, 40.71081328 ], [ -74.01060148, 40.71081266 ], [ -74.01059061, 40.71081437 ], [ -74.01058073, 40.71081818 ], [ -74.01057255, 40.71082397 ], [ -74.01056689, 40.71083098 ], [ -74.01050814, 40.71080429 ], [ -74.0105368, 40.71076779 ], [ -74.01055827, 40.71074049 ], [ -74.01058827, 40.71070228 ], [ -74.01065098, 40.71062262 ], [ -74.01062834, 40.71061186 ], [ -74.01065789, 40.710574 ], [ -74.01066679, 40.71056256 ], [ -74.01070317, 40.71051612 ], [ -74.01071215, 40.71050481 ], [ -74.01074889, 40.71045831 ], [ -74.01075779, 40.71044687 ], [ -74.01078429, 40.71041289 ], [ -74.01079354, 40.71040131 ], [ -74.01080243, 40.71038987 ], [ -74.01081375, 40.71037475 ], [ -74.01083935, 40.71034221 ], [ -74.01087798, 40.71029277 ], [ -74.01092568, 40.71031449 ], [ -74.01091921, 40.7103228 ], [ -74.01091607, 40.71033097 ], [ -74.01091607, 40.71033941 ], [ -74.01091912, 40.71034759 ], [ -74.01092478, 40.7103548 ], [ -74.01093305, 40.71036059 ], [ -74.01094284, 40.71036447 ], [ -74.0109538, 40.71036617 ], [ -74.01096494, 40.7103657 ], [ -74.01097545, 40.71036291 ], [ -74.01098452, 40.710358 ], [ -74.01099162, 40.71035147 ], [ -74.0109953, 40.71034602 ], [ -74.01104291, 40.7103676 ], [ -74.01069544, 40.71088927 ], [ -74.01063678, 40.71086271 ] ] ] } }, { "type": "Feature", "properties": { "height": 152.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726217, 40.70725367 ], [ -74.00715357, 40.70733491 ], [ -74.00679882, 40.70760396 ], [ -74.00666973, 40.70750597 ], [ -74.00674277, 40.70745061 ], [ -74.00671186, 40.70742711 ], [ -74.00697543, 40.70722759 ], [ -74.0069351, 40.70719702 ], [ -74.00706203, 40.707101 ], [ -74.00711251, 40.70713852 ], [ -74.00726217, 40.70725367 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0077805, 40.71341562 ], [ -74.00772804, 40.71348221 ], [ -74.00771277, 40.71347479 ], [ -74.00757703, 40.71364746 ], [ -74.00742279, 40.71357788 ], [ -74.00747741, 40.71350849 ], [ -74.00737249, 40.71346096 ], [ -74.00741048, 40.71341269 ], [ -74.00733754, 40.71337966 ], [ -74.00730278, 40.71342386 ], [ -74.00717333, 40.71336537 ], [ -74.00730358, 40.71319977 ], [ -74.0077805, 40.71341562 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00911099, 40.70671128 ], [ -74.00909078, 40.70670065 ], [ -74.00906338, 40.70668629 ], [ -74.00903113, 40.7066694 ], [ -74.00898487, 40.70664509 ], [ -74.00900733, 40.7066205 ], [ -74.00889423, 40.70656099 ], [ -74.00891408, 40.70653906 ], [ -74.00887141, 40.70651659 ], [ -74.00895118, 40.70642241 ], [ -74.00897517, 40.70639408 ], [ -74.00898191, 40.70638611 ], [ -74.00901263, 40.70634988 ], [ -74.00904919, 40.70630671 ], [ -74.00908863, 40.7062602 ], [ -74.00917262, 40.70631039 ], [ -74.0092885, 40.70637957 ], [ -74.00936863, 40.70642738 ], [ -74.00911099, 40.70671128 ] ] ] } }, { "type": "Feature", "properties": { "height": 47.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0064642, 40.71172688 ], [ -74.00623028, 40.71150537 ], [ -74.00646932, 40.71131928 ], [ -74.00679523, 40.71164442 ], [ -74.0064642, 40.71172688 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00613344, 40.70964567 ], [ -74.00606373, 40.70972071 ], [ -74.00604675, 40.70973896 ], [ -74.00575049, 40.70959051 ], [ -74.0057336, 40.70960829 ], [ -74.00542242, 40.70944847 ], [ -74.00545764, 40.70941286 ], [ -74.00552995, 40.70933952 ], [ -74.00556175, 40.70930731 ], [ -74.00587338, 40.70946536 ], [ -74.00585891, 40.7094802 ], [ -74.00615203, 40.70962572 ], [ -74.00613344, 40.70964567 ] ] ] } }, { "type": "Feature", "properties": { "height": 58.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01017819, 40.7093957 ], [ -74.01015762, 40.709385 ], [ -74.01013507, 40.70937288 ], [ -74.01011019, 40.70936042 ], [ -74.00997437, 40.70928988 ], [ -74.01002647, 40.70922791 ], [ -74.00998568, 40.70920666 ], [ -74.00982255, 40.70912189 ], [ -74.00992505, 40.70900762 ], [ -74.0099308, 40.70900102 ], [ -74.00994149, 40.7089891 ], [ -74.00995793, 40.70897078 ], [ -74.0103849, 40.70916492 ], [ -74.01017819, 40.7093957 ] ] ] } }, { "type": "Feature", "properties": { "height": 87.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00890043, 40.71195758 ], [ -74.00872562, 40.71217057 ], [ -74.0083406, 40.7119891 ], [ -74.00851541, 40.71177611 ], [ -74.00890043, 40.71195758 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00484211, 40.70942627 ], [ -74.00478821, 40.70947441 ], [ -74.0048139, 40.7094915 ], [ -74.00472497, 40.709569 ], [ -74.00470045, 40.70955259 ], [ -74.00449455, 40.70973617 ], [ -74.004518, 40.70975156 ], [ -74.0044296, 40.70982946 ], [ -74.0044067, 40.70981441 ], [ -74.00434319, 40.709871 ], [ -74.00420682, 40.70978227 ], [ -74.00427114, 40.70972486 ], [ -74.00425497, 40.70971431 ], [ -74.00434328, 40.70963668 ], [ -74.00435873, 40.7096469 ], [ -74.0045047, 40.7095167 ], [ -74.00449078, 40.70950778 ], [ -74.00457693, 40.70943002 ], [ -74.00459148, 40.70943941 ], [ -74.00464188, 40.7093944 ], [ -74.00466478, 40.70940938 ], [ -74.00472865, 40.70935246 ], [ -74.00474662, 40.70936417 ], [ -74.00478094, 40.7093865 ], [ -74.00484211, 40.70942627 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00976757, 40.7098746 ], [ -74.00962357, 40.7100479 ], [ -74.00938974, 40.70993528 ], [ -74.00932964, 40.7099064 ], [ -74.00925607, 40.709871 ], [ -74.00935264, 40.70975489 ], [ -74.00932452, 40.70974148 ], [ -74.00934249, 40.70971962 ], [ -74.00933647, 40.70971676 ], [ -74.00941894, 40.70961762 ], [ -74.00965735, 40.70973338 ], [ -74.00960498, 40.70979636 ], [ -74.00976757, 40.7098746 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01254355, 40.7065251 ], [ -74.01240584, 40.70668772 ], [ -74.01198524, 40.70649711 ], [ -74.01208172, 40.70631277 ], [ -74.01217793, 40.70635622 ], [ -74.01220623, 40.70631917 ], [ -74.01226911, 40.70634859 ], [ -74.01240251, 40.70640886 ], [ -74.01245048, 40.70643078 ], [ -74.01242192, 40.70646769 ], [ -74.01254355, 40.7065251 ] ] ] } }, { "type": "Feature", "properties": { "height": 39.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00761952, 40.71375321 ], [ -74.00752574, 40.71387291 ], [ -74.00697247, 40.713622 ], [ -74.00707469, 40.71349161 ], [ -74.00720729, 40.7135518 ], [ -74.00726675, 40.71357869 ], [ -74.00738147, 40.71363078 ], [ -74.00742279, 40.71357788 ], [ -74.00757703, 40.71364746 ], [ -74.00763587, 40.71367436 ], [ -74.0075861, 40.71373809 ], [ -74.00761952, 40.71375321 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01075868, 40.70669752 ], [ -74.01063642, 40.70690127 ], [ -74.01063544, 40.7069025 ], [ -74.01052979, 40.70692006 ], [ -74.01052737, 40.70691952 ], [ -74.01022922, 40.7067076 ], [ -74.01023811, 40.70670031 ], [ -74.01020595, 40.7066792 ], [ -74.01034241, 40.70655098 ], [ -74.01075868, 40.70669752 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01376427, 40.70727111 ], [ -74.01361605, 40.70761888 ], [ -74.01330424, 40.70750032 ], [ -74.01352864, 40.70717652 ], [ -74.01376427, 40.70727111 ] ] ] } }, { "type": "Feature", "properties": { "height": 165.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0107029, 40.70829997 ], [ -74.01065403, 40.70834471 ], [ -74.01056995, 40.70842166 ], [ -74.01023227, 40.70820981 ], [ -74.01031995, 40.70812967 ], [ -74.01036325, 40.7080901 ], [ -74.01044688, 40.70801336 ], [ -74.01078438, 40.70822541 ], [ -74.0107029, 40.70829997 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00616299, 40.70744986 ], [ -74.00614934, 40.70746096 ], [ -74.00613362, 40.70747376 ], [ -74.00611952, 40.70748486 ], [ -74.00610739, 40.70749487 ], [ -74.00607253, 40.70752231 ], [ -74.00600453, 40.7075787 ], [ -74.00599339, 40.70758741 ], [ -74.00594129, 40.70762957 ], [ -74.00593033, 40.70763842 ], [ -74.0059182, 40.70764816 ], [ -74.00590455, 40.70765926 ], [ -74.00588874, 40.70767219 ], [ -74.00587392, 40.70768411 ], [ -74.00560783, 40.70742017 ], [ -74.00594569, 40.70728888 ], [ -74.00612275, 40.70741996 ], [ -74.00616299, 40.70744986 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00741183, 40.70662159 ], [ -74.00740375, 40.70662997 ], [ -74.0073918, 40.70664216 ], [ -74.00738228, 40.7066521 ], [ -74.0073662, 40.70666858 ], [ -74.00735901, 40.70667607 ], [ -74.00732991, 40.70670617 ], [ -74.00731347, 40.70672306 ], [ -74.00724385, 40.70679511 ], [ -74.00721465, 40.70677917 ], [ -74.00717099, 40.70682548 ], [ -74.00716381, 40.70683317 ], [ -74.00714889, 40.70684897 ], [ -74.00713919, 40.70685919 ], [ -74.00712662, 40.70687267 ], [ -74.00711907, 40.7068807 ], [ -74.00689377, 40.70671536 ], [ -74.00714854, 40.70645298 ], [ -74.00741183, 40.70662159 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0069801, 40.7089161 ], [ -74.0069545, 40.70890248 ], [ -74.00692899, 40.70888886 ], [ -74.00690338, 40.70887518 ], [ -74.00687778, 40.70886156 ], [ -74.00685227, 40.70884801 ], [ -74.00682667, 40.70883439 ], [ -74.00680125, 40.70882077 ], [ -74.006685, 40.7087605 ], [ -74.00662931, 40.7087317 ], [ -74.00673306, 40.70863739 ], [ -74.00674313, 40.70862819 ], [ -74.00676379, 40.70860981 ], [ -74.00678463, 40.70859149 ], [ -74.00680529, 40.70857317 ], [ -74.00682613, 40.70855486 ], [ -74.00684679, 40.70853647 ], [ -74.00686754, 40.70851822 ], [ -74.00718007, 40.70871447 ], [ -74.0069801, 40.7089161 ] ] ] } }, { "type": "Feature", "properties": { "height": 113.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01356188, 40.70654621 ], [ -74.0134716, 40.70666606 ], [ -74.01341869, 40.70664318 ], [ -74.01339407, 40.7066758 ], [ -74.0133452, 40.70665462 ], [ -74.01331601, 40.70669337 ], [ -74.01304948, 40.70657651 ], [ -74.01307903, 40.7065379 ], [ -74.01303043, 40.70651659 ], [ -74.01305541, 40.70648376 ], [ -74.01300259, 40.70646068 ], [ -74.01302433, 40.70642997 ], [ -74.01297267, 40.70640627 ], [ -74.01304481, 40.70631992 ], [ -74.01307158, 40.7063317 ], [ -74.01313814, 40.70636098 ], [ -74.01315611, 40.70636881 ], [ -74.01322348, 40.7063983 ], [ -74.01322932, 40.70640089 ], [ -74.01325771, 40.70641328 ], [ -74.01342102, 40.70648458 ], [ -74.01344492, 40.706495 ], [ -74.01347321, 40.70650726 ], [ -74.01353951, 40.7065364 ], [ -74.01355703, 40.7065441 ], [ -74.01356188, 40.70654621 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01042963, 40.71113679 ], [ -74.01051039, 40.71117376 ], [ -74.01048263, 40.71120856 ], [ -74.01045478, 40.71124356 ], [ -74.01037394, 40.71120658 ], [ -74.01029192, 40.71130947 ], [ -74.010247, 40.7112887 ], [ -74.0101976, 40.71126569 ], [ -74.01013975, 40.71123886 ], [ -74.01014792, 40.71122899 ], [ -74.00994463, 40.71113658 ], [ -74.00993727, 40.71114571 ], [ -74.00991076, 40.71113359 ], [ -74.0100253, 40.71098991 ], [ -74.01025473, 40.71109498 ], [ -74.01036971, 40.71095069 ], [ -74.01052225, 40.71102048 ], [ -74.01042963, 40.71113679 ] ] ] } }, { "type": "Feature", "properties": { "height": 93.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01342255, 40.70798619 ], [ -74.01328771, 40.70829752 ], [ -74.01315961, 40.70826327 ], [ -74.01323121, 40.7080852 ], [ -74.0131217, 40.70805176 ], [ -74.01300402, 40.7082235 ], [ -74.01287583, 40.70818932 ], [ -74.01307849, 40.70787819 ], [ -74.01342255, 40.70798619 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00483708, 40.70800056 ], [ -74.00477034, 40.70802568 ], [ -74.00468212, 40.70805878 ], [ -74.00466469, 40.70806538 ], [ -74.0045675, 40.70794581 ], [ -74.00453767, 40.70790931 ], [ -74.00447766, 40.70783597 ], [ -74.00462427, 40.70777877 ], [ -74.00470404, 40.70774948 ], [ -74.0048625, 40.70768581 ], [ -74.0048926, 40.70774492 ], [ -74.00490625, 40.70776787 ], [ -74.00491649, 40.70778857 ], [ -74.00492835, 40.70781091 ], [ -74.00499752, 40.70794029 ], [ -74.00483708, 40.70800056 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00759733, 40.7075614 ], [ -74.00748415, 40.70764727 ], [ -74.00736736, 40.707736 ], [ -74.0072752, 40.70767717 ], [ -74.00710443, 40.70759062 ], [ -74.00716605, 40.7075471 ], [ -74.00713847, 40.7075215 ], [ -74.00738758, 40.70732361 ], [ -74.00740743, 40.70731339 ], [ -74.00759733, 40.7075614 ] ] ] } }, { "type": "Feature", "properties": { "height": 124.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00538344, 40.70637208 ], [ -74.00536592, 40.7063825 ], [ -74.00534714, 40.70638972 ], [ -74.00532603, 40.70639347 ], [ -74.00530061, 40.70639428 ], [ -74.00518482, 40.70647866 ], [ -74.00515463, 40.7064984 ], [ -74.00512247, 40.70651557 ], [ -74.00509193, 40.7065253 ], [ -74.00506292, 40.70652959 ], [ -74.00502555, 40.70652959 ], [ -74.00499303, 40.70652612 ], [ -74.00496168, 40.70651679 ], [ -74.00493042, 40.70650126 ], [ -74.00490167, 40.70648138 ], [ -74.0048917, 40.70647001 ], [ -74.00488433, 40.70645741 ], [ -74.00487975, 40.70644406 ], [ -74.00487849, 40.70643718 ], [ -74.00487831, 40.7064235 ], [ -74.00488101, 40.70640988 ], [ -74.00488343, 40.7064032 ], [ -74.00489044, 40.70639047 ], [ -74.00489817, 40.70637726 ], [ -74.00490769, 40.70636718 ], [ -74.00492098, 40.70635506 ], [ -74.00493913, 40.70634668 ], [ -74.00495305, 40.70634137 ], [ -74.00497488, 40.7063362 ], [ -74.00499977, 40.70633511 ], [ -74.00515535, 40.70622656 ], [ -74.00517988, 40.70621491 ], [ -74.00520997, 40.70620626 ], [ -74.00524141, 40.70620177 ], [ -74.00527716, 40.70620306 ], [ -74.00530753, 40.70620831 ], [ -74.00534589, 40.70622029 ], [ -74.00538065, 40.70623609 ], [ -74.00539987, 40.70624937 ], [ -74.00540805, 40.70625836 ], [ -74.00541569, 40.70627171 ], [ -74.00542063, 40.7062858 ], [ -74.00542197, 40.70629302 ], [ -74.0054226, 40.70630759 ], [ -74.00542179, 40.70631481 ], [ -74.00541802, 40.70632911 ], [ -74.00541128, 40.70634266 ], [ -74.00540203, 40.70635547 ], [ -74.00539017, 40.70636691 ], [ -74.00538344, 40.70637208 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00664171, 40.71053682 ], [ -74.0066294, 40.71054696 ], [ -74.00651001, 40.71064549 ], [ -74.0064801, 40.71067008 ], [ -74.00626091, 40.7104771 ], [ -74.00626917, 40.71047172 ], [ -74.00619093, 40.71040267 ], [ -74.0063732, 40.71025042 ], [ -74.00638703, 40.71023932 ], [ -74.00640787, 40.71022188 ], [ -74.0064297, 40.71020377 ], [ -74.0064492, 40.7101875 ], [ -74.00646537, 40.71017401 ], [ -74.00662311, 40.71025477 ], [ -74.00644695, 40.71039736 ], [ -74.00649465, 40.71043161 ], [ -74.00664171, 40.71053682 ] ] ] } }, { "type": "Feature", "properties": { "height": 32.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01257023, 40.70938691 ], [ -74.01248659, 40.7094975 ], [ -74.01234035, 40.70943349 ], [ -74.01208909, 40.70932358 ], [ -74.01227441, 40.70907837 ], [ -74.01252801, 40.70918937 ], [ -74.0125157, 40.70920571 ], [ -74.01248129, 40.7092512 ], [ -74.01243602, 40.70931119 ], [ -74.01257984, 40.70937411 ], [ -74.01257023, 40.70938691 ] ] ] } }, { "type": "Feature", "properties": { "height": 417.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01339838, 40.7129895 ], [ -74.0133929, 40.71303867 ], [ -74.01337584, 40.7130736 ], [ -74.01335194, 40.71310151 ], [ -74.01329939, 40.71313699 ], [ -74.01323588, 40.71315728 ], [ -74.01320489, 40.71316109 ], [ -74.01316213, 40.71316068 ], [ -74.01312107, 40.71315401 ], [ -74.01308092, 40.71314046 ], [ -74.0130387, 40.71311656 ], [ -74.01300582, 40.71308578 ], [ -74.01298812, 40.7130593 ], [ -74.01297402, 40.71298978 ], [ -74.01299154, 40.71293571 ], [ -74.01303142, 40.71288989 ], [ -74.01308047, 40.71286061 ], [ -74.01314578, 40.71284222 ], [ -74.01324423, 40.71284529 ], [ -74.01331763, 40.71287368 ], [ -74.01335347, 40.71290099 ], [ -74.01339057, 40.7129558 ], [ -74.01339838, 40.7129895 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01418773, 40.70971131 ], [ -74.01411183, 40.70990021 ], [ -74.01410904, 40.70990729 ], [ -74.01405811, 40.70989578 ], [ -74.01402083, 40.70998526 ], [ -74.01401508, 40.70999942 ], [ -74.0139742, 40.71010136 ], [ -74.01394294, 40.71008828 ], [ -74.01381394, 40.71003422 ], [ -74.01378179, 40.71002067 ], [ -74.01381314, 40.70994079 ], [ -74.01382347, 40.70991376 ], [ -74.0138347, 40.70988591 ], [ -74.01388168, 40.70976552 ], [ -74.0138947, 40.70973222 ], [ -74.01390719, 40.70970055 ], [ -74.01393881, 40.7096183 ], [ -74.0139681, 40.70961019 ], [ -74.01406502, 40.7096548 ], [ -74.01410042, 40.70967107 ], [ -74.01413249, 40.70968591 ], [ -74.01418773, 40.70971131 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00943762, 40.71372802 ], [ -74.0091675, 40.71360607 ], [ -74.00933144, 40.71339587 ], [ -74.00972823, 40.71357502 ], [ -74.00959788, 40.71374211 ], [ -74.00947113, 40.71368498 ], [ -74.00943762, 40.71372802 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01245399, 40.70801826 ], [ -74.01241805, 40.70806232 ], [ -74.01233199, 40.70816719 ], [ -74.01229489, 40.7082124 ], [ -74.01212044, 40.70813021 ], [ -74.0119715, 40.70806 ], [ -74.01190529, 40.70802882 ], [ -74.01194141, 40.70798469 ], [ -74.01202702, 40.70788037 ], [ -74.01206142, 40.70783842 ], [ -74.01206439, 40.70783481 ], [ -74.01213068, 40.707866 ], [ -74.01213868, 40.70786981 ], [ -74.01229642, 40.7079441 ], [ -74.01245399, 40.70801826 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00958548, 40.71217908 ], [ -74.0096551, 40.71221272 ], [ -74.00982174, 40.71229286 ], [ -74.00958827, 40.7125734 ], [ -74.00932183, 40.71244498 ], [ -74.00955512, 40.71216451 ], [ -74.00958548, 40.71217908 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00646537, 40.71017401 ], [ -74.0064492, 40.7101875 ], [ -74.0064297, 40.71020377 ], [ -74.00640787, 40.71022188 ], [ -74.00638703, 40.71023932 ], [ -74.0063732, 40.71025042 ], [ -74.00619093, 40.71040267 ], [ -74.00618698, 40.71040601 ], [ -74.00613542, 40.71035957 ], [ -74.00617108, 40.71031939 ], [ -74.0061099, 40.71028167 ], [ -74.00606562, 40.71025477 ], [ -74.0059686, 40.71019437 ], [ -74.00594659, 40.71018076 ], [ -74.00592763, 40.71016911 ], [ -74.00610685, 40.70998996 ], [ -74.00646537, 40.71017401 ] ] ] } }, { "type": "Feature", "properties": { "height": 41.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00755359, 40.70585161 ], [ -74.00741821, 40.70598672 ], [ -74.00708952, 40.70580081 ], [ -74.0070976, 40.70579236 ], [ -74.00707631, 40.70578038 ], [ -74.00692647, 40.70569621 ], [ -74.00706679, 40.70559052 ], [ -74.0070738, 40.7055959 ], [ -74.00709544, 40.70557956 ], [ -74.00711305, 40.70558997 ], [ -74.00712374, 40.70559651 ], [ -74.00716174, 40.70561946 ], [ -74.00726657, 40.70568116 ], [ -74.00731248, 40.7057086 ], [ -74.00731922, 40.70571262 ], [ -74.00735623, 40.70573462 ], [ -74.00747274, 40.70580367 ], [ -74.00753544, 40.70584078 ], [ -74.00755359, 40.70585161 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.009383, 40.7114462 ], [ -74.00936109, 40.71143537 ], [ -74.00930943, 40.7114957 ], [ -74.00896196, 40.71132459 ], [ -74.00897023, 40.71131499 ], [ -74.00891929, 40.71128986 ], [ -74.00905269, 40.7111342 ], [ -74.00910309, 40.71115912 ], [ -74.00911099, 40.71114986 ], [ -74.00945864, 40.71132098 ], [ -74.00940762, 40.71138056 ], [ -74.0094299, 40.71139145 ], [ -74.00946969, 40.71141107 ], [ -74.0094228, 40.71146581 ], [ -74.009383, 40.7114462 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00708395, 40.7080724 ], [ -74.00707092, 40.70809071 ], [ -74.0070561, 40.70811148 ], [ -74.00704352, 40.70812926 ], [ -74.00701576, 40.70816828 ], [ -74.00691255, 40.70831216 ], [ -74.00689997, 40.70833211 ], [ -74.00688704, 40.7083505 ], [ -74.00687949, 40.70836106 ], [ -74.0066179, 40.70819817 ], [ -74.00678921, 40.70801261 ], [ -74.00684571, 40.70792476 ], [ -74.00708395, 40.7080724 ] ] ] } }, { "type": "Feature", "properties": { "height": 173.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00931913, 40.71240119 ], [ -74.00926613, 40.7123758 ], [ -74.00926218, 40.71236347 ], [ -74.00924493, 40.71236572 ], [ -74.0091843, 40.71233651 ], [ -74.00918061, 40.71232411 ], [ -74.00916319, 40.71232629 ], [ -74.00910237, 40.71229729 ], [ -74.00909869, 40.71228489 ], [ -74.00908117, 40.71228707 ], [ -74.00902044, 40.71225807 ], [ -74.00901667, 40.71224567 ], [ -74.00899897, 40.71224792 ], [ -74.00893825, 40.71221891 ], [ -74.0089343, 40.71220659 ], [ -74.00891741, 40.71220877 ], [ -74.00885659, 40.71217976 ], [ -74.00885291, 40.71216737 ], [ -74.00897238, 40.71202322 ], [ -74.00898981, 40.71202097 ], [ -74.00905072, 40.71204991 ], [ -74.0090544, 40.7120623 ], [ -74.00907147, 40.71206012 ], [ -74.00913228, 40.71208899 ], [ -74.00913615, 40.71210139 ], [ -74.00915357, 40.71209927 ], [ -74.00921448, 40.71212821 ], [ -74.00921825, 40.71214061 ], [ -74.00923559, 40.7121385 ], [ -74.0092965, 40.71216737 ], [ -74.00930018, 40.71217976 ], [ -74.00928069, 40.712204 ], [ -74.00935237, 40.71223832 ], [ -74.00935615, 40.71225071 ], [ -74.00937357, 40.71224846 ], [ -74.00942352, 40.7122723 ], [ -74.00943439, 40.71227747 ], [ -74.00943825, 40.7122898 ], [ -74.00934438, 40.71240256 ], [ -74.00932695, 40.7124048 ], [ -74.00931913, 40.71240119 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00412283, 40.71285829 ], [ -74.00394038, 40.7130497 ], [ -74.0038422, 40.7131536 ], [ -74.00367538, 40.7133369 ], [ -74.00357567, 40.71328298 ], [ -74.00358932, 40.71319507 ], [ -74.00369173, 40.71308306 ], [ -74.00379081, 40.71297486 ], [ -74.00392017, 40.71284106 ], [ -74.00402321, 40.71280436 ], [ -74.00412283, 40.71285829 ] ] ] } }, { "type": "Feature", "properties": { "height": 93.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00888399, 40.7119605 ], [ -74.00872184, 40.71215817 ], [ -74.00835704, 40.71198617 ], [ -74.00851918, 40.7117885 ], [ -74.00888399, 40.7119605 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00889495, 40.70994821 ], [ -74.00887914, 40.7099664 ], [ -74.00881752, 40.71003721 ], [ -74.00875239, 40.71011212 ], [ -74.00869175, 40.71018191 ], [ -74.00864585, 40.71023469 ], [ -74.00848774, 40.71015508 ], [ -74.00841534, 40.71011859 ], [ -74.0084899, 40.71003285 ], [ -74.00858198, 40.7099269 ], [ -74.00862168, 40.70988121 ], [ -74.00867513, 40.70981986 ], [ -74.00868852, 40.70980447 ], [ -74.00874008, 40.70984042 ], [ -74.0088433, 40.70991226 ], [ -74.00889495, 40.70994821 ] ] ] } }, { "type": "Feature", "properties": { "height": 51.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0066921, 40.70844488 ], [ -74.00667494, 40.7084602 ], [ -74.00665419, 40.70847886 ], [ -74.00663344, 40.70849759 ], [ -74.00663039, 40.70850031 ], [ -74.00661305, 40.70851638 ], [ -74.00659248, 40.70853531 ], [ -74.00658251, 40.70854457 ], [ -74.00652394, 40.70859878 ], [ -74.00649555, 40.70862561 ], [ -74.00647094, 40.70864726 ], [ -74.00644255, 40.70867048 ], [ -74.00646555, 40.70868751 ], [ -74.00637401, 40.70876159 ], [ -74.00617054, 40.70862091 ], [ -74.00626154, 40.70854348 ], [ -74.00643815, 40.70839286 ], [ -74.00651531, 40.70832701 ], [ -74.00663021, 40.70840341 ], [ -74.0066921, 40.70844488 ] ] ] } }, { "type": "Feature", "properties": { "height": 165.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01107193, 40.70748752 ], [ -74.01088804, 40.70768159 ], [ -74.01055288, 40.70751836 ], [ -74.01076021, 40.70730972 ], [ -74.01107193, 40.70748752 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00582702, 40.7131822 ], [ -74.00548405, 40.71360947 ], [ -74.00540526, 40.71357318 ], [ -74.00531705, 40.71353246 ], [ -74.00565994, 40.71310519 ], [ -74.00582702, 40.7131822 ] ] ] } }, { "type": "Feature", "properties": { "height": 145.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01319707, 40.71372516 ], [ -74.01300564, 40.71396858 ], [ -74.01270965, 40.71383471 ], [ -74.01290117, 40.71359136 ], [ -74.01319707, 40.71372516 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00991822, 40.71418687 ], [ -74.01008378, 40.7139745 ], [ -74.0100933, 40.71396231 ], [ -74.01002332, 40.71393072 ], [ -74.0101516, 40.71376608 ], [ -74.01037762, 40.71386808 ], [ -74.01007417, 40.71425728 ], [ -74.00991822, 40.71418687 ] ] ] } }, { "type": "Feature", "properties": { "height": 77.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01015762, 40.709385 ], [ -74.01013507, 40.70937288 ], [ -74.01011019, 40.70936042 ], [ -74.00997437, 40.70928988 ], [ -74.01002647, 40.70922791 ], [ -74.00998568, 40.70920666 ], [ -74.00982255, 40.70912189 ], [ -74.00992505, 40.70900762 ], [ -74.0099308, 40.70900102 ], [ -74.00994149, 40.7089891 ], [ -74.01034735, 40.70917296 ], [ -74.01015762, 40.709385 ] ] ] } }, { "type": "Feature", "properties": { "height": 42.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00751343, 40.70896152 ], [ -74.00749484, 40.70898059 ], [ -74.00738326, 40.70909458 ], [ -74.00736638, 40.70911181 ], [ -74.00732119, 40.7090862 ], [ -74.00722741, 40.70918208 ], [ -74.00713991, 40.7091323 ], [ -74.00709527, 40.70910752 ], [ -74.00708125, 40.70909948 ], [ -74.00705412, 40.7090843 ], [ -74.00703571, 40.70907381 ], [ -74.00701451, 40.70906162 ], [ -74.00728014, 40.70878979 ], [ -74.00751343, 40.70896152 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0079457, 40.70739497 ], [ -74.00785263, 40.70733532 ], [ -74.00793519, 40.70726082 ], [ -74.0080217, 40.70731632 ], [ -74.008042, 40.707298 ], [ -74.00802763, 40.70728867 ], [ -74.00802799, 40.70728057 ], [ -74.00805431, 40.7072568 ], [ -74.00806455, 40.70725551 ], [ -74.00807802, 40.70724332 ], [ -74.00808844, 40.70724462 ], [ -74.00810533, 40.70725537 ], [ -74.00813039, 40.70723277 ], [ -74.00814117, 40.70723127 ], [ -74.00816237, 40.70724489 ], [ -74.00815941, 40.70726232 ], [ -74.00816651, 40.70725592 ], [ -74.0081807, 40.70725667 ], [ -74.00822121, 40.70728268 ], [ -74.00821573, 40.70728758 ], [ -74.00822984, 40.70729657 ], [ -74.00823523, 40.70729167 ], [ -74.00827583, 40.70731768 ], [ -74.00828374, 40.7073187 ], [ -74.0083538, 40.70736372 ], [ -74.0083574, 40.70737012 ], [ -74.00837824, 40.7073834 ], [ -74.00837321, 40.70738796 ], [ -74.00838066, 40.70739279 ], [ -74.00840752, 40.70740539 ], [ -74.00840923, 40.70741499 ], [ -74.00824978, 40.70758081 ], [ -74.00823559, 40.70758108 ], [ -74.0081427, 40.7075215 ], [ -74.00813938, 40.70751067 ], [ -74.00813749, 40.70750951 ], [ -74.00810839, 40.70749079 ], [ -74.00810461, 40.70749426 ], [ -74.00804002, 40.70745286 ], [ -74.00804389, 40.70744938 ], [ -74.00800741, 40.70742596 ], [ -74.00799475, 40.7074265 ], [ -74.0079457, 40.70739497 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01454589, 40.7091859 ], [ -74.01455541, 40.7091624 ], [ -74.01456107, 40.70916376 ], [ -74.01460455, 40.7090559 ], [ -74.01459764, 40.70905427 ], [ -74.01460725, 40.70903077 ], [ -74.01461291, 40.70903207 ], [ -74.01462333, 40.70900776 ], [ -74.01461677, 40.70900578 ], [ -74.01442794, 40.70895941 ], [ -74.01442237, 40.70895798 ], [ -74.01439722, 40.70902199 ], [ -74.01440378, 40.70902369 ], [ -74.01439489, 40.70904732 ], [ -74.01436021, 40.70903922 ], [ -74.01436308, 40.70903166 ], [ -74.01429284, 40.70901647 ], [ -74.01428978, 40.70902376 ], [ -74.01425565, 40.70901579 ], [ -74.01426481, 40.70899216 ], [ -74.01429508, 40.70899931 ], [ -74.01434045, 40.70888417 ], [ -74.01430981, 40.70887702 ], [ -74.01431898, 40.70885345 ], [ -74.0143568, 40.7088621 ], [ -74.01436767, 40.7088367 ], [ -74.01439075, 40.70878039 ], [ -74.01458138, 40.70882499 ], [ -74.01455227, 40.70889649 ], [ -74.0147499, 40.70894116 ], [ -74.01471873, 40.70902049 ], [ -74.01470355, 40.70905788 ], [ -74.01477029, 40.70907347 ], [ -74.01477182, 40.70906966 ], [ -74.01480488, 40.70907749 ], [ -74.01479526, 40.70910098 ], [ -74.01479221, 40.7091003 ], [ -74.01474855, 40.70920789 ], [ -74.01475188, 40.70920871 ], [ -74.01474235, 40.70923227 ], [ -74.01470948, 40.70922457 ], [ -74.01471154, 40.70921967 ], [ -74.01458048, 40.70918916 ], [ -74.01457868, 40.70919352 ], [ -74.01454589, 40.7091859 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01336811, 40.71371596 ], [ -74.01333083, 40.71387829 ], [ -74.01315755, 40.71379651 ], [ -74.01322492, 40.71371079 ], [ -74.01316931, 40.71368498 ], [ -74.01321118, 40.71363167 ], [ -74.012998, 40.71353532 ], [ -74.01295605, 40.71358857 ], [ -74.01290045, 40.71356412 ], [ -74.01282634, 40.71365809 ], [ -74.01257912, 40.71354111 ], [ -74.01262422, 40.713364 ], [ -74.01293943, 40.71351421 ], [ -74.0129556, 40.71349351 ], [ -74.01328169, 40.71364188 ], [ -74.01326364, 40.7136649 ], [ -74.01336811, 40.71371596 ] ] ] } }, { "type": "Feature", "properties": { "height": 61.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00775571, 40.70814737 ], [ -74.00761817, 40.70827689 ], [ -74.00719147, 40.70801458 ], [ -74.00720324, 40.7080013 ], [ -74.00730035, 40.70789092 ], [ -74.00732245, 40.70786579 ], [ -74.0074739, 40.70796426 ], [ -74.00775571, 40.70814737 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00736395, 40.71106549 ], [ -74.00727879, 40.71099597 ], [ -74.00714117, 40.7108877 ], [ -74.00710928, 40.71086087 ], [ -74.00730475, 40.71071808 ], [ -74.00733592, 40.71074539 ], [ -74.00747364, 40.71085359 ], [ -74.00758853, 40.71076977 ], [ -74.00770414, 40.7108416 ], [ -74.00736395, 40.71106549 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01130809, 40.7056292 ], [ -74.01130118, 40.70567156 ], [ -74.01128959, 40.70571296 ], [ -74.01127872, 40.70575532 ], [ -74.01126947, 40.7057861 ], [ -74.01125976, 40.7058181 ], [ -74.01124539, 40.70585678 ], [ -74.01123111, 40.70589526 ], [ -74.01122168, 40.70591828 ], [ -74.01101938, 40.70588886 ], [ -74.0109556, 40.7058796 ], [ -74.01095748, 40.70584419 ], [ -74.01092011, 40.70583949 ], [ -74.01092371, 40.70570969 ], [ -74.01092559, 40.70564289 ], [ -74.01084528, 40.70564146 ], [ -74.01084124, 40.7056213 ], [ -74.01130809, 40.7056292 ] ] ] } }, { "type": "Feature", "properties": { "height": 104.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0094078, 40.7076901 ], [ -74.00943187, 40.70766457 ], [ -74.0094458, 40.70764986 ], [ -74.0095058, 40.70758646 ], [ -74.00969149, 40.70768888 ], [ -74.00971242, 40.70766586 ], [ -74.00975482, 40.70761908 ], [ -74.00977341, 40.70759858 ], [ -74.00997149, 40.70771598 ], [ -74.00977512, 40.7079296 ], [ -74.0094078, 40.7076901 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01007264, 40.70727417 ], [ -74.00984061, 40.7071437 ], [ -74.0099741, 40.70700968 ], [ -74.01006536, 40.70691809 ], [ -74.0100907, 40.70689262 ], [ -74.01010399, 40.70687927 ], [ -74.010331, 40.70701526 ], [ -74.01007264, 40.70727417 ] ] ] } }, { "type": "Feature", "properties": { "height": 286.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00937645, 40.71276671 ], [ -74.00916831, 40.71302178 ], [ -74.00890429, 40.71289806 ], [ -74.00911243, 40.71264299 ], [ -74.00937645, 40.71276671 ] ] ] } }, { "type": "Feature", "properties": { "height": 83.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01307849, 40.70585617 ], [ -74.01297294, 40.70597977 ], [ -74.01237188, 40.70571711 ], [ -74.01242389, 40.70560891 ], [ -74.01307849, 40.70585617 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00842118, 40.70665088 ], [ -74.00811288, 40.70694642 ], [ -74.00793258, 40.70683038 ], [ -74.00795917, 40.70680539 ], [ -74.00797957, 40.70678591 ], [ -74.00799628, 40.70676977 ], [ -74.00801262, 40.70675418 ], [ -74.0080287, 40.70673852 ], [ -74.00804883, 40.70671911 ], [ -74.0080314, 40.70670951 ], [ -74.00810973, 40.70663487 ], [ -74.00812761, 40.70661792 ], [ -74.00814405, 40.70660191 ], [ -74.00816139, 40.70658509 ], [ -74.00817881, 40.70656848 ], [ -74.00819597, 40.706552 ], [ -74.00821421, 40.70653477 ], [ -74.00842118, 40.70665088 ] ] ] } }, { "type": "Feature", "properties": { "height": 42.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00796223, 40.71042405 ], [ -74.00789818, 40.71048861 ], [ -74.00785434, 40.7105328 ], [ -74.0078203, 40.71051298 ], [ -74.00775849, 40.71057577 ], [ -74.00779694, 40.71059776 ], [ -74.00786539, 40.71063712 ], [ -74.00777107, 40.71073231 ], [ -74.00770073, 40.71069296 ], [ -74.00763389, 40.71065557 ], [ -74.00750642, 40.71058441 ], [ -74.00750175, 40.71057992 ], [ -74.00749987, 40.71057427 ], [ -74.00750023, 40.71057141 ], [ -74.00750319, 40.7105661 ], [ -74.00773891, 40.71032477 ], [ -74.00774511, 40.7103211 ], [ -74.00774879, 40.71032001 ], [ -74.00775643, 40.71031967 ], [ -74.00796223, 40.71042405 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01232014, 40.70507147 ], [ -74.01231951, 40.70510388 ], [ -74.01188787, 40.70508597 ], [ -74.01188427, 40.70515339 ], [ -74.01184097, 40.70515196 ], [ -74.01183154, 40.70527549 ], [ -74.01173551, 40.70527148 ], [ -74.01167542, 40.70526868 ], [ -74.01164748, 40.70562968 ], [ -74.01157723, 40.70562988 ], [ -74.01156861, 40.70563002 ], [ -74.01163975, 40.70504546 ], [ -74.01232014, 40.70507147 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726801, 40.71394761 ], [ -74.00711907, 40.71413458 ], [ -74.0070181, 40.71408808 ], [ -74.00699187, 40.71407596 ], [ -74.00705098, 40.71400181 ], [ -74.00687132, 40.71391901 ], [ -74.00681239, 40.71399329 ], [ -74.00669228, 40.71393787 ], [ -74.00684113, 40.71375089 ], [ -74.00726801, 40.71394761 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01067649, 40.71265708 ], [ -74.01056249, 40.71280028 ], [ -74.01033288, 40.71269528 ], [ -74.01029587, 40.71274179 ], [ -74.01015133, 40.7126756 ], [ -74.01033567, 40.71244389 ], [ -74.0104803, 40.71251007 ], [ -74.01044679, 40.71255209 ], [ -74.01067649, 40.71265708 ] ] ] } }, { "type": "Feature", "properties": { "height": 239.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01509548, 40.70795418 ], [ -74.01504814, 40.70793709 ], [ -74.01496487, 40.70790767 ], [ -74.01480955, 40.70785258 ], [ -74.0147976, 40.70784836 ], [ -74.01478278, 40.70783951 ], [ -74.01477595, 40.70782609 ], [ -74.01477874, 40.70781179 ], [ -74.01485698, 40.70765136 ], [ -74.01486893, 40.70764019 ], [ -74.01488653, 40.70763501 ], [ -74.01490531, 40.70763706 ], [ -74.0152013, 40.70774036 ], [ -74.01521613, 40.70774942 ], [ -74.01522304, 40.70776269 ], [ -74.01522008, 40.707777 ], [ -74.01514372, 40.70793988 ], [ -74.01513195, 40.70795119 ], [ -74.01511417, 40.70795636 ], [ -74.01509548, 40.70795418 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01342372, 40.70921048 ], [ -74.01344402, 40.70917936 ], [ -74.01350025, 40.70908791 ], [ -74.013506, 40.70907742 ], [ -74.01351759, 40.70908171 ], [ -74.01355047, 40.70903588 ], [ -74.01387413, 40.70917411 ], [ -74.01386668, 40.70919448 ], [ -74.01391222, 40.70920557 ], [ -74.01385284, 40.70936471 ], [ -74.01384557, 40.70937159 ], [ -74.01384188, 40.70937397 ], [ -74.01383317, 40.70937731 ], [ -74.01382365, 40.70937847 ], [ -74.01381412, 40.70937738 ], [ -74.01380954, 40.70937608 ], [ -74.01342372, 40.70921048 ] ] ] } }, { "type": "Feature", "properties": { "height": 170.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00837501, 40.71240998 ], [ -74.00830224, 40.71250136 ], [ -74.00827017, 40.71254126 ], [ -74.00825858, 40.71254296 ], [ -74.00822597, 40.71254936 ], [ -74.00821178, 40.7125514 ], [ -74.00798675, 40.71244961 ], [ -74.00798415, 40.71244198 ], [ -74.00797534, 40.71241522 ], [ -74.00797121, 40.7124048 ], [ -74.0081083, 40.71223246 ], [ -74.00812204, 40.71223049 ], [ -74.00815483, 40.71222518 ], [ -74.00816821, 40.71222361 ], [ -74.00839297, 40.71232548 ], [ -74.00839594, 40.71233446 ], [ -74.00840465, 40.71236129 ], [ -74.00840663, 40.71236967 ], [ -74.00837501, 40.71240998 ] ] ] } }, { "type": "Feature", "properties": { "height": 112.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01196602, 40.70591739 ], [ -74.0118178, 40.7062143 ], [ -74.01156681, 40.70610759 ], [ -74.01161819, 40.70586046 ], [ -74.01171647, 40.7058766 ], [ -74.01196602, 40.70591739 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00811943, 40.70976879 ], [ -74.00793187, 40.70995768 ], [ -74.00778337, 40.70988169 ], [ -74.00769579, 40.70983681 ], [ -74.00762087, 40.70979841 ], [ -74.00778517, 40.7096328 ], [ -74.00781149, 40.70960638 ], [ -74.00788857, 40.7096471 ], [ -74.00811943, 40.70976879 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01096808, 40.71043951 ], [ -74.01072518, 40.7108047 ], [ -74.01070577, 40.71083377 ], [ -74.0105368, 40.71076779 ], [ -74.01055827, 40.71074049 ], [ -74.01058827, 40.71070228 ], [ -74.01065098, 40.71062262 ], [ -74.01062834, 40.71061186 ], [ -74.01065789, 40.710574 ], [ -74.01066679, 40.71056256 ], [ -74.01070317, 40.71051612 ], [ -74.01071215, 40.71050481 ], [ -74.01074889, 40.71045831 ], [ -74.01075779, 40.71044687 ], [ -74.01078429, 40.71041289 ], [ -74.01079354, 40.71040131 ], [ -74.01080243, 40.71038987 ], [ -74.01081375, 40.71037475 ], [ -74.01083935, 40.71034221 ], [ -74.01099117, 40.71040472 ], [ -74.01096808, 40.71043951 ] ] ] } }, { "type": "Feature", "properties": { "height": 51.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00809904, 40.71355976 ], [ -74.00792028, 40.7137865 ], [ -74.00783449, 40.71374756 ], [ -74.00786952, 40.71370316 ], [ -74.00780008, 40.71367177 ], [ -74.00776523, 40.71371596 ], [ -74.00763111, 40.71365529 ], [ -74.00775723, 40.71349542 ], [ -74.00772804, 40.71348221 ], [ -74.0077805, 40.71341562 ], [ -74.00786243, 40.71345259 ], [ -74.00809904, 40.71355976 ] ] ] } }, { "type": "Feature", "properties": { "height": 102.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0121597, 40.70691659 ], [ -74.01193233, 40.70719688 ], [ -74.01187493, 40.70717107 ], [ -74.01186685, 40.70716739 ], [ -74.01178214, 40.70712742 ], [ -74.0117559, 40.70711509 ], [ -74.01172204, 40.70709916 ], [ -74.01191679, 40.70680491 ], [ -74.0121597, 40.70691659 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00482019, 40.70877957 ], [ -74.00457145, 40.70889676 ], [ -74.0045471, 40.70886932 ], [ -74.00436528, 40.70864529 ], [ -74.00461565, 40.70852762 ], [ -74.00482019, 40.70877957 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01133747, 40.70545521 ], [ -74.01130809, 40.7056292 ], [ -74.01084124, 40.7056213 ], [ -74.0108063, 40.70544908 ], [ -74.01101174, 40.70544969 ], [ -74.01122482, 40.7054533 ], [ -74.01127692, 40.70545419 ], [ -74.01133747, 40.70545521 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01141374, 40.70791319 ], [ -74.0113575, 40.70788479 ], [ -74.01134771, 40.70787989 ], [ -74.011263, 40.70783706 ], [ -74.01119697, 40.70780376 ], [ -74.01117981, 40.70779511 ], [ -74.01113041, 40.70777019 ], [ -74.01105531, 40.70773226 ], [ -74.01113382, 40.70765006 ], [ -74.01116535, 40.70761717 ], [ -74.0111852, 40.70759627 ], [ -74.01122302, 40.70755691 ], [ -74.01155306, 40.70775316 ], [ -74.01141374, 40.70791319 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00718285, 40.71066681 ], [ -74.00698235, 40.71080878 ], [ -74.00676765, 40.71065516 ], [ -74.00673181, 40.71068417 ], [ -74.00668114, 40.71072516 ], [ -74.00665302, 40.71074791 ], [ -74.00658412, 40.71069847 ], [ -74.00693483, 40.71041466 ], [ -74.00703292, 40.71046498 ], [ -74.00684167, 40.71061976 ], [ -74.00690985, 40.71066851 ], [ -74.00702053, 40.71057897 ], [ -74.00706859, 40.71060498 ], [ -74.00718285, 40.71066681 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00644938, 40.70765306 ], [ -74.00637311, 40.70771081 ], [ -74.00642207, 40.70774826 ], [ -74.00630708, 40.70783522 ], [ -74.0062522, 40.7077932 ], [ -74.00612589, 40.70788881 ], [ -74.00596294, 40.7077723 ], [ -74.00628121, 40.70753151 ], [ -74.00644938, 40.70765306 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00940762, 40.71138056 ], [ -74.00936109, 40.71143537 ], [ -74.00930943, 40.7114957 ], [ -74.00896196, 40.71132459 ], [ -74.00897023, 40.71131499 ], [ -74.00910309, 40.71115912 ], [ -74.00911099, 40.71114986 ], [ -74.00945864, 40.71132098 ], [ -74.00940762, 40.71138056 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00714934, 40.7104007 ], [ -74.00739467, 40.71014936 ], [ -74.00740258, 40.7101414 ], [ -74.00762644, 40.71025457 ], [ -74.00737033, 40.71051237 ], [ -74.00714934, 40.7104007 ] ] ] } }, { "type": "Feature", "properties": { "height": 145.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0079457, 40.70739497 ], [ -74.00794372, 40.70738401 ], [ -74.0080217, 40.70731632 ], [ -74.008042, 40.707298 ], [ -74.00802763, 40.70728867 ], [ -74.00802799, 40.70728057 ], [ -74.00805431, 40.7072568 ], [ -74.00806455, 40.70725551 ], [ -74.00807802, 40.70724332 ], [ -74.00808844, 40.70724462 ], [ -74.00810533, 40.70725537 ], [ -74.00813039, 40.70723277 ], [ -74.00814117, 40.70723127 ], [ -74.00816237, 40.70724489 ], [ -74.00815941, 40.70726232 ], [ -74.00816651, 40.70725592 ], [ -74.0081807, 40.70725667 ], [ -74.00822121, 40.70728268 ], [ -74.00821573, 40.70728758 ], [ -74.00822984, 40.70729657 ], [ -74.00823523, 40.70729167 ], [ -74.00827583, 40.70731768 ], [ -74.00828374, 40.7073187 ], [ -74.0083538, 40.70736372 ], [ -74.0083574, 40.70737012 ], [ -74.00837824, 40.7073834 ], [ -74.00837321, 40.70738796 ], [ -74.00838066, 40.70739279 ], [ -74.00840752, 40.70740539 ], [ -74.00840923, 40.70741499 ], [ -74.00824978, 40.70758081 ], [ -74.00823559, 40.70758108 ], [ -74.0081427, 40.7075215 ], [ -74.00813938, 40.70751067 ], [ -74.00813749, 40.70750951 ], [ -74.00810839, 40.70749079 ], [ -74.00810461, 40.70749426 ], [ -74.00804002, 40.70745286 ], [ -74.00804389, 40.70744938 ], [ -74.00800741, 40.70742596 ], [ -74.00799475, 40.7074265 ], [ -74.0079457, 40.70739497 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01083423, 40.70796392 ], [ -74.0109123, 40.70788207 ], [ -74.01098434, 40.70792102 ], [ -74.01107525, 40.70782718 ], [ -74.01113041, 40.70777019 ], [ -74.01117981, 40.70779511 ], [ -74.01119697, 40.70780376 ], [ -74.01113768, 40.70786361 ], [ -74.01111675, 40.70788479 ], [ -74.01120874, 40.7079422 ], [ -74.01126003, 40.70789031 ], [ -74.01135014, 40.70793668 ], [ -74.01116185, 40.7081567 ], [ -74.01083423, 40.70796392 ] ] ] } }, { "type": "Feature", "properties": { "height": 212.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00990124, 40.70696807 ], [ -74.00976811, 40.70710236 ], [ -74.0097347, 40.70713777 ], [ -74.0097267, 40.70714622 ], [ -74.0096693, 40.7071138 ], [ -74.00951362, 40.70702596 ], [ -74.00945568, 40.70699341 ], [ -74.00965843, 40.70678877 ], [ -74.00992783, 40.70694226 ], [ -74.00990124, 40.70696807 ] ] ] } }, { "type": "Feature", "properties": { "height": 96.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00764908, 40.70706232 ], [ -74.00772498, 40.70699667 ], [ -74.00782901, 40.7069089 ], [ -74.0081286, 40.70710277 ], [ -74.00807515, 40.70715221 ], [ -74.00792719, 40.70705047 ], [ -74.00774924, 40.70720682 ], [ -74.00785434, 40.70727689 ], [ -74.00780269, 40.70732327 ], [ -74.00754882, 40.70715588 ], [ -74.00764908, 40.70706232 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0042344, 40.70800471 ], [ -74.00419739, 40.70802221 ], [ -74.0042088, 40.7080361 ], [ -74.00415445, 40.70806177 ], [ -74.00420008, 40.7081172 ], [ -74.00416523, 40.70813382 ], [ -74.00374679, 40.70833171 ], [ -74.00370457, 40.70828036 ], [ -74.00372865, 40.70826906 ], [ -74.00371742, 40.70825537 ], [ -74.0037529, 40.70823862 ], [ -74.00369874, 40.7081727 ], [ -74.00418383, 40.70794329 ], [ -74.0042344, 40.70800471 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01450152, 40.70556042 ], [ -74.014431, 40.70572052 ], [ -74.01441761, 40.70571698 ], [ -74.014264, 40.70567748 ], [ -74.01419779, 40.70576546 ], [ -74.01414785, 40.70577411 ], [ -74.01402523, 40.70572032 ], [ -74.01400915, 40.70567871 ], [ -74.01416357, 40.70548217 ], [ -74.01432212, 40.70551888 ], [ -74.01450152, 40.70556042 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00886378, 40.71196411 ], [ -74.00871699, 40.71214292 ], [ -74.00837725, 40.7119827 ], [ -74.00852395, 40.71180389 ], [ -74.00886378, 40.71196411 ] ] ] } }, { "type": "Feature", "properties": { "height": 184.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00829523, 40.70872516 ], [ -74.00818034, 40.70865788 ], [ -74.00801487, 40.70882016 ], [ -74.00777852, 40.70868179 ], [ -74.00782173, 40.70863929 ], [ -74.00798559, 40.70847852 ], [ -74.00833701, 40.70868417 ], [ -74.00829523, 40.70872516 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00552142, 40.70619598 ], [ -74.00531705, 40.7060431 ], [ -74.00553938, 40.70590711 ], [ -74.00572192, 40.70604242 ], [ -74.00580493, 40.70610432 ], [ -74.00560523, 40.7062587 ], [ -74.00552142, 40.70619598 ] ] ] } }, { "type": "Feature", "properties": { "height": 113.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01311739, 40.70695888 ], [ -74.01310724, 40.70696201 ], [ -74.01309619, 40.70696222 ], [ -74.0130908, 40.70696126 ], [ -74.01267928, 40.70678189 ], [ -74.01267632, 40.70677917 ], [ -74.01267255, 40.70677291 ], [ -74.01267174, 40.70676936 ], [ -74.01267174, 40.70676589 ], [ -74.01267407, 40.70675908 ], [ -74.01268674, 40.70674519 ], [ -74.01275591, 40.70666218 ], [ -74.01276031, 40.70665912 ], [ -74.01277073, 40.70665442 ], [ -74.01277639, 40.70665292 ], [ -74.01285832, 40.70668881 ], [ -74.01287395, 40.70666797 ], [ -74.01314434, 40.70678666 ], [ -74.01312862, 40.70680757 ], [ -74.01319141, 40.70683467 ], [ -74.01319851, 40.70684271 ], [ -74.0131968, 40.70685272 ], [ -74.01311739, 40.70695888 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01111639, 40.71398887 ], [ -74.01115044, 40.71394488 ], [ -74.01118017, 40.71390628 ], [ -74.01122913, 40.71384302 ], [ -74.0113434, 40.7136952 ], [ -74.01138194, 40.71364638 ], [ -74.01144787, 40.71367048 ], [ -74.01140745, 40.71411926 ], [ -74.01111639, 40.71398887 ] ] ] } }, { "type": "Feature", "properties": { "height": 39.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01252801, 40.70918937 ], [ -74.0125157, 40.70920571 ], [ -74.01248129, 40.7092512 ], [ -74.01243602, 40.70931119 ], [ -74.0123894, 40.7093707 ], [ -74.01235418, 40.70941578 ], [ -74.01234035, 40.70943349 ], [ -74.01208909, 40.70932358 ], [ -74.01227441, 40.70907837 ], [ -74.01252801, 40.70918937 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01525457, 40.71366612 ], [ -74.01510608, 40.71387291 ], [ -74.01503368, 40.71397382 ], [ -74.01436165, 40.71369622 ], [ -74.01473804, 40.7131728 ], [ -74.01491627, 40.71324662 ], [ -74.01512144, 40.71333146 ], [ -74.01510105, 40.71336142 ], [ -74.01484225, 40.7132539 ], [ -74.01475771, 40.71321911 ], [ -74.01471118, 40.71328386 ], [ -74.01447385, 40.71361492 ], [ -74.01442561, 40.71368212 ], [ -74.01451122, 40.71371739 ], [ -74.01491761, 40.71388476 ], [ -74.01501445, 40.71392466 ], [ -74.01506045, 40.71386052 ], [ -74.01521289, 40.71364801 ], [ -74.01525457, 40.71366612 ] ] ] } }, { "type": "Feature", "properties": { "height": 83.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0054288, 40.70861948 ], [ -74.00540823, 40.70862799 ], [ -74.00519919, 40.7087157 ], [ -74.00496814, 40.70842071 ], [ -74.00515374, 40.70834281 ], [ -74.0054288, 40.70861948 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01200132, 40.70562471 ], [ -74.01199647, 40.70572651 ], [ -74.01193287, 40.70571977 ], [ -74.01194177, 40.70586836 ], [ -74.01171647, 40.7058766 ], [ -74.01161819, 40.70586046 ], [ -74.0115863, 40.70585522 ], [ -74.01154462, 40.70584841 ], [ -74.0115545, 40.70578167 ], [ -74.01175959, 40.70578086 ], [ -74.01177719, 40.70575648 ], [ -74.01177719, 40.70572978 ], [ -74.01175887, 40.70570697 ], [ -74.01156537, 40.70570908 ], [ -74.01157723, 40.70562988 ], [ -74.01164748, 40.70562968 ], [ -74.01179318, 40.7056275 ], [ -74.01200132, 40.70562471 ] ] ] } }, { "type": "Feature", "properties": { "height": 88.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01013507, 40.70937288 ], [ -74.01011019, 40.70936042 ], [ -74.00997437, 40.70928988 ], [ -74.01002647, 40.70922791 ], [ -74.00998568, 40.70920666 ], [ -74.00982255, 40.70912189 ], [ -74.00992505, 40.70900762 ], [ -74.01030899, 40.70917806 ], [ -74.01013507, 40.70937288 ] ] ] } }, { "type": "Feature", "properties": { "height": 88.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00613362, 40.71139602 ], [ -74.00587535, 40.7115781 ], [ -74.00566847, 40.71138138 ], [ -74.00590931, 40.71121169 ], [ -74.00596168, 40.7112567 ], [ -74.00600004, 40.71128959 ], [ -74.00593051, 40.7113395 ], [ -74.00597677, 40.71137688 ], [ -74.00605825, 40.71131846 ], [ -74.00613362, 40.71139602 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00811943, 40.70976879 ], [ -74.00788857, 40.7096471 ], [ -74.00813093, 40.70940489 ], [ -74.00833539, 40.70955109 ], [ -74.00811943, 40.70976879 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00470341, 40.70563792 ], [ -74.00455788, 40.70573979 ], [ -74.0045524, 40.7057353 ], [ -74.00453498, 40.70574749 ], [ -74.00464008, 40.70583438 ], [ -74.00459615, 40.70586516 ], [ -74.0044791, 40.70576846 ], [ -74.00442933, 40.7058034 ], [ -74.00424877, 40.70565406 ], [ -74.00434822, 40.70559127 ], [ -74.00451755, 40.70548422 ], [ -74.00470341, 40.70563792 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00926847, 40.70952058 ], [ -74.00925203, 40.70953808 ], [ -74.00921825, 40.7095741 ], [ -74.00914459, 40.70965228 ], [ -74.00913211, 40.70966562 ], [ -74.00909474, 40.70964526 ], [ -74.00904712, 40.7096964 ], [ -74.00908782, 40.7097124 ], [ -74.0089519, 40.70984641 ], [ -74.00891687, 40.70980072 ], [ -74.00906779, 40.70963062 ], [ -74.00899709, 40.70959208 ], [ -74.00885039, 40.70975367 ], [ -74.0087858, 40.70970811 ], [ -74.00892675, 40.70955429 ], [ -74.00894723, 40.70953188 ], [ -74.00909447, 40.70937111 ], [ -74.00912213, 40.70939692 ], [ -74.00917909, 40.70944752 ], [ -74.00920828, 40.70947217 ], [ -74.00926847, 40.70952058 ] ] ] } }, { "type": "Feature", "properties": { "height": 152.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01317282, 40.71372979 ], [ -74.01299944, 40.71395006 ], [ -74.01273399, 40.71383008 ], [ -74.01290736, 40.71360981 ], [ -74.01317282, 40.71372979 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00623594, 40.70842731 ], [ -74.00599528, 40.7086333 ], [ -74.00581211, 40.70848438 ], [ -74.00582163, 40.70845816 ], [ -74.00586924, 40.7084284 ], [ -74.0058272, 40.70838932 ], [ -74.00592871, 40.70833858 ], [ -74.00593913, 40.70833348 ], [ -74.00602681, 40.70828758 ], [ -74.0060976, 40.70833756 ], [ -74.00616829, 40.70838387 ], [ -74.00617575, 40.70838829 ], [ -74.00619767, 40.70840191 ], [ -74.00621698, 40.70841472 ], [ -74.00623594, 40.70842731 ] ] ] } }, { "type": "Feature", "properties": { "height": 192.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00848532, 40.70883636 ], [ -74.00841004, 40.70891011 ], [ -74.00834931, 40.70896942 ], [ -74.00833485, 40.70898358 ], [ -74.00827942, 40.7089511 ], [ -74.00829667, 40.70893408 ], [ -74.00818842, 40.70887068 ], [ -74.00813938, 40.70891876 ], [ -74.00812653, 40.70893149 ], [ -74.0079855, 40.70884896 ], [ -74.00801487, 40.70882016 ], [ -74.00818034, 40.70865788 ], [ -74.00829523, 40.70872516 ], [ -74.0083521, 40.70875846 ], [ -74.00844705, 40.70881396 ], [ -74.00848532, 40.70883636 ] ] ] } }, { "type": "Feature", "properties": { "height": 220.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01247725, 40.71025831 ], [ -74.0123107, 40.71070562 ], [ -74.01217614, 40.71064679 ], [ -74.01200618, 40.71057679 ], [ -74.01247725, 40.71025831 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00778517, 40.7096328 ], [ -74.00762087, 40.70979841 ], [ -74.00731895, 40.70963927 ], [ -74.00749232, 40.70946447 ], [ -74.00778517, 40.7096328 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0064642, 40.71172688 ], [ -74.00610658, 40.71181628 ], [ -74.00597444, 40.71169297 ], [ -74.00623028, 40.71150537 ], [ -74.0064642, 40.71172688 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00917621, 40.70863609 ], [ -74.00905584, 40.70863718 ], [ -74.00894382, 40.70854437 ], [ -74.00865977, 40.70830937 ], [ -74.00833189, 40.70803787 ], [ -74.00834473, 40.70794989 ], [ -74.00872517, 40.70826388 ], [ -74.00900957, 40.70849861 ], [ -74.00917621, 40.70863609 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0048131, 40.71090711 ], [ -74.0045613, 40.71105916 ], [ -74.00436358, 40.71087116 ], [ -74.00461547, 40.7107191 ], [ -74.0048131, 40.71090711 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01096808, 40.71043951 ], [ -74.01072518, 40.7108047 ], [ -74.01062699, 40.71076691 ], [ -74.01055827, 40.71074049 ], [ -74.01058827, 40.71070228 ], [ -74.01065098, 40.71062262 ], [ -74.01062834, 40.71061186 ], [ -74.01065789, 40.710574 ], [ -74.01066679, 40.71056256 ], [ -74.01070317, 40.71051612 ], [ -74.01071215, 40.71050481 ], [ -74.01074889, 40.71045831 ], [ -74.01075779, 40.71044687 ], [ -74.01078429, 40.71041289 ], [ -74.01079354, 40.71040131 ], [ -74.01080243, 40.71038987 ], [ -74.01081375, 40.71037475 ], [ -74.01096808, 40.71043951 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00962357, 40.7100479 ], [ -74.00949179, 40.71020861 ], [ -74.00922948, 40.71002107 ], [ -74.00912411, 40.70994569 ], [ -74.00920622, 40.70984696 ], [ -74.00925607, 40.709871 ], [ -74.00932964, 40.7099064 ], [ -74.00938974, 40.70993528 ], [ -74.00962357, 40.7100479 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01006779, 40.70951881 ], [ -74.0099122, 40.70969238 ], [ -74.00958405, 40.70952208 ], [ -74.00967891, 40.70941619 ], [ -74.00970343, 40.70942899 ], [ -74.00978347, 40.70933959 ], [ -74.00988498, 40.70939215 ], [ -74.00980431, 40.70948218 ], [ -74.00989028, 40.70952678 ], [ -74.00995164, 40.70945841 ], [ -74.01006779, 40.70951881 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00941265, 40.71187266 ], [ -74.00925302, 40.71206448 ], [ -74.00925248, 40.71206509 ], [ -74.00922005, 40.71210418 ], [ -74.00900562, 40.71200027 ], [ -74.00899098, 40.71199366 ], [ -74.0090491, 40.71192401 ], [ -74.00914306, 40.71181097 ], [ -74.00918358, 40.71176229 ], [ -74.00941265, 40.71187266 ] ] ] } }, { "type": "Feature", "properties": { "height": 225.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00991014, 40.70694172 ], [ -74.0097223, 40.70713117 ], [ -74.00947239, 40.70698898 ], [ -74.00966031, 40.70679946 ], [ -74.00991014, 40.70694172 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01052171, 40.70610051 ], [ -74.01039199, 40.70631549 ], [ -74.01024072, 40.70626258 ], [ -74.01027467, 40.70620626 ], [ -74.0101022, 40.706146 ], [ -74.01011405, 40.70612652 ], [ -74.0101313, 40.70609778 ], [ -74.01016059, 40.7060493 ], [ -74.01017882, 40.7060192 ], [ -74.010202, 40.70598066 ], [ -74.01052171, 40.70610051 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00905584, 40.70863718 ], [ -74.00891705, 40.70874988 ], [ -74.00833189, 40.70803787 ], [ -74.00865977, 40.70830937 ], [ -74.00863965, 40.70832347 ], [ -74.00892397, 40.70855819 ], [ -74.00894382, 40.70854437 ], [ -74.00905584, 40.70863718 ] ] ] } }, { "type": "Feature", "properties": { "height": 104.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00889684, 40.70556321 ], [ -74.00881437, 40.70573938 ], [ -74.00878814, 40.70578596 ], [ -74.00874547, 40.70579577 ], [ -74.00852898, 40.70569301 ], [ -74.0085367, 40.70568252 ], [ -74.00854542, 40.70567081 ], [ -74.00858054, 40.70562328 ], [ -74.00863615, 40.70554809 ], [ -74.00868358, 40.70556839 ], [ -74.00870199, 40.70553468 ], [ -74.00869894, 40.70551922 ], [ -74.00869633, 40.70550601 ], [ -74.00869103, 40.70547952 ], [ -74.00888264, 40.70546277 ], [ -74.00889684, 40.70556321 ] ] ] } }, { "type": "Feature", "properties": { "height": 53.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01413994, 40.7097472 ], [ -74.01408757, 40.70987637 ], [ -74.01406691, 40.70987168 ], [ -74.01405811, 40.70989578 ], [ -74.01402083, 40.70998526 ], [ -74.01401508, 40.70999942 ], [ -74.01397959, 40.70999118 ], [ -74.01396118, 40.7100398 ], [ -74.01394294, 40.71008828 ], [ -74.01381394, 40.71003422 ], [ -74.01382392, 40.71000902 ], [ -74.01384763, 40.7099491 ], [ -74.01385832, 40.70992179 ], [ -74.01386955, 40.70989401 ], [ -74.01391707, 40.70977369 ], [ -74.01393037, 40.70974087 ], [ -74.01394294, 40.70970961 ], [ -74.01396298, 40.70965909 ], [ -74.01396819, 40.70965357 ], [ -74.01397151, 40.70965112 ], [ -74.01398238, 40.70964826 ], [ -74.01399361, 40.7096501 ], [ -74.01404975, 40.70967577 ], [ -74.01408497, 40.70969198 ], [ -74.01411632, 40.70970641 ], [ -74.01415009, 40.70972187 ], [ -74.01413994, 40.7097472 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00605547, 40.71339321 ], [ -74.00578004, 40.71373646 ], [ -74.00562445, 40.71366476 ], [ -74.00589997, 40.71332151 ], [ -74.00605547, 40.71339321 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00891705, 40.70874988 ], [ -74.00890995, 40.70885516 ], [ -74.00822418, 40.70802289 ], [ -74.00833189, 40.70803787 ], [ -74.00891705, 40.70874988 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00753544, 40.70584078 ], [ -74.00741102, 40.70596057 ], [ -74.00711224, 40.70578406 ], [ -74.00713398, 40.70576111 ], [ -74.00704298, 40.70570806 ], [ -74.00712221, 40.705629 ], [ -74.00713973, 40.70564098 ], [ -74.00716174, 40.70561946 ], [ -74.00726657, 40.70568116 ], [ -74.00731248, 40.7057086 ], [ -74.00731922, 40.70571262 ], [ -74.00735623, 40.70573462 ], [ -74.00747274, 40.70580367 ], [ -74.00753544, 40.70584078 ] ] ] } }, { "type": "Feature", "properties": { "height": 47.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01350025, 40.70908791 ], [ -74.01344402, 40.70917936 ], [ -74.01342372, 40.70921048 ], [ -74.0134177, 40.70922028 ], [ -74.01322645, 40.70913789 ], [ -74.01321818, 40.70912931 ], [ -74.01321252, 40.7091176 ], [ -74.01321531, 40.70910656 ], [ -74.01334134, 40.70883432 ], [ -74.01335158, 40.70882846 ], [ -74.013362, 40.70882676 ], [ -74.0133753, 40.70882628 ], [ -74.01354831, 40.70890378 ], [ -74.01347393, 40.70900939 ], [ -74.01342569, 40.70899877 ], [ -74.01339928, 40.70906087 ], [ -74.01350025, 40.70908791 ] ] ] } }, { "type": "Feature", "properties": { "height": 97.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01362027, 40.70646081 ], [ -74.01359125, 40.70649902 ], [ -74.01355703, 40.7065441 ], [ -74.01353951, 40.7065364 ], [ -74.01347321, 40.70650726 ], [ -74.01344492, 40.706495 ], [ -74.01342102, 40.70648458 ], [ -74.01325771, 40.70641328 ], [ -74.01322932, 40.70640089 ], [ -74.01322348, 40.7063983 ], [ -74.01315611, 40.70636881 ], [ -74.01313814, 40.70636098 ], [ -74.0131721, 40.70631631 ], [ -74.01320183, 40.70627736 ], [ -74.01323552, 40.70623269 ], [ -74.01329759, 40.70625959 ], [ -74.01336479, 40.70628907 ], [ -74.0135361, 40.70636398 ], [ -74.01359224, 40.70638849 ], [ -74.01365458, 40.7064158 ], [ -74.01362027, 40.70646081 ] ] ] } }, { "type": "Feature", "properties": { "height": 66.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01260284, 40.708905 ], [ -74.01246692, 40.7088461 ], [ -74.01242039, 40.70882601 ], [ -74.01262134, 40.70852081 ], [ -74.01278178, 40.70858638 ], [ -74.01280379, 40.70859537 ], [ -74.01260284, 40.708905 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0075835, 40.70673157 ], [ -74.00748442, 40.70680988 ], [ -74.00746555, 40.70679599 ], [ -74.00727825, 40.70699735 ], [ -74.00711907, 40.7068807 ], [ -74.00712662, 40.70687267 ], [ -74.00713919, 40.70685919 ], [ -74.00714889, 40.70684897 ], [ -74.00716381, 40.70683317 ], [ -74.00717099, 40.70682548 ], [ -74.00721465, 40.70677917 ], [ -74.00724385, 40.70679511 ], [ -74.00731347, 40.70672306 ], [ -74.00732991, 40.70670617 ], [ -74.00735901, 40.70667607 ], [ -74.0073662, 40.70666858 ], [ -74.00738228, 40.7066521 ], [ -74.0073918, 40.70664216 ], [ -74.00740375, 40.70662997 ], [ -74.00741183, 40.70662159 ], [ -74.0075835, 40.70673157 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0077107, 40.70680879 ], [ -74.00760919, 40.7069204 ], [ -74.00754334, 40.70699286 ], [ -74.00744489, 40.707101 ], [ -74.00727825, 40.70699735 ], [ -74.00746555, 40.70679599 ], [ -74.00748442, 40.70680988 ], [ -74.0075835, 40.70673157 ], [ -74.0077107, 40.70680879 ] ] ] } }, { "type": "Feature", "properties": { "height": 58.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00629639, 40.7067204 ], [ -74.00631104, 40.70670876 ], [ -74.00634113, 40.70673198 ], [ -74.00639063, 40.70669521 ], [ -74.00636053, 40.70667199 ], [ -74.00634122, 40.70665748 ], [ -74.00618617, 40.7065409 ], [ -74.0061682, 40.70652741 ], [ -74.00613838, 40.70650501 ], [ -74.00607613, 40.70655261 ], [ -74.00593132, 40.70644447 ], [ -74.00605061, 40.70635118 ], [ -74.00624564, 40.70649548 ], [ -74.0064006, 40.70661206 ], [ -74.00656391, 40.70673818 ], [ -74.00644462, 40.70682609 ], [ -74.00629639, 40.7067204 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00469964, 40.70595076 ], [ -74.00455438, 40.7060525 ], [ -74.00448099, 40.70599169 ], [ -74.00433474, 40.70587081 ], [ -74.00427024, 40.70581749 ], [ -74.00414897, 40.70571732 ], [ -74.00424877, 40.70565406 ], [ -74.00442933, 40.7058034 ], [ -74.0044791, 40.70576846 ], [ -74.00459615, 40.70586516 ], [ -74.00463999, 40.70590146 ], [ -74.00469964, 40.70595076 ] ], [ [ -74.00457351, 40.70592788 ], [ -74.00449958, 40.70586537 ], [ -74.00445709, 40.70589451 ], [ -74.00453102, 40.70595689 ], [ -74.00457351, 40.70592788 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00870199, 40.70553468 ], [ -74.00860569, 40.70553441 ], [ -74.00861423, 40.70554476 ], [ -74.00855233, 40.70560707 ], [ -74.00858054, 40.70562328 ], [ -74.00854542, 40.70567081 ], [ -74.0085367, 40.70568252 ], [ -74.00852898, 40.70569301 ], [ -74.00849601, 40.70573748 ], [ -74.00848011, 40.70575906 ], [ -74.0084758, 40.70576492 ], [ -74.00831617, 40.70567292 ], [ -74.00847274, 40.70542409 ], [ -74.0086754, 40.7054008 ], [ -74.00868223, 40.70543498 ], [ -74.00869103, 40.70547952 ], [ -74.00869633, 40.70550601 ], [ -74.00869894, 40.70551922 ], [ -74.00870199, 40.70553468 ] ] ] } }, { "type": "Feature", "properties": { "height": 52.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00799538, 40.70930792 ], [ -74.00796897, 40.70933448 ], [ -74.00791453, 40.70938936 ], [ -74.00788291, 40.70942116 ], [ -74.00785084, 40.70940278 ], [ -74.00779568, 40.70937111 ], [ -74.00773738, 40.70942988 ], [ -74.00772265, 40.70944479 ], [ -74.0077664, 40.70946999 ], [ -74.00772265, 40.70951418 ], [ -74.00767872, 40.70948899 ], [ -74.00763021, 40.70946107 ], [ -74.00757101, 40.70942709 ], [ -74.00754451, 40.7094119 ], [ -74.00779209, 40.70916247 ], [ -74.00799538, 40.70930792 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00505735, 40.70561217 ], [ -74.00491155, 40.70571269 ], [ -74.00457819, 40.70544751 ], [ -74.00472497, 40.70535776 ], [ -74.00505735, 40.70561217 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01186685, 40.70716739 ], [ -74.01178214, 40.70712742 ], [ -74.0117559, 40.70711509 ], [ -74.01176803, 40.70709916 ], [ -74.01174692, 40.70708969 ], [ -74.01192299, 40.70682507 ], [ -74.01213302, 40.7069217 ], [ -74.01192712, 40.70717087 ], [ -74.01188095, 40.7071501 ], [ -74.01186685, 40.70716739 ] ] ] } }, { "type": "Feature", "properties": { "height": 61.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00749484, 40.70898059 ], [ -74.00738326, 40.70909458 ], [ -74.00736638, 40.70911181 ], [ -74.00732119, 40.7090862 ], [ -74.00722741, 40.70918208 ], [ -74.00713991, 40.7091323 ], [ -74.00709527, 40.70910752 ], [ -74.00708125, 40.70909948 ], [ -74.00705412, 40.7090843 ], [ -74.00727538, 40.70886122 ], [ -74.00749484, 40.70898059 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00696474, 40.70701159 ], [ -74.00667297, 40.70723052 ], [ -74.00666398, 40.70722071 ], [ -74.00662823, 40.70724856 ], [ -74.00650372, 40.70711278 ], [ -74.00654648, 40.7070931 ], [ -74.00655547, 40.70710365 ], [ -74.00681634, 40.70689916 ], [ -74.00696474, 40.70701159 ] ] ] } }, { "type": "Feature", "properties": { "height": 95.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01041319, 40.70640967 ], [ -74.01038319, 40.70639748 ], [ -74.01036235, 40.7064158 ], [ -74.01032147, 40.70645162 ], [ -74.01024763, 40.70651638 ], [ -74.01023452, 40.70650767 ], [ -74.01011073, 40.70661601 ], [ -74.01009043, 40.70663228 ], [ -74.00992783, 40.70652231 ], [ -74.00994113, 40.7065078 ], [ -74.00996619, 40.70648049 ], [ -74.01000365, 40.70643977 ], [ -74.01001254, 40.7064301 ], [ -74.01005719, 40.70645959 ], [ -74.01023479, 40.70630412 ], [ -74.01024512, 40.70631086 ], [ -74.01031528, 40.70635731 ], [ -74.01034339, 40.70633265 ], [ -74.0103707, 40.70635077 ], [ -74.01043808, 40.70637699 ], [ -74.01041319, 40.70640967 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00666973, 40.70750597 ], [ -74.00653499, 40.70740328 ], [ -74.00641892, 40.7074931 ], [ -74.0062592, 40.70736991 ], [ -74.00649079, 40.70724965 ], [ -74.0065667, 40.70721036 ], [ -74.00667692, 40.70732511 ], [ -74.00662275, 40.70735541 ], [ -74.00671186, 40.70742711 ], [ -74.00674277, 40.70745061 ], [ -74.00666973, 40.70750597 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0085517, 40.70673259 ], [ -74.0083644, 40.70692667 ], [ -74.00834105, 40.70695098 ], [ -74.00826945, 40.70702521 ], [ -74.00825634, 40.70703869 ], [ -74.00811288, 40.70694642 ], [ -74.00842118, 40.70665088 ], [ -74.00855709, 40.70672701 ], [ -74.0085517, 40.70673259 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01028159, 40.71341459 ], [ -74.01013795, 40.71334936 ], [ -74.00983099, 40.71321019 ], [ -74.00990591, 40.71311527 ], [ -74.01020874, 40.71325261 ], [ -74.01035893, 40.71332077 ], [ -74.01043323, 40.7133544 ], [ -74.01035831, 40.71344932 ], [ -74.01028159, 40.71341459 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01329912, 40.71401386 ], [ -74.01326157, 40.71418068 ], [ -74.01296962, 40.71404416 ], [ -74.01294465, 40.71407589 ], [ -74.01261362, 40.71392446 ], [ -74.01264272, 40.71388796 ], [ -74.01267785, 40.71384676 ], [ -74.01273327, 40.71387196 ], [ -74.01269141, 40.71392527 ], [ -74.01290458, 40.71402169 ], [ -74.01294662, 40.71396851 ], [ -74.01300241, 40.7139935 ], [ -74.01306762, 40.71391077 ], [ -74.01329912, 40.71401386 ] ] ] } }, { "type": "Feature", "properties": { "height": 120.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00943187, 40.70766457 ], [ -74.0094458, 40.70764986 ], [ -74.0095058, 40.70758646 ], [ -74.00969149, 40.70768888 ], [ -74.00971242, 40.70766586 ], [ -74.00975482, 40.70761908 ], [ -74.00992478, 40.70772129 ], [ -74.00976955, 40.70788888 ], [ -74.00943187, 40.70766457 ] ] ] } }, { "type": "Feature", "properties": { "height": 192.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01386668, 40.70919448 ], [ -74.01381412, 40.70933986 ], [ -74.01344402, 40.70917936 ], [ -74.0134504, 40.70916969 ], [ -74.01350025, 40.70908791 ], [ -74.013506, 40.70907742 ], [ -74.01351759, 40.70908171 ], [ -74.01355047, 40.70903588 ], [ -74.01387413, 40.70917411 ], [ -74.01386668, 40.70919448 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00622632, 40.71048602 ], [ -74.00619515, 40.71050747 ], [ -74.00601324, 40.71063371 ], [ -74.00598252, 40.71065278 ], [ -74.00588685, 40.71056446 ], [ -74.00591748, 40.7105454 ], [ -74.00584607, 40.7104786 ], [ -74.00596069, 40.71038708 ], [ -74.00595764, 40.71037796 ], [ -74.00603229, 40.71030339 ], [ -74.00622632, 40.71048602 ] ] ] } }, { "type": "Feature", "properties": { "height": 66.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00775571, 40.70814737 ], [ -74.0074739, 40.70796426 ], [ -74.00753059, 40.70790658 ], [ -74.00766947, 40.70799681 ], [ -74.00768968, 40.70794376 ], [ -74.00765438, 40.70789787 ], [ -74.00766731, 40.70788758 ], [ -74.00776909, 40.70780621 ], [ -74.0078989, 40.7079772 ], [ -74.00790069, 40.7079819 ], [ -74.00790159, 40.7079917 ], [ -74.0078989, 40.7080013 ], [ -74.00789288, 40.70801002 ], [ -74.00775571, 40.70814737 ] ] ] } }, { "type": "Feature", "properties": { "height": 230.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00989657, 40.70694329 ], [ -74.00972041, 40.70712102 ], [ -74.00948604, 40.70698762 ], [ -74.0096622, 40.70680968 ], [ -74.00989657, 40.70694329 ] ] ] } }, { "type": "Feature", "properties": { "height": 195.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00935615, 40.71225071 ], [ -74.00930925, 40.71230709 ], [ -74.00926218, 40.71236347 ], [ -74.00924493, 40.71236572 ], [ -74.0091843, 40.71233651 ], [ -74.00918061, 40.71232411 ], [ -74.00916319, 40.71232629 ], [ -74.00910237, 40.71229729 ], [ -74.00909869, 40.71228489 ], [ -74.00908117, 40.71228707 ], [ -74.00902044, 40.71225807 ], [ -74.00901667, 40.71224567 ], [ -74.00899897, 40.71224792 ], [ -74.00893825, 40.71221891 ], [ -74.0089343, 40.71220659 ], [ -74.00898164, 40.71215028 ], [ -74.00902844, 40.7120939 ], [ -74.00904551, 40.71209178 ], [ -74.00911612, 40.71212549 ], [ -74.00913615, 40.71210139 ], [ -74.00915357, 40.71209927 ], [ -74.00921448, 40.71212821 ], [ -74.00921825, 40.71214061 ], [ -74.00923559, 40.7121385 ], [ -74.0092965, 40.71216737 ], [ -74.00930018, 40.71217976 ], [ -74.00928069, 40.712204 ], [ -74.00935237, 40.71223832 ], [ -74.00935615, 40.71225071 ] ] ] } }, { "type": "Feature", "properties": { "height": 186.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00935615, 40.71225071 ], [ -74.00930925, 40.71230709 ], [ -74.00926218, 40.71236347 ], [ -74.00924493, 40.71236572 ], [ -74.0091843, 40.71233651 ], [ -74.00918061, 40.71232411 ], [ -74.00916319, 40.71232629 ], [ -74.00910237, 40.71229729 ], [ -74.00909869, 40.71228489 ], [ -74.00908117, 40.71228707 ], [ -74.00902044, 40.71225807 ], [ -74.00901667, 40.71224567 ], [ -74.00899897, 40.71224792 ], [ -74.00893825, 40.71221891 ], [ -74.0089343, 40.71220659 ], [ -74.00898164, 40.71215028 ], [ -74.00902844, 40.7120939 ], [ -74.00904551, 40.71209178 ], [ -74.00911612, 40.71212549 ], [ -74.00913615, 40.71210139 ], [ -74.00915357, 40.71209927 ], [ -74.00921448, 40.71212821 ], [ -74.00921825, 40.71214061 ], [ -74.00923559, 40.7121385 ], [ -74.0092965, 40.71216737 ], [ -74.00930018, 40.71217976 ], [ -74.00928069, 40.712204 ], [ -74.00935237, 40.71223832 ], [ -74.00935615, 40.71225071 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00544434, 40.71312439 ], [ -74.005177, 40.71345749 ], [ -74.00503678, 40.71339287 ], [ -74.0053042, 40.71305977 ], [ -74.00544434, 40.71312439 ] ] ] } }, { "type": "Feature", "properties": { "height": 52.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00887914, 40.7099664 ], [ -74.00881752, 40.71003721 ], [ -74.00875239, 40.71011212 ], [ -74.00869175, 40.71018191 ], [ -74.00852601, 40.71009645 ], [ -74.0086454, 40.70995897 ], [ -74.00858198, 40.7099269 ], [ -74.00862168, 40.70988121 ], [ -74.00867513, 40.70981986 ], [ -74.00872571, 40.70985622 ], [ -74.00882695, 40.70992888 ], [ -74.00887914, 40.7099664 ] ] ] } }, { "type": "Feature", "properties": { "height": 32.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00984977, 40.70896717 ], [ -74.00974691, 40.70908198 ], [ -74.00971592, 40.70911657 ], [ -74.00969194, 40.7091434 ], [ -74.00944068, 40.709013 ], [ -74.00960893, 40.70884229 ], [ -74.00984977, 40.70896717 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01126462, 40.70715861 ], [ -74.01116365, 40.70731278 ], [ -74.01115331, 40.70732899 ], [ -74.01087439, 40.70714642 ], [ -74.01096108, 40.70701887 ], [ -74.01127791, 40.70713832 ], [ -74.01126462, 40.70715861 ] ] ] } }, { "type": "Feature", "properties": { "height": 118.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00804254, 40.71306209 ], [ -74.00797319, 40.71315006 ], [ -74.00794938, 40.7131393 ], [ -74.00793007, 40.71316382 ], [ -74.00782272, 40.7131152 ], [ -74.00761287, 40.71302021 ], [ -74.00772328, 40.71288001 ], [ -74.00804038, 40.71302348 ], [ -74.00801855, 40.71305126 ], [ -74.00804254, 40.71306209 ] ] ] } }, { "type": "Feature", "properties": { "height": 109.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01280675, 40.70949042 ], [ -74.01257023, 40.70938691 ], [ -74.01257984, 40.70937411 ], [ -74.01243602, 40.70931119 ], [ -74.01248129, 40.7092512 ], [ -74.0125157, 40.70920571 ], [ -74.01252801, 40.70918937 ], [ -74.0128735, 40.70933659 ], [ -74.01280675, 40.70949042 ] ] ] } }, { "type": "Feature", "properties": { "height": 116.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00834644, 40.7091895 ], [ -74.00848702, 40.7090478 ], [ -74.00834931, 40.70896942 ], [ -74.00841004, 40.70891011 ], [ -74.00847957, 40.70894818 ], [ -74.00851011, 40.70892931 ], [ -74.00861647, 40.70898467 ], [ -74.00868034, 40.70906748 ], [ -74.00848244, 40.70927006 ], [ -74.00834644, 40.7091895 ] ] ] } }, { "type": "Feature", "properties": { "height": 96.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01214802, 40.70541517 ], [ -74.0121323, 40.70563839 ], [ -74.01200132, 40.70562471 ], [ -74.01179318, 40.7056275 ], [ -74.01179552, 40.70559188 ], [ -74.01209744, 40.70560448 ], [ -74.01212044, 40.70528762 ], [ -74.01183154, 40.70527549 ], [ -74.01184097, 40.70515196 ], [ -74.01188427, 40.70515339 ], [ -74.01193027, 40.70515496 ], [ -74.01216608, 40.70516265 ], [ -74.01214802, 40.70541517 ] ] ] } }, { "type": "Feature", "properties": { "height": 47.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00830242, 40.71024837 ], [ -74.00820325, 40.7103625 ], [ -74.00786719, 40.71020207 ], [ -74.00786099, 40.71019819 ], [ -74.00785883, 40.71019567 ], [ -74.00785722, 40.71019288 ], [ -74.00785605, 40.71018688 ], [ -74.00785784, 40.71018089 ], [ -74.00785973, 40.7101783 ], [ -74.00797678, 40.7100622 ], [ -74.00808314, 40.71012301 ], [ -74.00821546, 40.71019866 ], [ -74.00825921, 40.71022372 ], [ -74.00830242, 40.71024837 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0085906, 40.71359531 ], [ -74.00864737, 40.713523 ], [ -74.00869732, 40.71354567 ], [ -74.0089351, 40.71324341 ], [ -74.00904632, 40.71329407 ], [ -74.00875158, 40.71366857 ], [ -74.0085906, 40.71359531 ] ] ] } }, { "type": "Feature", "properties": { "height": 120.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01466941, 40.70939427 ], [ -74.01465423, 40.70943587 ], [ -74.01463698, 40.70947911 ], [ -74.01461991, 40.70952358 ], [ -74.01460338, 40.70956668 ], [ -74.01458695, 40.70961026 ], [ -74.01456979, 40.70965439 ], [ -74.01455389, 40.70969606 ], [ -74.01441375, 40.70963648 ], [ -74.01443495, 40.70958221 ], [ -74.01447178, 40.70959038 ], [ -74.01450583, 40.70949341 ], [ -74.01438976, 40.70946767 ], [ -74.01436955, 40.70952719 ], [ -74.01429221, 40.70951207 ], [ -74.01435266, 40.70935797 ], [ -74.01449711, 40.70939209 ], [ -74.0146395, 40.70939352 ], [ -74.01466941, 40.70939427 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00754011, 40.70930458 ], [ -74.00752214, 40.70929437 ], [ -74.00750678, 40.70928579 ], [ -74.0074784, 40.70926979 ], [ -74.00745809, 40.70925842 ], [ -74.00741201, 40.709232 ], [ -74.00739827, 40.7092243 ], [ -74.00747462, 40.70914626 ], [ -74.00738326, 40.70909458 ], [ -74.00749484, 40.70898059 ], [ -74.00751343, 40.70896152 ], [ -74.007724, 40.70911637 ], [ -74.00754011, 40.70930458 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01246575, 40.70959692 ], [ -74.01238805, 40.70969906 ], [ -74.01238203, 40.7096964 ], [ -74.01233379, 40.7097598 ], [ -74.01237673, 40.70977859 ], [ -74.01229921, 40.7098806 ], [ -74.01208118, 40.70978458 ], [ -74.01216042, 40.7096804 ], [ -74.01220048, 40.70969797 ], [ -74.01221809, 40.70967488 ], [ -74.01224692, 40.70963695 ], [ -74.01224369, 40.70963559 ], [ -74.01232139, 40.70953338 ], [ -74.01246575, 40.70959692 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00862168, 40.70988121 ], [ -74.00858198, 40.7099269 ], [ -74.0084899, 40.71003285 ], [ -74.00819795, 40.7098428 ], [ -74.0083114, 40.70973018 ], [ -74.00846214, 40.70982857 ], [ -74.00850364, 40.7097931 ], [ -74.00862168, 40.70988121 ] ] ] } }, { "type": "Feature", "properties": { "height": 53.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00976793, 40.70918276 ], [ -74.00972805, 40.7092305 ], [ -74.00975051, 40.70924221 ], [ -74.00968529, 40.709315 ], [ -74.00948748, 40.70921238 ], [ -74.00943304, 40.70918406 ], [ -74.00932641, 40.70912876 ], [ -74.00944068, 40.709013 ], [ -74.00969194, 40.7091434 ], [ -74.00976793, 40.70918276 ] ] ] } }, { "type": "Feature", "properties": { "height": 180.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01042963, 40.71113679 ], [ -74.01037394, 40.71120658 ], [ -74.01029192, 40.71130947 ], [ -74.010247, 40.7112887 ], [ -74.0101976, 40.71126569 ], [ -74.01013975, 40.71123886 ], [ -74.01014792, 40.71122899 ], [ -74.01025473, 40.71109498 ], [ -74.01036971, 40.71095069 ], [ -74.01052225, 40.71102048 ], [ -74.01042963, 40.71113679 ] ] ] } }, { "type": "Feature", "properties": { "height": 194.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0083653, 40.71237716 ], [ -74.00825957, 40.71251096 ], [ -74.00820253, 40.71252117 ], [ -74.008027, 40.71244028 ], [ -74.0080128, 40.71240017 ], [ -74.00811997, 40.71226487 ], [ -74.00817684, 40.71225446 ], [ -74.00835102, 40.71233337 ], [ -74.0083653, 40.71237716 ] ] ] } }, { "type": "Feature", "properties": { "height": 94.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00548773, 40.70797127 ], [ -74.0054694, 40.70793947 ], [ -74.00543365, 40.70787778 ], [ -74.00547291, 40.70785476 ], [ -74.00542152, 40.70779947 ], [ -74.00537634, 40.70775078 ], [ -74.00535074, 40.70769841 ], [ -74.00532307, 40.70764189 ], [ -74.0054191, 40.70760519 ], [ -74.005526, 40.70771128 ], [ -74.00554064, 40.70770291 ], [ -74.0056355, 40.70779817 ], [ -74.00562158, 40.70780621 ], [ -74.00569524, 40.70788016 ], [ -74.00548773, 40.70797127 ] ] ] } }, { "type": "Feature", "properties": { "height": 32.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00572192, 40.70604242 ], [ -74.00565697, 40.70609206 ], [ -74.00564673, 40.7061001 ], [ -74.00566021, 40.70611018 ], [ -74.00560128, 40.70615526 ], [ -74.0055878, 40.70614518 ], [ -74.00557999, 40.70615117 ], [ -74.00552142, 40.70619598 ], [ -74.00531705, 40.7060431 ], [ -74.00553938, 40.70590711 ], [ -74.00572192, 40.70604242 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00664934, 40.7108636 ], [ -74.00653274, 40.71094449 ], [ -74.0064748, 40.71098467 ], [ -74.00642728, 40.71094551 ], [ -74.0063485, 40.71100019 ], [ -74.00623405, 40.71089179 ], [ -74.00634023, 40.71081811 ], [ -74.00638874, 40.71078447 ], [ -74.0064792, 40.71072169 ], [ -74.00658179, 40.71080728 ], [ -74.00664934, 40.7108636 ] ] ] } }, { "type": "Feature", "properties": { "height": 150.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00882731, 40.71197051 ], [ -74.00870855, 40.71211528 ], [ -74.00841372, 40.71197616 ], [ -74.00853239, 40.71183147 ], [ -74.00882731, 40.71197051 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00863255, 40.71112501 ], [ -74.00859015, 40.71117546 ], [ -74.00852107, 40.71113958 ], [ -74.0083008, 40.71102586 ], [ -74.00824161, 40.71099509 ], [ -74.00825948, 40.71097466 ], [ -74.00829344, 40.71093612 ], [ -74.00832668, 40.71095266 ], [ -74.00830341, 40.71098058 ], [ -74.00853095, 40.71109736 ], [ -74.0086922, 40.71091201 ], [ -74.00850562, 40.71081532 ], [ -74.00852008, 40.71079836 ], [ -74.0085429, 40.7107716 ], [ -74.0088203, 40.71090977 ], [ -74.00863255, 40.71112501 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00867352, 40.7071772 ], [ -74.00852368, 40.70707526 ], [ -74.0085606, 40.70703706 ], [ -74.00873712, 40.70685449 ], [ -74.00874394, 40.7068585 ], [ -74.00875194, 40.70685061 ], [ -74.00890887, 40.70694308 ], [ -74.00867352, 40.7071772 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00637527, 40.7106235 ], [ -74.00613029, 40.7107936 ], [ -74.00598252, 40.71065278 ], [ -74.00601324, 40.71063371 ], [ -74.00619515, 40.71050747 ], [ -74.00622632, 40.71048602 ], [ -74.00637527, 40.7106235 ] ] ] } }, { "type": "Feature", "properties": { "height": 108.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01360239, 40.70645346 ], [ -74.01357329, 40.70649166 ], [ -74.01353951, 40.7065364 ], [ -74.01347321, 40.70650726 ], [ -74.01344492, 40.706495 ], [ -74.01342102, 40.70648458 ], [ -74.01325771, 40.70641328 ], [ -74.01322932, 40.70640089 ], [ -74.01322348, 40.7063983 ], [ -74.01315611, 40.70636881 ], [ -74.01319033, 40.7063238 ], [ -74.01321971, 40.70628519 ], [ -74.01324307, 40.70625407 ], [ -74.01328744, 40.70627327 ], [ -74.01358218, 40.70640239 ], [ -74.01362629, 40.70642132 ], [ -74.01360239, 40.70645346 ] ] ] } }, { "type": "Feature", "properties": { "height": 52.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00971808, 40.71201981 ], [ -74.00960381, 40.71215722 ], [ -74.00949493, 40.71210472 ], [ -74.00942567, 40.71218786 ], [ -74.00930422, 40.71212937 ], [ -74.00932812, 40.7121007 ], [ -74.00948775, 40.71190882 ], [ -74.00971808, 40.71201981 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01232139, 40.70953338 ], [ -74.01224369, 40.70963559 ], [ -74.01224692, 40.70963695 ], [ -74.01221809, 40.70967488 ], [ -74.01217335, 40.70965507 ], [ -74.01216311, 40.70966848 ], [ -74.01216787, 40.70967059 ], [ -74.01216042, 40.7096804 ], [ -74.01208118, 40.70978458 ], [ -74.011937, 40.70972112 ], [ -74.01214029, 40.70945358 ], [ -74.01232139, 40.70953338 ] ] ] } }, { "type": "Feature", "properties": { "height": 38.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01373408, 40.70879707 ], [ -74.01372843, 40.70880477 ], [ -74.01368414, 40.70886551 ], [ -74.0133815, 40.70873517 ], [ -74.01343845, 40.70860307 ], [ -74.0135202, 40.7086235 ], [ -74.01365665, 40.70865748 ], [ -74.01372618, 40.70867491 ], [ -74.0137101, 40.70869636 ], [ -74.01378789, 40.70872346 ], [ -74.01373408, 40.70879707 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00491155, 40.70571269 ], [ -74.00505735, 40.70561217 ], [ -74.00532639, 40.70581817 ], [ -74.00517601, 40.70592318 ], [ -74.00491155, 40.70571269 ] ] ] } }, { "type": "Feature", "properties": { "height": 83.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0069598, 40.7059445 ], [ -74.00663497, 40.70626912 ], [ -74.0064969, 40.70616377 ], [ -74.00688272, 40.7059005 ], [ -74.0069598, 40.7059445 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01500987, 40.70826606 ], [ -74.01482383, 40.70820008 ], [ -74.01457473, 40.70811176 ], [ -74.01474702, 40.70783038 ], [ -74.0147976, 40.70784836 ], [ -74.01480955, 40.70785258 ], [ -74.01473418, 40.70797822 ], [ -74.01466797, 40.70808867 ], [ -74.01490791, 40.70817189 ], [ -74.0149875, 40.7081996 ], [ -74.01512935, 40.70796589 ], [ -74.01518217, 40.70798469 ], [ -74.01500987, 40.70826606 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00624384, 40.70676147 ], [ -74.00627573, 40.70673681 ], [ -74.00644731, 40.70686749 ], [ -74.00660523, 40.70674778 ], [ -74.0060463, 40.70632659 ], [ -74.00589278, 40.70644468 ], [ -74.00608331, 40.70659218 ], [ -74.00605789, 40.70661478 ], [ -74.00583673, 40.70644011 ], [ -74.00605214, 40.70629166 ], [ -74.00665365, 40.70674396 ], [ -74.00645468, 40.70692796 ], [ -74.00624384, 40.70676147 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01241805, 40.70806232 ], [ -74.01233199, 40.70816719 ], [ -74.01194141, 40.70798469 ], [ -74.01193377, 40.70798122 ], [ -74.01193889, 40.70797502 ], [ -74.01201381, 40.70788282 ], [ -74.01201884, 40.70787662 ], [ -74.01202702, 40.70788037 ], [ -74.01241805, 40.70806232 ] ] ] } }, { "type": "Feature", "properties": { "height": 95.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00962357, 40.7100479 ], [ -74.00949179, 40.71020861 ], [ -74.00922948, 40.71002107 ], [ -74.00932964, 40.7099064 ], [ -74.00962357, 40.7100479 ] ] ] } }, { "type": "Feature", "properties": { "height": 170.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01183567, 40.70730726 ], [ -74.01181968, 40.70732647 ], [ -74.01180378, 40.70734588 ], [ -74.01178591, 40.70736896 ], [ -74.01170165, 40.70746961 ], [ -74.01169805, 40.70747356 ], [ -74.01168305, 40.70749167 ], [ -74.01166787, 40.70750992 ], [ -74.0116641, 40.70750808 ], [ -74.01163715, 40.70749521 ], [ -74.01163194, 40.70749269 ], [ -74.01160669, 40.70748078 ], [ -74.01152108, 40.70743999 ], [ -74.01149908, 40.70742936 ], [ -74.01149378, 40.70742691 ], [ -74.01146889, 40.70741506 ], [ -74.01146539, 40.7074135 ], [ -74.01148147, 40.70739409 ], [ -74.01149773, 40.70737461 ], [ -74.01150123, 40.70737019 ], [ -74.01158343, 40.70727111 ], [ -74.01160337, 40.70724686 ], [ -74.01161855, 40.70722888 ], [ -74.01163328, 40.70721091 ], [ -74.01166383, 40.70722528 ], [ -74.01168161, 40.70723358 ], [ -74.01169437, 40.70723998 ], [ -74.01178025, 40.70728077 ], [ -74.01179157, 40.70728636 ], [ -74.01180792, 40.70729412 ], [ -74.01183567, 40.70730726 ] ] ] } }, { "type": "Feature", "properties": { "height": 119.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00832668, 40.71095266 ], [ -74.00834464, 40.7109622 ], [ -74.00842073, 40.71087531 ], [ -74.00845882, 40.7108337 ], [ -74.0084705, 40.71082077 ], [ -74.00848523, 40.7108047 ], [ -74.00850562, 40.71081532 ], [ -74.0086922, 40.71091201 ], [ -74.00853095, 40.71109736 ], [ -74.00830341, 40.71098058 ], [ -74.00832668, 40.71095266 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0085367, 40.70568252 ], [ -74.00854542, 40.70567081 ], [ -74.00858054, 40.70562328 ], [ -74.00863615, 40.70554809 ], [ -74.00868358, 40.70556839 ], [ -74.00870199, 40.70553468 ], [ -74.00869894, 40.70551922 ], [ -74.00869633, 40.70550601 ], [ -74.00886513, 40.70548851 ], [ -74.00887501, 40.70555572 ], [ -74.00877251, 40.7057626 ], [ -74.00873011, 40.70577248 ], [ -74.0085367, 40.70568252 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01413994, 40.7097472 ], [ -74.01408757, 40.70987637 ], [ -74.01406691, 40.70987168 ], [ -74.01405811, 40.70989578 ], [ -74.01402083, 40.70998526 ], [ -74.01401508, 40.70999942 ], [ -74.01397959, 40.70999118 ], [ -74.01396118, 40.7100398 ], [ -74.01382392, 40.71000902 ], [ -74.01384763, 40.7099491 ], [ -74.01385832, 40.70992179 ], [ -74.01386955, 40.70989401 ], [ -74.01391707, 40.70977369 ], [ -74.01393037, 40.70974087 ], [ -74.01394294, 40.70970961 ], [ -74.01401202, 40.70972541 ], [ -74.01399693, 40.7097645 ], [ -74.01402828, 40.70977151 ], [ -74.01404688, 40.70972541 ], [ -74.01413994, 40.7097472 ] ] ] } }, { "type": "Feature", "properties": { "height": 95.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00616829, 40.70838387 ], [ -74.0060976, 40.70833756 ], [ -74.00618491, 40.70826531 ], [ -74.00600929, 40.70815602 ], [ -74.00583187, 40.70822629 ], [ -74.00592871, 40.70833858 ], [ -74.0058272, 40.70838932 ], [ -74.00569623, 40.70826797 ], [ -74.00566901, 40.7082427 ], [ -74.00602241, 40.70810808 ], [ -74.00628903, 40.70827192 ], [ -74.00616829, 40.70838387 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01058827, 40.71070228 ], [ -74.01055827, 40.71074049 ], [ -74.0105368, 40.71076779 ], [ -74.01050814, 40.71080429 ], [ -74.01047086, 40.7107874 ], [ -74.01041697, 40.71076296 ], [ -74.01040187, 40.71075621 ], [ -74.01034797, 40.7107317 ], [ -74.01033297, 40.71072489 ], [ -74.01027943, 40.71070058 ], [ -74.01026443, 40.71069377 ], [ -74.01021062, 40.7106694 ], [ -74.01019562, 40.71066259 ], [ -74.01014208, 40.71063828 ], [ -74.01012699, 40.71063147 ], [ -74.01014037, 40.71061451 ], [ -74.01020847, 40.71052701 ], [ -74.01022338, 40.71053369 ], [ -74.01027737, 40.7105582 ], [ -74.01029237, 40.71056501 ], [ -74.01034591, 40.71058918 ], [ -74.01036091, 40.71059599 ], [ -74.01041472, 40.71062037 ], [ -74.01042972, 40.71062718 ], [ -74.01048344, 40.71065149 ], [ -74.01049844, 40.7106583 ], [ -74.01055234, 40.71068281 ], [ -74.01056734, 40.71068962 ], [ -74.01057615, 40.71067832 ], [ -74.0106128, 40.71063181 ], [ -74.01062178, 40.71062037 ], [ -74.01062834, 40.71061186 ], [ -74.01065098, 40.71062262 ], [ -74.01058827, 40.71070228 ] ] ] } }, { "type": "Feature", "properties": { "height": 52.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00729047, 40.70956001 ], [ -74.00724448, 40.70960706 ], [ -74.00716354, 40.7095613 ], [ -74.00699798, 40.70973058 ], [ -74.00699367, 40.70973501 ], [ -74.00698953, 40.7097393 ], [ -74.00698522, 40.70974366 ], [ -74.00698091, 40.70974808 ], [ -74.0068396, 40.70967482 ], [ -74.00686215, 40.7096518 ], [ -74.00702987, 40.70948006 ], [ -74.00707263, 40.70943628 ], [ -74.007102, 40.70945249 ], [ -74.00716345, 40.70948769 ], [ -74.00720809, 40.70951309 ], [ -74.00722669, 40.70952378 ], [ -74.00725454, 40.70953978 ], [ -74.00727071, 40.70954891 ], [ -74.00729047, 40.70956001 ] ] ] } }, { "type": "Feature", "properties": { "height": 262.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00988184, 40.70694478 ], [ -74.00971835, 40.70710978 ], [ -74.00950068, 40.70698598 ], [ -74.00966427, 40.70682091 ], [ -74.00988184, 40.70694478 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01265763, 40.70892877 ], [ -74.01256322, 40.70905488 ], [ -74.01255612, 40.70905182 ], [ -74.01252639, 40.70909138 ], [ -74.01251884, 40.70908811 ], [ -74.01249692, 40.70911726 ], [ -74.012316, 40.70903881 ], [ -74.0123364, 40.70901157 ], [ -74.01230675, 40.7089987 ], [ -74.01240107, 40.70885196 ], [ -74.01244779, 40.70887198 ], [ -74.01246692, 40.7088461 ], [ -74.01260284, 40.708905 ], [ -74.01265763, 40.70892877 ] ] ] } }, { "type": "Feature", "properties": { "height": 36.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00501773, 40.70601886 ], [ -74.00495171, 40.7060651 ], [ -74.00470161, 40.70585842 ], [ -74.00476764, 40.70581211 ], [ -74.0047229, 40.70577507 ], [ -74.0046567, 40.70582151 ], [ -74.00455788, 40.70573979 ], [ -74.00470341, 40.70563792 ], [ -74.00470673, 40.7056356 ], [ -74.00487238, 40.70577262 ], [ -74.00478983, 40.70583036 ], [ -74.00481274, 40.70584929 ], [ -74.00498018, 40.70598787 ], [ -74.00501773, 40.70601886 ] ] ] } }, { "type": "Feature", "properties": { "height": 77.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00911099, 40.70671128 ], [ -74.00896852, 40.70686838 ], [ -74.00870442, 40.7067138 ], [ -74.00871897, 40.70669657 ], [ -74.00879829, 40.706603 ], [ -74.00890914, 40.70666116 ], [ -74.00894355, 40.7066233 ], [ -74.00898487, 40.70664509 ], [ -74.00903113, 40.7066694 ], [ -74.00906338, 40.70668629 ], [ -74.00909078, 40.70670065 ], [ -74.00911099, 40.70671128 ] ] ] } }, { "type": "Feature", "properties": { "height": 227.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00861773, 40.70625516 ], [ -74.00850984, 40.70636507 ], [ -74.00846187, 40.7063381 ], [ -74.00842531, 40.70637549 ], [ -74.00828239, 40.706295 ], [ -74.00831913, 40.70625761 ], [ -74.00827493, 40.70623269 ], [ -74.00838273, 40.70612271 ], [ -74.00842693, 40.7061477 ], [ -74.00845873, 40.70611529 ], [ -74.00860165, 40.70619578 ], [ -74.00856985, 40.70622819 ], [ -74.00861773, 40.70625516 ] ] ] } }, { "type": "Feature", "properties": { "height": 102.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01361901, 40.70582301 ], [ -74.01354634, 40.70578869 ], [ -74.01375133, 40.70553951 ], [ -74.01382589, 40.70557472 ], [ -74.01391123, 40.70561497 ], [ -74.01370624, 40.70586428 ], [ -74.01361901, 40.70582301 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0065516, 40.70934272 ], [ -74.00643285, 40.70946951 ], [ -74.00614404, 40.70931957 ], [ -74.00617844, 40.7092813 ], [ -74.00623881, 40.70921381 ], [ -74.00625929, 40.70919087 ], [ -74.00633583, 40.70923057 ], [ -74.0063785, 40.70925276 ], [ -74.0065516, 40.70934272 ] ] ] } }, { "type": "Feature", "properties": { "height": 66.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00613362, 40.71139602 ], [ -74.00605825, 40.71131846 ], [ -74.00601387, 40.71127291 ], [ -74.00605017, 40.71125248 ], [ -74.00601558, 40.71122408 ], [ -74.0062053, 40.7110928 ], [ -74.00635811, 40.71123777 ], [ -74.00613362, 40.71139602 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01426562, 40.70831468 ], [ -74.01423588, 40.70838829 ], [ -74.0141916, 40.70837706 ], [ -74.01392489, 40.70830951 ], [ -74.01397654, 40.70819449 ], [ -74.01398274, 40.7081804 ], [ -74.01399954, 40.7081441 ], [ -74.01407751, 40.7081678 ], [ -74.01413878, 40.70818646 ], [ -74.01429778, 40.70823487 ], [ -74.01426562, 40.70831468 ] ] ] } }, { "type": "Feature", "properties": { "height": 117.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00937708, 40.70898658 ], [ -74.00919121, 40.70888716 ], [ -74.00939217, 40.70870256 ], [ -74.00957731, 40.70879659 ], [ -74.00937708, 40.70898658 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0089351, 40.71324341 ], [ -74.00869732, 40.71354567 ], [ -74.00864737, 40.713523 ], [ -74.0085906, 40.71359531 ], [ -74.00852502, 40.71356542 ], [ -74.00881967, 40.71319078 ], [ -74.0089351, 40.71324341 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00847274, 40.70542409 ], [ -74.00831617, 40.70567292 ], [ -74.00805134, 40.70552031 ], [ -74.00810479, 40.70546651 ], [ -74.00847274, 40.70542409 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0080641, 40.71130879 ], [ -74.00801298, 40.71119508 ], [ -74.0079828, 40.71112807 ], [ -74.00793833, 40.71102927 ], [ -74.00796241, 40.71099992 ], [ -74.00830557, 40.71120549 ], [ -74.00830359, 40.71122892 ], [ -74.00829838, 40.71125186 ], [ -74.0080658, 40.71131247 ], [ -74.0080641, 40.71130879 ] ] ] } }, { "type": "Feature", "properties": { "height": 182.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01180378, 40.70734588 ], [ -74.01178591, 40.70736896 ], [ -74.01170165, 40.70746961 ], [ -74.01169805, 40.70747356 ], [ -74.0116658, 40.70748609 ], [ -74.01164631, 40.70748786 ], [ -74.01160669, 40.70748078 ], [ -74.01152108, 40.70743999 ], [ -74.01149719, 40.70741472 ], [ -74.01149279, 40.70739872 ], [ -74.01149773, 40.70737461 ], [ -74.01150123, 40.70737019 ], [ -74.01158343, 40.70727111 ], [ -74.01160337, 40.70724686 ], [ -74.01163203, 40.70723549 ], [ -74.0116552, 40.70723358 ], [ -74.01169437, 40.70723998 ], [ -74.01178025, 40.70728077 ], [ -74.01179965, 40.70730257 ], [ -74.01180657, 40.70732088 ], [ -74.01180378, 40.70734588 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00908476, 40.71052061 ], [ -74.00908117, 40.71055016 ], [ -74.0090677, 40.71057808 ], [ -74.00904497, 40.71060239 ], [ -74.00901479, 40.71062146 ], [ -74.00897921, 40.71063392 ], [ -74.00894049, 40.71063896 ], [ -74.00890142, 40.7106363 ], [ -74.00886459, 40.71062602 ], [ -74.00883252, 40.71060879 ], [ -74.00880736, 40.71058591 ], [ -74.00879101, 40.71055888 ], [ -74.00878428, 40.7105296 ], [ -74.00878787, 40.71049998 ], [ -74.00880153, 40.71047199 ], [ -74.00882407, 40.71044768 ], [ -74.00885435, 40.71042868 ], [ -74.00888992, 40.71041616 ], [ -74.00892864, 40.71041118 ], [ -74.00896771, 40.71041391 ], [ -74.00900463, 40.71042419 ], [ -74.00903661, 40.71044142 ], [ -74.00906168, 40.71046416 ], [ -74.00907821, 40.71049126 ], [ -74.00908476, 40.71052061 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01404023, 40.71165239 ], [ -74.01395103, 40.71199666 ], [ -74.0137976, 40.71192639 ], [ -74.01388842, 40.71162957 ], [ -74.01404023, 40.71165239 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00676657, 40.71096152 ], [ -74.00650399, 40.71114741 ], [ -74.0063485, 40.71100019 ], [ -74.00642728, 40.71094551 ], [ -74.0064748, 40.71098467 ], [ -74.00653274, 40.71094449 ], [ -74.00664934, 40.7108636 ], [ -74.00676657, 40.71096152 ] ] ] } }, { "type": "Feature", "properties": { "height": 209.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00736395, 40.71106549 ], [ -74.00721789, 40.71116157 ], [ -74.0069739, 40.7109577 ], [ -74.00710928, 40.71086087 ], [ -74.00714117, 40.7108877 ], [ -74.00727879, 40.71099597 ], [ -74.00736395, 40.71106549 ] ] ] } }, { "type": "Feature", "properties": { "height": 34.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00889594, 40.71008556 ], [ -74.00896987, 40.71000051 ], [ -74.0094016, 40.71030108 ], [ -74.00935893, 40.71035017 ], [ -74.00891831, 40.71012825 ], [ -74.00893735, 40.71010646 ], [ -74.00889594, 40.71008556 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01344258, 40.70683038 ], [ -74.01339443, 40.70689487 ], [ -74.01314434, 40.70678666 ], [ -74.01287395, 40.70666797 ], [ -74.01278403, 40.70662902 ], [ -74.01283954, 40.70656609 ], [ -74.01344258, 40.70683038 ] ] ] } }, { "type": "Feature", "properties": { "height": 52.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00664934, 40.7108636 ], [ -74.00653274, 40.71094449 ], [ -74.0064748, 40.71098467 ], [ -74.00642728, 40.71094551 ], [ -74.0063485, 40.71100019 ], [ -74.00623405, 40.71089179 ], [ -74.00634023, 40.71081811 ], [ -74.00644183, 40.71089587 ], [ -74.00648711, 40.71086387 ], [ -74.00638874, 40.71078447 ], [ -74.0064792, 40.71072169 ], [ -74.00658179, 40.71080728 ], [ -74.00664934, 40.7108636 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01007264, 40.70727417 ], [ -74.0100112, 40.70733661 ], [ -74.00999422, 40.70735412 ], [ -74.00969229, 40.70718292 ], [ -74.0096339, 40.70715119 ], [ -74.00947131, 40.70705966 ], [ -74.00938318, 40.70701036 ], [ -74.00941993, 40.70697318 ], [ -74.00945568, 40.70699341 ], [ -74.00951362, 40.70702596 ], [ -74.0096693, 40.7071138 ], [ -74.0097267, 40.70714622 ], [ -74.00977162, 40.70717148 ], [ -74.00978024, 40.70716276 ], [ -74.00981402, 40.70712851 ], [ -74.00984061, 40.7071437 ], [ -74.01007264, 40.70727417 ] ] ] } }, { "type": "Feature", "properties": { "height": 101.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01504814, 40.70793709 ], [ -74.01497825, 40.70805422 ], [ -74.0149398, 40.70811857 ], [ -74.01490791, 40.70817189 ], [ -74.01466797, 40.70808867 ], [ -74.01473418, 40.70797822 ], [ -74.01476751, 40.70798986 ], [ -74.01479832, 40.70794152 ], [ -74.01491995, 40.7079806 ], [ -74.01496487, 40.70790767 ], [ -74.01504814, 40.70793709 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00796897, 40.70933448 ], [ -74.00791453, 40.70938936 ], [ -74.00788291, 40.70942116 ], [ -74.00785084, 40.70940278 ], [ -74.00779568, 40.70937111 ], [ -74.00773738, 40.70942988 ], [ -74.00772265, 40.70944479 ], [ -74.0077664, 40.70946999 ], [ -74.00772265, 40.70951418 ], [ -74.00767872, 40.70948899 ], [ -74.00763021, 40.70946107 ], [ -74.00757101, 40.70942709 ], [ -74.00758655, 40.7094117 ], [ -74.00776155, 40.7092369 ], [ -74.00778984, 40.70920871 ], [ -74.00785102, 40.70925167 ], [ -74.00796897, 40.70933448 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00735901, 40.70667607 ], [ -74.00732991, 40.70670617 ], [ -74.00731347, 40.70672306 ], [ -74.00724385, 40.70679511 ], [ -74.00721465, 40.70677917 ], [ -74.00717099, 40.70682548 ], [ -74.00700292, 40.70671162 ], [ -74.00716264, 40.70654662 ], [ -74.00735901, 40.70667607 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00817603, 40.71298222 ], [ -74.00813731, 40.71303131 ], [ -74.00774421, 40.71285339 ], [ -74.00772328, 40.71288001 ], [ -74.00761287, 40.71302021 ], [ -74.0075976, 40.71303962 ], [ -74.00780745, 40.71313461 ], [ -74.00778346, 40.71316491 ], [ -74.00752807, 40.71304929 ], [ -74.00773729, 40.71278366 ], [ -74.00817603, 40.71298222 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00968529, 40.709315 ], [ -74.00951982, 40.70949968 ], [ -74.00933692, 40.70938051 ], [ -74.00948748, 40.70921238 ], [ -74.00968529, 40.709315 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00741201, 40.709232 ], [ -74.00716345, 40.70948769 ], [ -74.007102, 40.70945249 ], [ -74.00731005, 40.70924146 ], [ -74.00718519, 40.70917071 ], [ -74.00691479, 40.70944466 ], [ -74.00686404, 40.70941592 ], [ -74.0068626, 40.70941517 ], [ -74.00713991, 40.7091323 ], [ -74.00722741, 40.70918208 ], [ -74.0072778, 40.70921048 ], [ -74.00731203, 40.70917548 ], [ -74.00739827, 40.7092243 ], [ -74.00741201, 40.709232 ] ] ] } }, { "type": "Feature", "properties": { "height": 225.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00882892, 40.70623119 ], [ -74.00861773, 40.70625516 ], [ -74.00856985, 40.70622819 ], [ -74.00842693, 40.7061477 ], [ -74.00838273, 40.70612271 ], [ -74.0083521, 40.70596247 ], [ -74.00839612, 40.70598726 ], [ -74.00878131, 40.70620436 ], [ -74.00882892, 40.70623119 ] ] ] } }, { "type": "Feature", "properties": { "height": 225.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00881284, 40.70617228 ], [ -74.00878131, 40.70620436 ], [ -74.00849313, 40.7064982 ], [ -74.00846035, 40.70653061 ], [ -74.00842531, 40.70637549 ], [ -74.00846187, 40.7063381 ], [ -74.00856985, 40.70622819 ], [ -74.00860165, 40.70619578 ], [ -74.00881284, 40.70617228 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0084899, 40.71003285 ], [ -74.00841534, 40.71011859 ], [ -74.00840115, 40.71013486 ], [ -74.00808701, 40.70995278 ], [ -74.00819795, 40.7098428 ], [ -74.0084899, 40.71003285 ] ] ] } }, { "type": "Feature", "properties": { "height": 114.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00483708, 40.70800056 ], [ -74.00477034, 40.70802568 ], [ -74.00468212, 40.70805878 ], [ -74.004662, 40.70802752 ], [ -74.00465257, 40.70801942 ], [ -74.00464242, 40.70800948 ], [ -74.00462984, 40.70799279 ], [ -74.00462202, 40.70797298 ], [ -74.00462014, 40.7079567 ], [ -74.0046028, 40.70793117 ], [ -74.00465535, 40.7079106 ], [ -74.00492835, 40.70781091 ], [ -74.00499752, 40.70794029 ], [ -74.00483708, 40.70800056 ] ] ] } }, { "type": "Feature", "properties": { "height": 225.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00854056, 40.70652496 ], [ -74.00849313, 40.7064982 ], [ -74.00810794, 40.70628097 ], [ -74.00806401, 40.70625632 ], [ -74.00827493, 40.70623269 ], [ -74.00831913, 40.70625761 ], [ -74.00846187, 40.7063381 ], [ -74.00850984, 40.70636507 ], [ -74.00854056, 40.70652496 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00615105, 40.71270209 ], [ -74.00596698, 40.71290991 ], [ -74.00580277, 40.7128237 ], [ -74.00597938, 40.71261521 ], [ -74.00615105, 40.71270209 ] ] ] } }, { "type": "Feature", "properties": { "height": 171.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01187969, 40.70624059 ], [ -74.01178878, 40.70636357 ], [ -74.0114759, 40.70623058 ], [ -74.01156681, 40.70610759 ], [ -74.0118178, 40.7062143 ], [ -74.01187969, 40.70624059 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00926847, 40.70952058 ], [ -74.00925203, 40.70953808 ], [ -74.00921825, 40.7095741 ], [ -74.00914459, 40.70965228 ], [ -74.00913211, 40.70966562 ], [ -74.00909474, 40.70964526 ], [ -74.00906779, 40.70963062 ], [ -74.00899709, 40.70959208 ], [ -74.00892675, 40.70955429 ], [ -74.00894723, 40.70953188 ], [ -74.00909447, 40.70937111 ], [ -74.00912213, 40.70939692 ], [ -74.00917909, 40.70944752 ], [ -74.00920828, 40.70947217 ], [ -74.00926847, 40.70952058 ] ] ] } }, { "type": "Feature", "properties": { "height": 225.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00845873, 40.70611529 ], [ -74.00842693, 40.7061477 ], [ -74.00831913, 40.70625761 ], [ -74.00828239, 40.706295 ], [ -74.00808144, 40.70631168 ], [ -74.00810794, 40.70628097 ], [ -74.00839612, 40.70598726 ], [ -74.00842747, 40.70595519 ], [ -74.00845873, 40.70611529 ] ] ] } }, { "type": "Feature", "properties": { "height": 131.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0096728, 40.70780097 ], [ -74.0095809, 40.70774472 ], [ -74.00959078, 40.70773668 ], [ -74.0094458, 40.70764986 ], [ -74.0095058, 40.70758646 ], [ -74.00969149, 40.70768888 ], [ -74.00971242, 40.70766586 ], [ -74.0097232, 40.70767226 ], [ -74.00973613, 40.70767989 ], [ -74.00976515, 40.70764938 ], [ -74.00989154, 40.70772599 ], [ -74.00976317, 40.70786361 ], [ -74.00966822, 40.70780546 ], [ -74.0096728, 40.70780097 ] ] ] } }, { "type": "Feature", "properties": { "height": 400.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01302199, 40.71325227 ], [ -74.0127039, 40.71312698 ], [ -74.01287314, 40.71288049 ], [ -74.01302199, 40.71325227 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00448099, 40.70599169 ], [ -74.00435675, 40.70607879 ], [ -74.00414637, 40.70590479 ], [ -74.00415337, 40.70589989 ], [ -74.00421086, 40.70585958 ], [ -74.00414403, 40.70580428 ], [ -74.00408663, 40.70575668 ], [ -74.00414897, 40.70571732 ], [ -74.00427024, 40.70581749 ], [ -74.0042538, 40.705829 ], [ -74.0043183, 40.70588239 ], [ -74.00433474, 40.70587081 ], [ -74.00448099, 40.70599169 ] ] ] } }, { "type": "Feature", "properties": { "height": 111.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.007102, 40.70945249 ], [ -74.00707263, 40.70943628 ], [ -74.00702987, 40.70948006 ], [ -74.0069898, 40.70945739 ], [ -74.00697112, 40.70947659 ], [ -74.00691479, 40.70944466 ], [ -74.00718519, 40.70917071 ], [ -74.00731005, 40.70924146 ], [ -74.007102, 40.70945249 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01365072, 40.70616656 ], [ -74.0136324, 40.70619489 ], [ -74.01358487, 40.70626837 ], [ -74.01357921, 40.70627729 ], [ -74.01342399, 40.7062096 ], [ -74.01324181, 40.7061302 ], [ -74.01321513, 40.70611849 ], [ -74.01329858, 40.70601961 ], [ -74.01331763, 40.70602751 ], [ -74.01337242, 40.70605039 ], [ -74.01341464, 40.70606796 ], [ -74.01347537, 40.70609336 ], [ -74.01365072, 40.70616656 ] ] ] } }, { "type": "Feature", "properties": { "height": 97.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00581211, 40.70848438 ], [ -74.0056444, 40.70860477 ], [ -74.00562104, 40.70858189 ], [ -74.0055286, 40.70849139 ], [ -74.00556795, 40.70846538 ], [ -74.0055702, 40.70846742 ], [ -74.00559867, 40.70844856 ], [ -74.00552187, 40.70838121 ], [ -74.0055269, 40.70837788 ], [ -74.00556373, 40.7083537 ], [ -74.0055746, 40.7083633 ], [ -74.00563712, 40.70832217 ], [ -74.00562832, 40.70831441 ], [ -74.00567018, 40.70828676 ], [ -74.00577564, 40.70837931 ], [ -74.00572812, 40.7084107 ], [ -74.00581211, 40.70848438 ] ] ] } }, { "type": "Feature", "properties": { "height": 400.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0133567, 40.71275772 ], [ -74.01287314, 40.71288049 ], [ -74.01304238, 40.71263386 ], [ -74.0133567, 40.71275772 ] ] ] } }, { "type": "Feature", "properties": { "height": 400.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01367084, 40.71288151 ], [ -74.01350151, 40.71312807 ], [ -74.0133567, 40.71275772 ], [ -74.01367084, 40.71288151 ] ] ] } }, { "type": "Feature", "properties": { "height": 117.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00619515, 40.71050747 ], [ -74.00601324, 40.71063371 ], [ -74.00591748, 40.7105454 ], [ -74.00584607, 40.7104786 ], [ -74.00596069, 40.71038708 ], [ -74.00597138, 40.71039307 ], [ -74.00602366, 40.710358 ], [ -74.00619515, 40.71050747 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01348929, 40.70676916 ], [ -74.01344258, 40.70683038 ], [ -74.01283954, 40.70656609 ], [ -74.01288949, 40.7065059 ], [ -74.01294815, 40.70653211 ], [ -74.01300088, 40.7065552 ], [ -74.01304948, 40.70657651 ], [ -74.01331601, 40.70669337 ], [ -74.01336488, 40.70671461 ], [ -74.01341761, 40.70673777 ], [ -74.01348929, 40.70676916 ] ] ] } }, { "type": "Feature", "properties": { "height": 400.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01350151, 40.71312807 ], [ -74.01333218, 40.71337449 ], [ -74.01302199, 40.71325227 ], [ -74.01350151, 40.71312807 ] ] ] } }, { "type": "Feature", "properties": { "height": 131.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0143126, 40.70787097 ], [ -74.01423795, 40.70799558 ], [ -74.01421864, 40.70798898 ], [ -74.01420399, 40.70798408 ], [ -74.01416447, 40.70797059 ], [ -74.01415827, 40.70796848 ], [ -74.01406448, 40.70793648 ], [ -74.0140599, 40.70793491 ], [ -74.01398588, 40.70790971 ], [ -74.01394887, 40.70789712 ], [ -74.01391653, 40.70788602 ], [ -74.01399172, 40.70776038 ], [ -74.01402729, 40.70777271 ], [ -74.0143126, 40.70787097 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01029524, 40.71041636 ], [ -74.01020847, 40.71052701 ], [ -74.01014037, 40.71061451 ], [ -74.01012699, 40.71063147 ], [ -74.00995478, 40.71055316 ], [ -74.00996817, 40.7105362 ], [ -74.01003815, 40.71044761 ], [ -74.01004542, 40.71043829 ], [ -74.01005773, 40.71044387 ], [ -74.01013579, 40.71034411 ], [ -74.01014388, 40.71034779 ], [ -74.01021134, 40.7103783 ], [ -74.01029524, 40.71041636 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01017819, 40.7093957 ], [ -74.01006779, 40.70951881 ], [ -74.00995164, 40.70945841 ], [ -74.00998712, 40.70941892 ], [ -74.00990115, 40.70937431 ], [ -74.00988498, 40.70939215 ], [ -74.00978347, 40.70933959 ], [ -74.00977162, 40.70933339 ], [ -74.00981069, 40.70928981 ], [ -74.00986262, 40.70923186 ], [ -74.00992235, 40.70926291 ], [ -74.00997437, 40.70928988 ], [ -74.01011019, 40.70936042 ], [ -74.01013507, 40.70937288 ], [ -74.01015762, 40.709385 ], [ -74.01017819, 40.7093957 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00562104, 40.70858189 ], [ -74.00555304, 40.70862282 ], [ -74.00523297, 40.70830937 ], [ -74.0053908, 40.70824311 ], [ -74.00551414, 40.70836378 ], [ -74.00544192, 40.70840641 ], [ -74.0055286, 40.70849139 ], [ -74.00562104, 40.70858189 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0070181, 40.71408808 ], [ -74.00697175, 40.71414146 ], [ -74.0069642, 40.71413799 ], [ -74.00693581, 40.71412498 ], [ -74.00689844, 40.71417196 ], [ -74.00688704, 40.71418626 ], [ -74.00667575, 40.71408896 ], [ -74.00659984, 40.71405396 ], [ -74.00669228, 40.71393787 ], [ -74.00681239, 40.71399329 ], [ -74.00699187, 40.71407596 ], [ -74.0070181, 40.71408808 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00820621, 40.71294388 ], [ -74.00817603, 40.71298222 ], [ -74.00773729, 40.71278366 ], [ -74.00752807, 40.71304929 ], [ -74.00778346, 40.71316491 ], [ -74.00776523, 40.71318819 ], [ -74.00747103, 40.71305508 ], [ -74.00748172, 40.71304146 ], [ -74.00772867, 40.7127279 ], [ -74.00820621, 40.71294388 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00822867, 40.71419191 ], [ -74.00855988, 40.71376921 ], [ -74.00864324, 40.713807 ], [ -74.00831203, 40.7142297 ], [ -74.00830718, 40.71422746 ], [ -74.00822867, 40.71419191 ] ] ] } }, { "type": "Feature", "properties": { "height": 93.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01385554, 40.70620742 ], [ -74.0138126, 40.70626878 ], [ -74.01379858, 40.70626279 ], [ -74.01373947, 40.70634736 ], [ -74.01368773, 40.70632462 ], [ -74.01359619, 40.70628471 ], [ -74.01357921, 40.70627729 ], [ -74.01358487, 40.70626837 ], [ -74.0136324, 40.70619489 ], [ -74.01365072, 40.70616656 ], [ -74.01347537, 40.70609336 ], [ -74.01350268, 40.70605441 ], [ -74.01361784, 40.70609397 ], [ -74.0136235, 40.70608451 ], [ -74.01375448, 40.70612959 ], [ -74.01374882, 40.70613919 ], [ -74.0138585, 40.70617698 ], [ -74.01384161, 40.70620116 ], [ -74.01385554, 40.70620742 ] ] ] } }, { "type": "Feature", "properties": { "height": 11.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00571887, 40.70886592 ], [ -74.00554926, 40.70900858 ], [ -74.00536277, 40.70888628 ], [ -74.00556175, 40.7087411 ], [ -74.00557711, 40.70875329 ], [ -74.00571887, 40.70886592 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00537921, 40.70964118 ], [ -74.00532217, 40.70968796 ], [ -74.00520871, 40.70978097 ], [ -74.00514305, 40.70983491 ], [ -74.00510181, 40.70980576 ], [ -74.0051134, 40.7097963 ], [ -74.00506992, 40.70976559 ], [ -74.00509283, 40.70974679 ], [ -74.00505923, 40.70972309 ], [ -74.00506399, 40.70971921 ], [ -74.00505142, 40.70971029 ], [ -74.00507774, 40.70968871 ], [ -74.00506651, 40.70968081 ], [ -74.005071, 40.70967706 ], [ -74.00505789, 40.7096678 ], [ -74.00508205, 40.70964812 ], [ -74.00506759, 40.70963791 ], [ -74.00507343, 40.70963321 ], [ -74.0050657, 40.70962776 ], [ -74.00511089, 40.70959072 ], [ -74.00512014, 40.70959726 ], [ -74.00515122, 40.70957179 ], [ -74.0051647, 40.70958139 ], [ -74.00516811, 40.7095786 ], [ -74.00518832, 40.70959276 ], [ -74.00521428, 40.70957138 ], [ -74.00522704, 40.70958037 ], [ -74.00523207, 40.70957621 ], [ -74.00527887, 40.70960917 ], [ -74.0052839, 40.70960509 ], [ -74.00531094, 40.70962422 ], [ -74.00531561, 40.7096202 ], [ -74.00532019, 40.70962347 ], [ -74.00533591, 40.70961067 ], [ -74.00537921, 40.70964118 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01087798, 40.71029277 ], [ -74.01083935, 40.71034221 ], [ -74.01081375, 40.71037475 ], [ -74.01080243, 40.71038987 ], [ -74.01078698, 40.71038286 ], [ -74.01073317, 40.71035868 ], [ -74.01071808, 40.71035188 ], [ -74.01066445, 40.71032757 ], [ -74.01064945, 40.71032089 ], [ -74.01059555, 40.71029658 ], [ -74.01058055, 40.71028977 ], [ -74.01052692, 40.7102656 ], [ -74.01051192, 40.71025886 ], [ -74.01045811, 40.71023462 ], [ -74.0104432, 40.71022788 ], [ -74.01051964, 40.71013016 ], [ -74.01053464, 40.71013711 ], [ -74.01058836, 40.71016128 ], [ -74.01060328, 40.71016829 ], [ -74.01065691, 40.7101924 ], [ -74.01067182, 40.71019928 ], [ -74.01072572, 40.71022359 ], [ -74.01074063, 40.71023046 ], [ -74.01079435, 40.71025477 ], [ -74.01080917, 40.71026172 ], [ -74.01086307, 40.71028596 ], [ -74.01087798, 40.71029277 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01219473, 40.70574721 ], [ -74.01210337, 40.70593986 ], [ -74.01203923, 40.70592938 ], [ -74.01196602, 40.70591739 ], [ -74.01171647, 40.7058766 ], [ -74.01194177, 40.70586836 ], [ -74.01193287, 40.70571977 ], [ -74.01199647, 40.70572651 ], [ -74.01219473, 40.70574721 ] ] ] } }, { "type": "Feature", "properties": { "height": 73.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01016059, 40.7060493 ], [ -74.0101313, 40.70609778 ], [ -74.00998784, 40.70604467 ], [ -74.00990933, 40.70617439 ], [ -74.00988992, 40.70616806 ], [ -74.00980279, 40.7063125 ], [ -74.01000365, 40.70643977 ], [ -74.00996619, 40.70648049 ], [ -74.00973245, 40.70633238 ], [ -74.0099502, 40.7059716 ], [ -74.01016059, 40.7060493 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01115044, 40.71394488 ], [ -74.01118017, 40.71390628 ], [ -74.01122913, 40.71384302 ], [ -74.0113434, 40.7136952 ], [ -74.01142047, 40.71373646 ], [ -74.01134699, 40.71403646 ], [ -74.01115044, 40.71394488 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00471563, 40.70901539 ], [ -74.00452267, 40.70889111 ], [ -74.0045471, 40.70886932 ], [ -74.00457145, 40.70889676 ], [ -74.00482019, 40.70877957 ], [ -74.00492988, 40.70891467 ], [ -74.00471563, 40.70901539 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00854542, 40.70567081 ], [ -74.00858054, 40.70562328 ], [ -74.00863615, 40.70554809 ], [ -74.00868358, 40.70556839 ], [ -74.00870199, 40.70553468 ], [ -74.00869894, 40.70551922 ], [ -74.0088495, 40.70550376 ], [ -74.00885695, 40.70555388 ], [ -74.00875895, 40.70575157 ], [ -74.00873262, 40.70575777 ], [ -74.00854542, 40.70567081 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01055234, 40.71068281 ], [ -74.01047086, 40.7107874 ], [ -74.01041697, 40.71076296 ], [ -74.010422, 40.71075649 ], [ -74.01040708, 40.71074961 ], [ -74.01040187, 40.71075621 ], [ -74.01034797, 40.7107317 ], [ -74.01035319, 40.71072516 ], [ -74.01033818, 40.71071829 ], [ -74.01033297, 40.71072489 ], [ -74.01027943, 40.71070058 ], [ -74.01028446, 40.71069398 ], [ -74.01026964, 40.7106871 ], [ -74.01026443, 40.71069377 ], [ -74.01021062, 40.7106694 ], [ -74.01021574, 40.71066279 ], [ -74.01020083, 40.71065591 ], [ -74.01019562, 40.71066259 ], [ -74.01014208, 40.71063828 ], [ -74.01022338, 40.71053369 ], [ -74.01027737, 40.7105582 ], [ -74.01029237, 40.71056501 ], [ -74.01034591, 40.71058918 ], [ -74.01036091, 40.71059599 ], [ -74.01041472, 40.71062037 ], [ -74.01042972, 40.71062718 ], [ -74.01048344, 40.71065149 ], [ -74.01049844, 40.7106583 ], [ -74.01055234, 40.71068281 ] ] ] } }, { "type": "Feature", "properties": { "height": 42.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01415827, 40.70796848 ], [ -74.01414479, 40.70799157 ], [ -74.01408964, 40.70797332 ], [ -74.01407401, 40.70800021 ], [ -74.01406907, 40.70800886 ], [ -74.01405748, 40.7080329 ], [ -74.0140493, 40.70804788 ], [ -74.01404194, 40.7080615 ], [ -74.01395552, 40.70803426 ], [ -74.01387871, 40.70801009 ], [ -74.01372205, 40.70796079 ], [ -74.01377622, 40.70783821 ], [ -74.01381287, 40.70785068 ], [ -74.01383398, 40.70785789 ], [ -74.01385284, 40.70786429 ], [ -74.0138894, 40.70787676 ], [ -74.01391653, 40.70788602 ], [ -74.01394887, 40.70789712 ], [ -74.01398588, 40.70790971 ], [ -74.0140599, 40.70793491 ], [ -74.01406448, 40.70793648 ], [ -74.01415827, 40.70796848 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.014135, 40.70701186 ], [ -74.01417992, 40.70690767 ], [ -74.01418163, 40.70689957 ], [ -74.01418719, 40.70688377 ], [ -74.01419582, 40.70686872 ], [ -74.01420714, 40.70685469 ], [ -74.0142137, 40.70684829 ], [ -74.0142287, 40.70683651 ], [ -74.01424568, 40.70682636 ], [ -74.01426445, 40.70681826 ], [ -74.01428448, 40.70681227 ], [ -74.0143055, 40.70680859 ], [ -74.01432554, 40.70680716 ], [ -74.01442139, 40.7068282 ], [ -74.01447681, 40.70684822 ], [ -74.01449613, 40.70685776 ], [ -74.01451364, 40.7068692 ], [ -74.01452155, 40.7068756 ], [ -74.01453574, 40.70688949 ], [ -74.01454185, 40.70689691 ], [ -74.01455209, 40.70691257 ], [ -74.01455955, 40.70692919 ], [ -74.01456215, 40.7069377 ], [ -74.01456718, 40.70694649 ], [ -74.01448831, 40.7069108 ], [ -74.01446828, 40.70688881 ], [ -74.01436021, 40.70684999 ], [ -74.01432122, 40.70685081 ], [ -74.01424648, 40.70697332 ], [ -74.01427101, 40.70699531 ], [ -74.01438473, 40.70703406 ], [ -74.01457194, 40.70706879 ], [ -74.01453718, 40.70712592 ], [ -74.01421864, 40.70701131 ], [ -74.01420301, 40.70703671 ], [ -74.014135, 40.70701186 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00438891, 40.70848199 ], [ -74.004245, 40.70855016 ], [ -74.00409283, 40.70836398 ], [ -74.00405932, 40.70832326 ], [ -74.00420251, 40.70825558 ], [ -74.00438891, 40.70848199 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00591668, 40.70870719 ], [ -74.00571887, 40.70886592 ], [ -74.00557711, 40.70875329 ], [ -74.00576827, 40.70859367 ], [ -74.00591668, 40.70870719 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00742279, 40.71357788 ], [ -74.00738147, 40.71363078 ], [ -74.00726675, 40.71357869 ], [ -74.00730817, 40.71352572 ], [ -74.00724879, 40.71349875 ], [ -74.00720729, 40.7135518 ], [ -74.00707469, 40.71349161 ], [ -74.00709401, 40.71346689 ], [ -74.00715339, 40.7133909 ], [ -74.00717333, 40.71336537 ], [ -74.00730278, 40.71342386 ], [ -74.0072831, 40.71344912 ], [ -74.00728005, 40.71345307 ], [ -74.0073441, 40.71348207 ], [ -74.00736377, 40.71345702 ], [ -74.00737249, 40.71346096 ], [ -74.00747741, 40.71350849 ], [ -74.00742279, 40.71357788 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00881967, 40.71319078 ], [ -74.00852502, 40.71356542 ], [ -74.00843708, 40.71352538 ], [ -74.00858198, 40.71334106 ], [ -74.00872759, 40.71315599 ], [ -74.00873182, 40.71315081 ], [ -74.00881967, 40.71319078 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01003743, 40.706403 ], [ -74.00988319, 40.70630528 ], [ -74.01001353, 40.70608927 ], [ -74.01011405, 40.70612652 ], [ -74.0101022, 40.706146 ], [ -74.01005719, 40.7062205 ], [ -74.01016921, 40.70625959 ], [ -74.01003743, 40.706403 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01339443, 40.70689487 ], [ -74.01326651, 40.70706498 ], [ -74.01325924, 40.70707029 ], [ -74.01324998, 40.70707322 ], [ -74.01324504, 40.70707369 ], [ -74.01323507, 40.7070726 ], [ -74.01308209, 40.70700587 ], [ -74.01311739, 40.70695888 ], [ -74.0131968, 40.70685272 ], [ -74.01319851, 40.70684271 ], [ -74.01319141, 40.70683467 ], [ -74.01312862, 40.70680757 ], [ -74.01314434, 40.70678666 ], [ -74.01339443, 40.70689487 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00742279, 40.7140189 ], [ -74.00725552, 40.71422909 ], [ -74.00710074, 40.7141578 ], [ -74.00711907, 40.71413458 ], [ -74.00726801, 40.71394761 ], [ -74.00742279, 40.7140189 ] ] ] } }, { "type": "Feature", "properties": { "height": 58.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01029524, 40.71041636 ], [ -74.01020847, 40.71052701 ], [ -74.01014037, 40.71061451 ], [ -74.00996817, 40.7105362 ], [ -74.01003815, 40.71044761 ], [ -74.01004542, 40.71043829 ], [ -74.01005773, 40.71044387 ], [ -74.01013579, 40.71034411 ], [ -74.01014388, 40.71034779 ], [ -74.01021134, 40.7103783 ], [ -74.01029524, 40.71041636 ] ] ] } }, { "type": "Feature", "properties": { "height": 95.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00688704, 40.7083505 ], [ -74.00689997, 40.70833211 ], [ -74.00691255, 40.70831216 ], [ -74.00701576, 40.70816828 ], [ -74.00720369, 40.70828561 ], [ -74.00703562, 40.70844352 ], [ -74.00688704, 40.7083505 ] ] ] } }, { "type": "Feature", "properties": { "height": 82.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00909078, 40.70670065 ], [ -74.00897409, 40.70682909 ], [ -74.00895613, 40.70683236 ], [ -74.00871897, 40.70669657 ], [ -74.00879829, 40.706603 ], [ -74.00890914, 40.70666116 ], [ -74.00894355, 40.7066233 ], [ -74.00898487, 40.70664509 ], [ -74.00903113, 40.7066694 ], [ -74.00906338, 40.70668629 ], [ -74.00909078, 40.70670065 ] ] ] } }, { "type": "Feature", "properties": { "height": 93.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01134771, 40.70787989 ], [ -74.011263, 40.70783706 ], [ -74.01119697, 40.70780376 ], [ -74.01117981, 40.70779511 ], [ -74.01113041, 40.70777019 ], [ -74.01105531, 40.70773226 ], [ -74.01113382, 40.70765006 ], [ -74.01116535, 40.70761717 ], [ -74.01120838, 40.70764332 ], [ -74.01125357, 40.70767049 ], [ -74.01136451, 40.7077375 ], [ -74.01134933, 40.70775296 ], [ -74.0114282, 40.70779668 ], [ -74.01134771, 40.70787989 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01243557, 40.70994059 ], [ -74.01251408, 40.70983736 ], [ -74.01253555, 40.70976729 ], [ -74.01259978, 40.70965588 ], [ -74.01270839, 40.70970369 ], [ -74.01258325, 40.71000562 ], [ -74.01243557, 40.70994059 ] ] ] } }, { "type": "Feature", "properties": { "height": 113.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0042697, 40.71265136 ], [ -74.00412831, 40.71280096 ], [ -74.00393239, 40.71269392 ], [ -74.00407513, 40.71254637 ], [ -74.0042697, 40.71265136 ] ] ] } }, { "type": "Feature", "properties": { "height": 242.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00782569, 40.70645087 ], [ -74.00781194, 40.70646429 ], [ -74.00779478, 40.70648131 ], [ -74.00777502, 40.70648097 ], [ -74.00775669, 40.70649868 ], [ -74.00776128, 40.7065142 ], [ -74.00774358, 40.70653136 ], [ -74.00773001, 40.70654478 ], [ -74.00771591, 40.70655867 ], [ -74.00769318, 40.70656058 ], [ -74.00766561, 40.70654437 ], [ -74.00763578, 40.70652687 ], [ -74.00763587, 40.70651236 ], [ -74.00758718, 40.70648349 ], [ -74.0075685, 40.70648751 ], [ -74.00753867, 40.70647008 ], [ -74.00751092, 40.7064538 ], [ -74.00750759, 40.70643678 ], [ -74.00753598, 40.70640899 ], [ -74.0075535, 40.70639176 ], [ -74.00757308, 40.70639231 ], [ -74.00759131, 40.7063746 ], [ -74.00758682, 40.70635908 ], [ -74.00760434, 40.70634192 ], [ -74.00761799, 40.7063285 ], [ -74.00763219, 40.70631461 ], [ -74.00765483, 40.7063127 ], [ -74.00768249, 40.70632898 ], [ -74.00771232, 40.70634641 ], [ -74.00771214, 40.70636098 ], [ -74.00776074, 40.70638999 ], [ -74.0077796, 40.70638577 ], [ -74.00783709, 40.70641948 ], [ -74.00784024, 40.70643637 ], [ -74.00782569, 40.70645087 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01003815, 40.71044761 ], [ -74.00996817, 40.7105362 ], [ -74.00995478, 40.71055316 ], [ -74.00990771, 40.71053191 ], [ -74.00965097, 40.71041418 ], [ -74.00969831, 40.71035079 ], [ -74.00973164, 40.71030857 ], [ -74.01003815, 40.71044761 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00789818, 40.71048861 ], [ -74.00785434, 40.7105328 ], [ -74.0078203, 40.71051298 ], [ -74.00775849, 40.71057577 ], [ -74.00779694, 40.71059776 ], [ -74.00770073, 40.71069296 ], [ -74.00763389, 40.71065557 ], [ -74.00768142, 40.71060532 ], [ -74.00767055, 40.71059906 ], [ -74.00757128, 40.71054506 ], [ -74.00771762, 40.7103928 ], [ -74.00776837, 40.71041929 ], [ -74.00781904, 40.71044687 ], [ -74.00789818, 40.71048861 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00684544, 40.71036876 ], [ -74.00682038, 40.71038939 ], [ -74.00670971, 40.71048071 ], [ -74.00668465, 40.71050141 ], [ -74.00664171, 40.71053682 ], [ -74.00649465, 40.71043161 ], [ -74.00653624, 40.71039791 ], [ -74.00665177, 40.71030428 ], [ -74.00667809, 40.71028296 ], [ -74.00684544, 40.71036876 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01461677, 40.70900578 ], [ -74.01460725, 40.70903077 ], [ -74.01459764, 40.70905427 ], [ -74.01455541, 40.7091624 ], [ -74.01454589, 40.7091859 ], [ -74.01453278, 40.70921817 ], [ -74.01452802, 40.70923036 ], [ -74.01435428, 40.70915587 ], [ -74.01438923, 40.70906257 ], [ -74.01439489, 40.70904732 ], [ -74.01440378, 40.70902369 ], [ -74.01442794, 40.70895941 ], [ -74.01461677, 40.70900578 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01377307, 40.70852571 ], [ -74.01350097, 40.70845782 ], [ -74.01355721, 40.70832728 ], [ -74.01384341, 40.70839871 ], [ -74.01387692, 40.70840709 ], [ -74.01384628, 40.70847818 ], [ -74.01379867, 40.70846626 ], [ -74.01377307, 40.70852571 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00766282, 40.70574258 ], [ -74.00748837, 40.70565916 ], [ -74.00754748, 40.70560019 ], [ -74.00756733, 40.7056117 ], [ -74.00759078, 40.70558807 ], [ -74.00769022, 40.70548878 ], [ -74.00782892, 40.70557697 ], [ -74.00783449, 40.70558276 ], [ -74.00767082, 40.7057464 ], [ -74.00766282, 40.70574258 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00774636, 40.71015842 ], [ -74.00763857, 40.71026649 ], [ -74.0075384, 40.71021446 ], [ -74.00742055, 40.71015672 ], [ -74.00740024, 40.71017681 ], [ -74.00737527, 40.71016339 ], [ -74.00740509, 40.71013527 ], [ -74.00747364, 40.7100541 ], [ -74.00750472, 40.71006929 ], [ -74.00751217, 40.71006159 ], [ -74.00757092, 40.71006282 ], [ -74.00762617, 40.71000998 ], [ -74.00764854, 40.71002312 ], [ -74.00765932, 40.71004116 ], [ -74.00760982, 40.71009387 ], [ -74.00774636, 40.71015842 ] ] ] } }, { "type": "Feature", "properties": { "height": 61.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00796897, 40.70933448 ], [ -74.00791453, 40.70938936 ], [ -74.00788435, 40.70937036 ], [ -74.00785084, 40.70940278 ], [ -74.00779568, 40.70937111 ], [ -74.00773738, 40.70942988 ], [ -74.00772265, 40.70944479 ], [ -74.00767872, 40.70948899 ], [ -74.00763021, 40.70946107 ], [ -74.00764575, 40.70944636 ], [ -74.00758655, 40.7094117 ], [ -74.00776155, 40.7092369 ], [ -74.00782748, 40.7092749 ], [ -74.00785102, 40.70925167 ], [ -74.00796897, 40.70933448 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01086307, 40.71028596 ], [ -74.01078698, 40.71038286 ], [ -74.01073317, 40.71035868 ], [ -74.01071808, 40.71035188 ], [ -74.01066445, 40.71032757 ], [ -74.01064945, 40.71032089 ], [ -74.01059555, 40.71029658 ], [ -74.01058055, 40.71028977 ], [ -74.01052692, 40.7102656 ], [ -74.01051192, 40.71025886 ], [ -74.01045811, 40.71023462 ], [ -74.01053464, 40.71013711 ], [ -74.01058836, 40.71016128 ], [ -74.01058324, 40.71016802 ], [ -74.01059825, 40.71017469 ], [ -74.01060328, 40.71016829 ], [ -74.01065691, 40.7101924 ], [ -74.0106517, 40.710199 ], [ -74.0106667, 40.71020581 ], [ -74.01067182, 40.71019928 ], [ -74.01072572, 40.71022359 ], [ -74.01072051, 40.71023019 ], [ -74.01073551, 40.710237 ], [ -74.01074063, 40.71023046 ], [ -74.01079435, 40.71025477 ], [ -74.01078914, 40.71026131 ], [ -74.01080423, 40.71026812 ], [ -74.01080917, 40.71026172 ], [ -74.01086307, 40.71028596 ] ] ] } }, { "type": "Feature", "properties": { "height": 96.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01125608, 40.7071439 ], [ -74.01115529, 40.7072978 ], [ -74.0109229, 40.70714281 ], [ -74.01098578, 40.7070425 ], [ -74.01125608, 40.7071439 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01025473, 40.71109498 ], [ -74.01014792, 40.71122899 ], [ -74.00994463, 40.71113658 ], [ -74.00993727, 40.71114571 ], [ -74.00991076, 40.71113359 ], [ -74.00994499, 40.71109062 ], [ -74.0100253, 40.71098991 ], [ -74.01025473, 40.71109498 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01259978, 40.70965588 ], [ -74.01253555, 40.70976729 ], [ -74.01249432, 40.70974911 ], [ -74.01244904, 40.70980869 ], [ -74.01251408, 40.70983736 ], [ -74.01243557, 40.70994059 ], [ -74.01229921, 40.7098806 ], [ -74.01237673, 40.70977859 ], [ -74.01242174, 40.70979847 ], [ -74.01243314, 40.70978349 ], [ -74.01240512, 40.7097711 ], [ -74.01244195, 40.70972282 ], [ -74.01238805, 40.70969906 ], [ -74.01246575, 40.70959692 ], [ -74.01259978, 40.70965588 ] ] ] } }, { "type": "Feature", "properties": { "height": 59.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00868852, 40.70980447 ], [ -74.00867513, 40.70981986 ], [ -74.00862168, 40.70988121 ], [ -74.00850364, 40.7097931 ], [ -74.00846214, 40.70982857 ], [ -74.0083114, 40.70973018 ], [ -74.00842289, 40.70961959 ], [ -74.00868852, 40.70980447 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00702987, 40.70948006 ], [ -74.00686215, 40.7096518 ], [ -74.0068396, 40.70967482 ], [ -74.00668788, 40.7095961 ], [ -74.00671025, 40.70957322 ], [ -74.0067345, 40.70954836 ], [ -74.00686404, 40.70941592 ], [ -74.00691479, 40.70944466 ], [ -74.00697112, 40.70947659 ], [ -74.0069898, 40.70945739 ], [ -74.00702987, 40.70948006 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0064792, 40.71072169 ], [ -74.00638874, 40.71078447 ], [ -74.00634023, 40.71081811 ], [ -74.00623405, 40.71089179 ], [ -74.00613029, 40.7107936 ], [ -74.00637527, 40.7106235 ], [ -74.0064792, 40.71072169 ] ] ] } }, { "type": "Feature", "properties": { "height": 71.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01389982, 40.70826756 ], [ -74.01384341, 40.70839871 ], [ -74.01355721, 40.70832728 ], [ -74.01361371, 40.7081962 ], [ -74.01389982, 40.70826756 ] ] ] } }, { "type": "Feature", "properties": { "height": 124.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01358245, 40.70644488 ], [ -74.0135537, 40.70648267 ], [ -74.01351337, 40.70649507 ], [ -74.01349019, 40.70648499 ], [ -74.01347321, 40.70650726 ], [ -74.01344492, 40.706495 ], [ -74.01342102, 40.70648458 ], [ -74.01325771, 40.70641328 ], [ -74.01322932, 40.70640089 ], [ -74.01324657, 40.70637821 ], [ -74.01321971, 40.7063665 ], [ -74.01321028, 40.70633177 ], [ -74.01323938, 40.70629357 ], [ -74.01327612, 40.70628839 ], [ -74.01357122, 40.70641716 ], [ -74.01358245, 40.70644488 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00550983, 40.7087014 ], [ -74.0054924, 40.7086839 ], [ -74.0054288, 40.70861948 ], [ -74.00515374, 40.70834281 ], [ -74.00523297, 40.70830937 ], [ -74.00555304, 40.70862282 ], [ -74.00558098, 40.70865026 ], [ -74.00550983, 40.7087014 ] ] ] } }, { "type": "Feature", "properties": { "height": 199.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01165583, 40.70747172 ], [ -74.01164478, 40.70747206 ], [ -74.01163508, 40.70747948 ], [ -74.01162232, 40.70746586 ], [ -74.01161002, 40.70746709 ], [ -74.01159169, 40.7074581 ], [ -74.01156914, 40.70745469 ], [ -74.01155585, 40.70743999 ], [ -74.01153743, 40.70743106 ], [ -74.01153384, 40.70742221 ], [ -74.01151165, 40.70741901 ], [ -74.01151659, 40.70740941 ], [ -74.0115121, 40.70740076 ], [ -74.01150833, 40.70739239 ], [ -74.01152773, 40.70738067 ], [ -74.01152612, 40.7073742 ], [ -74.01153052, 40.70736957 ], [ -74.01152378, 40.70736161 ], [ -74.01153133, 40.70735486 ], [ -74.01153411, 40.70734376 ], [ -74.01155289, 40.70733607 ], [ -74.01155675, 40.7073151 ], [ -74.01158181, 40.70730277 ], [ -74.0115837, 40.70728656 ], [ -74.011596, 40.70728016 ], [ -74.01160121, 40.7072724 ], [ -74.01161352, 40.7072739 ], [ -74.01161729, 40.70726899 ], [ -74.01162574, 40.7072675 ], [ -74.01163221, 40.70724938 ], [ -74.01164559, 40.70724891 ], [ -74.0116561, 40.70724836 ], [ -74.0116658, 40.70724101 ], [ -74.01167892, 40.70725476 ], [ -74.01169087, 40.70725388 ], [ -74.01170928, 40.70726287 ], [ -74.01173255, 40.70726586 ], [ -74.01174584, 40.70728016 ], [ -74.01176417, 40.70728908 ], [ -74.01176767, 40.70729807 ], [ -74.01178941, 40.70730148 ], [ -74.01178429, 40.70731121 ], [ -74.01178797, 40.70731918 ], [ -74.01179265, 40.70732817 ], [ -74.01177333, 40.70733988 ], [ -74.01177477, 40.70734628 ], [ -74.01177037, 40.70735098 ], [ -74.0117771, 40.70735888 ], [ -74.01176974, 40.70736556 ], [ -74.01176695, 40.70737666 ], [ -74.01174809, 40.70738449 ], [ -74.01174423, 40.70740539 ], [ -74.01171925, 40.70741779 ], [ -74.01171719, 40.70743386 ], [ -74.01170488, 40.70744026 ], [ -74.01169985, 40.70744809 ], [ -74.01168754, 40.70744666 ], [ -74.01168359, 40.70745156 ], [ -74.01167524, 40.70745299 ], [ -74.01166868, 40.70747117 ], [ -74.01165583, 40.70747172 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00747364, 40.71085359 ], [ -74.00727879, 40.71099597 ], [ -74.00714117, 40.7108877 ], [ -74.00733592, 40.71074539 ], [ -74.00747364, 40.71085359 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00857641, 40.71308721 ], [ -74.00829353, 40.71344667 ], [ -74.0082107, 40.71340901 ], [ -74.00849349, 40.71304936 ], [ -74.00857641, 40.71308721 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01421253, 40.70844638 ], [ -74.0141606, 40.70857508 ], [ -74.01389291, 40.70850862 ], [ -74.01386129, 40.70850072 ], [ -74.01390441, 40.70840171 ], [ -74.01388338, 40.70839667 ], [ -74.01389713, 40.70836718 ], [ -74.0139522, 40.70838039 ], [ -74.01394591, 40.7083949 ], [ -74.01410751, 40.70843562 ], [ -74.01411362, 40.70842139 ], [ -74.01421253, 40.70844638 ] ] ] } }, { "type": "Feature", "properties": { "height": 115.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00490167, 40.70648138 ], [ -74.00493042, 40.70650126 ], [ -74.00496168, 40.70651679 ], [ -74.00499303, 40.70652612 ], [ -74.00502555, 40.70652959 ], [ -74.00506292, 40.70652959 ], [ -74.00509193, 40.7065253 ], [ -74.00512247, 40.70651557 ], [ -74.00515463, 40.7064984 ], [ -74.00518482, 40.70647866 ], [ -74.00530061, 40.70639428 ], [ -74.00532603, 40.70639347 ], [ -74.00534714, 40.70638972 ], [ -74.00536592, 40.7063825 ], [ -74.00538344, 40.70637208 ], [ -74.00541533, 40.70639857 ], [ -74.00504881, 40.70665387 ], [ -74.00486879, 40.7065044 ], [ -74.00490167, 40.70648138 ] ] ] } }, { "type": "Feature", "properties": { "height": 82.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00732991, 40.70670617 ], [ -74.00731347, 40.70672306 ], [ -74.00724385, 40.70679511 ], [ -74.00721465, 40.70677917 ], [ -74.0072019, 40.70677229 ], [ -74.00717854, 40.70679402 ], [ -74.00715033, 40.70679722 ], [ -74.00703445, 40.70671959 ], [ -74.00703166, 40.7067029 ], [ -74.00714997, 40.70657992 ], [ -74.00717863, 40.7065808 ], [ -74.00731948, 40.70667199 ], [ -74.00732991, 40.70670617 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00693483, 40.71041466 ], [ -74.00658412, 40.71069847 ], [ -74.00651001, 40.71064549 ], [ -74.0066294, 40.71054696 ], [ -74.00664171, 40.71053682 ], [ -74.00668465, 40.71050141 ], [ -74.00670971, 40.71048071 ], [ -74.00682038, 40.71038939 ], [ -74.00684544, 40.71036876 ], [ -74.00693483, 40.71041466 ] ] ] } }, { "type": "Feature", "properties": { "height": 83.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00653499, 40.70740328 ], [ -74.00641892, 40.7074931 ], [ -74.0062592, 40.70736991 ], [ -74.00649079, 40.70724965 ], [ -74.00658933, 40.70736018 ], [ -74.00653499, 40.70740328 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01359395, 40.70767056 ], [ -74.01355092, 40.70777148 ], [ -74.01345722, 40.70773798 ], [ -74.01328268, 40.7076756 ], [ -74.01327927, 40.70768112 ], [ -74.01319878, 40.70765231 ], [ -74.01326714, 40.70755377 ], [ -74.01359395, 40.70767056 ] ] ] } }, { "type": "Feature", "properties": { "height": 119.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00610739, 40.70749487 ], [ -74.00607253, 40.70752231 ], [ -74.00600453, 40.7075787 ], [ -74.00599339, 40.70758741 ], [ -74.00594129, 40.70762957 ], [ -74.00576531, 40.7074534 ], [ -74.00593644, 40.70739218 ], [ -74.00605582, 40.70747642 ], [ -74.00606768, 40.70746641 ], [ -74.00610739, 40.70749487 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00628121, 40.70753151 ], [ -74.00596294, 40.7077723 ], [ -74.00592153, 40.7077313 ], [ -74.00605223, 40.70763236 ], [ -74.00599339, 40.70758741 ], [ -74.00600453, 40.7075787 ], [ -74.00607253, 40.70752231 ], [ -74.00610739, 40.70749487 ], [ -74.00611952, 40.70748486 ], [ -74.00613362, 40.70747376 ], [ -74.00614934, 40.70746096 ], [ -74.00616299, 40.70744986 ], [ -74.00628121, 40.70753151 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00875194, 40.70685061 ], [ -74.00874394, 40.7068585 ], [ -74.00873712, 40.70685449 ], [ -74.0085606, 40.70703706 ], [ -74.00843483, 40.7069661 ], [ -74.00861899, 40.70678496 ], [ -74.0086092, 40.70677917 ], [ -74.00861719, 40.70677127 ], [ -74.0086295, 40.70675922 ], [ -74.00876425, 40.70683848 ], [ -74.00875194, 40.70685061 ] ] ] } }, { "type": "Feature", "properties": { "height": 115.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00539987, 40.70624937 ], [ -74.00538065, 40.70623609 ], [ -74.00534589, 40.70622029 ], [ -74.00530753, 40.70620831 ], [ -74.00527716, 40.70620306 ], [ -74.00524141, 40.70620177 ], [ -74.00520997, 40.70620626 ], [ -74.00517988, 40.70621491 ], [ -74.00515535, 40.70622656 ], [ -74.00499977, 40.70633511 ], [ -74.00497488, 40.7063362 ], [ -74.00495305, 40.70634137 ], [ -74.00493913, 40.70634668 ], [ -74.00492098, 40.70635506 ], [ -74.00489188, 40.7063315 ], [ -74.0052539, 40.70607919 ], [ -74.00543239, 40.70622731 ], [ -74.00539987, 40.70624937 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00845882, 40.7108337 ], [ -74.00842073, 40.71087531 ], [ -74.00820783, 40.71076697 ], [ -74.00819085, 40.71078386 ], [ -74.00816121, 40.71076629 ], [ -74.00810578, 40.71082526 ], [ -74.00796591, 40.71075002 ], [ -74.00807425, 40.7106408 ], [ -74.00845882, 40.7108337 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00894723, 40.70953188 ], [ -74.00892675, 40.70955429 ], [ -74.0087858, 40.70970811 ], [ -74.00865303, 40.70961128 ], [ -74.00881311, 40.7094386 ], [ -74.00894723, 40.70953188 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0108478, 40.70578167 ], [ -74.01076857, 40.70575259 ], [ -74.01077027, 40.70571187 ], [ -74.01074593, 40.7057148 ], [ -74.01068664, 40.70542177 ], [ -74.01079812, 40.7054087 ], [ -74.0108063, 40.70544908 ], [ -74.01084124, 40.7056213 ], [ -74.01084528, 40.70564146 ], [ -74.0108575, 40.70570166 ], [ -74.0108478, 40.70578167 ] ] ] } }, { "type": "Feature", "properties": { "height": 38.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00867352, 40.7071772 ], [ -74.00861818, 40.70723052 ], [ -74.00861459, 40.70723229 ], [ -74.00860641, 40.7072342 ], [ -74.00860201, 40.70723406 ], [ -74.00859392, 40.70723202 ], [ -74.00826945, 40.70702521 ], [ -74.00834105, 40.70695098 ], [ -74.00852368, 40.70707526 ], [ -74.00867352, 40.7071772 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01345722, 40.70773798 ], [ -74.0133956, 40.70785946 ], [ -74.0131306, 40.7077774 ], [ -74.01319878, 40.70765231 ], [ -74.01327927, 40.70768112 ], [ -74.01328268, 40.7076756 ], [ -74.01345722, 40.70773798 ] ] ] } }, { "type": "Feature", "properties": { "height": 66.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0096613, 40.71220516 ], [ -74.00980189, 40.71203622 ], [ -74.00996251, 40.71211351 ], [ -74.00982192, 40.71228251 ], [ -74.0096613, 40.71220516 ] ] ] } }, { "type": "Feature", "properties": { "height": 225.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00838273, 40.70612271 ], [ -74.00827493, 40.70623269 ], [ -74.00806401, 40.70625632 ], [ -74.0083521, 40.70596247 ], [ -74.00838273, 40.70612271 ] ] ] } }, { "type": "Feature", "properties": { "height": 166.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00878401, 40.71196602 ], [ -74.00868699, 40.71208409 ], [ -74.00845558, 40.71197501 ], [ -74.0085526, 40.7118568 ], [ -74.00878401, 40.71196602 ] ] ] } }, { "type": "Feature", "properties": { "height": 225.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00882892, 40.70623119 ], [ -74.00854056, 40.70652496 ], [ -74.00850984, 40.70636507 ], [ -74.00861773, 40.70625516 ], [ -74.00882892, 40.70623119 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00766282, 40.70574258 ], [ -74.00755359, 40.70585161 ], [ -74.00753544, 40.70584078 ], [ -74.00747274, 40.70580367 ], [ -74.00735623, 40.70573462 ], [ -74.00731922, 40.70571262 ], [ -74.00731248, 40.7057086 ], [ -74.00740554, 40.70561858 ], [ -74.00743734, 40.70563778 ], [ -74.00748235, 40.70566509 ], [ -74.00748837, 40.70565916 ], [ -74.00766282, 40.70574258 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01486569, 40.70734696 ], [ -74.01480047, 40.7075106 ], [ -74.01477173, 40.70750039 ], [ -74.01457311, 40.70748377 ], [ -74.01460518, 40.70739851 ], [ -74.01463294, 40.7073247 ], [ -74.01486569, 40.70734696 ] ] ] } }, { "type": "Feature", "properties": { "height": 47.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00881311, 40.7094386 ], [ -74.00865303, 40.70961128 ], [ -74.00851559, 40.7095165 ], [ -74.00864854, 40.70936839 ], [ -74.008656, 40.70937227 ], [ -74.00866884, 40.70935797 ], [ -74.00881311, 40.7094386 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01280675, 40.70949042 ], [ -74.01275447, 40.70961857 ], [ -74.01248659, 40.7094975 ], [ -74.01257023, 40.70938691 ], [ -74.01280675, 40.70949042 ] ] ] } }, { "type": "Feature", "properties": { "height": 225.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00881284, 40.70617228 ], [ -74.00860165, 40.70619578 ], [ -74.00845873, 40.70611529 ], [ -74.00842747, 40.70595519 ], [ -74.00881284, 40.70617228 ] ] ] } }, { "type": "Feature", "properties": { "height": 59.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01017882, 40.7060192 ], [ -74.01016059, 40.7060493 ], [ -74.0099502, 40.7059716 ], [ -74.00973245, 40.70633238 ], [ -74.00996619, 40.70648049 ], [ -74.00994113, 40.7065078 ], [ -74.00967909, 40.70634171 ], [ -74.00983854, 40.7060777 ], [ -74.00992945, 40.70592706 ], [ -74.01017882, 40.7060192 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00730035, 40.70789092 ], [ -74.00720324, 40.7080013 ], [ -74.00712428, 40.7079727 ], [ -74.00713488, 40.70796051 ], [ -74.00705924, 40.70793191 ], [ -74.00706957, 40.70792 ], [ -74.00699438, 40.70789099 ], [ -74.00700292, 40.70788139 ], [ -74.0069377, 40.70785626 ], [ -74.00694282, 40.70785047 ], [ -74.00690563, 40.70783508 ], [ -74.00694839, 40.70777257 ], [ -74.00720935, 40.70787356 ], [ -74.00722328, 40.7078517 ], [ -74.00730035, 40.70789092 ] ] ] } }, { "type": "Feature", "properties": { "height": 118.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00680125, 40.70882077 ], [ -74.00660775, 40.70904038 ], [ -74.0064916, 40.70898011 ], [ -74.00651172, 40.70895778 ], [ -74.00660083, 40.7088538 ], [ -74.00665671, 40.7087919 ], [ -74.00667081, 40.7087763 ], [ -74.006685, 40.7087605 ], [ -74.00680125, 40.70882077 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00909447, 40.70937111 ], [ -74.00894723, 40.70953188 ], [ -74.00881311, 40.7094386 ], [ -74.00884545, 40.70940421 ], [ -74.00898038, 40.7092608 ], [ -74.00898254, 40.70925848 ], [ -74.00909447, 40.70937111 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01146557, 40.7068376 ], [ -74.01143494, 40.70682677 ], [ -74.01133864, 40.70679272 ], [ -74.01136469, 40.70675377 ], [ -74.01138077, 40.7067328 ], [ -74.0114088, 40.70674512 ], [ -74.0115112, 40.70661172 ], [ -74.01154264, 40.70657079 ], [ -74.01139559, 40.70650596 ], [ -74.01129444, 40.7066378 ], [ -74.0112648, 40.70662588 ], [ -74.01136981, 40.70646837 ], [ -74.01158864, 40.7065633 ], [ -74.01158055, 40.7065742 ], [ -74.01156879, 40.70658959 ], [ -74.0115572, 40.70660511 ], [ -74.01159232, 40.70661928 ], [ -74.01146557, 40.7068376 ] ] ] } }, { "type": "Feature", "properties": { "height": 82.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00704352, 40.70812926 ], [ -74.00701576, 40.70816828 ], [ -74.00691255, 40.70831216 ], [ -74.00681957, 40.7082553 ], [ -74.00683134, 40.70824359 ], [ -74.00675094, 40.70819388 ], [ -74.00690051, 40.70806082 ], [ -74.00698253, 40.70811046 ], [ -74.00699358, 40.70809882 ], [ -74.00704352, 40.70812926 ] ] ] } }, { "type": "Feature", "properties": { "height": 79.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00900957, 40.70849861 ], [ -74.00894382, 40.70854437 ], [ -74.00892397, 40.70855819 ], [ -74.00863965, 40.70832347 ], [ -74.00865977, 40.70830937 ], [ -74.00872517, 40.70826388 ], [ -74.00900957, 40.70849861 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0115112, 40.70661172 ], [ -74.0114088, 40.70674512 ], [ -74.01138077, 40.7067328 ], [ -74.01136469, 40.70675377 ], [ -74.01126659, 40.7067106 ], [ -74.0112868, 40.70668431 ], [ -74.01126578, 40.70667498 ], [ -74.01127252, 40.70666627 ], [ -74.01129444, 40.7066378 ], [ -74.01139559, 40.70650596 ], [ -74.01154264, 40.70657079 ], [ -74.0115112, 40.70661172 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0090677, 40.71400637 ], [ -74.00892747, 40.71418231 ], [ -74.00877449, 40.71411177 ], [ -74.0089148, 40.71393576 ], [ -74.0090677, 40.71400637 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01122913, 40.71384302 ], [ -74.01121449, 40.71391152 ], [ -74.01118017, 40.71390628 ], [ -74.01102243, 40.7138821 ], [ -74.01123344, 40.71361648 ], [ -74.0112921, 40.71362411 ], [ -74.01122913, 40.71384302 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0088919, 40.70576397 ], [ -74.00882794, 40.7058939 ], [ -74.00878554, 40.7059052 ], [ -74.00848011, 40.70575906 ], [ -74.00849601, 40.70573748 ], [ -74.00852898, 40.70569301 ], [ -74.00874547, 40.70579577 ], [ -74.00878814, 40.70578596 ], [ -74.00881437, 40.70573938 ], [ -74.00886899, 40.70575668 ], [ -74.0088919, 40.70576397 ] ] ] } }, { "type": "Feature", "properties": { "height": 34.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00702987, 40.70948006 ], [ -74.00686215, 40.7096518 ], [ -74.00671025, 40.70957322 ], [ -74.0067345, 40.70954836 ], [ -74.00686404, 40.70941592 ], [ -74.00691479, 40.70944466 ], [ -74.00697112, 40.70947659 ], [ -74.0069898, 40.70945739 ], [ -74.00702987, 40.70948006 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00903787, 40.71183188 ], [ -74.0089855, 40.71189459 ], [ -74.00877925, 40.71179572 ], [ -74.00872193, 40.71186429 ], [ -74.00862141, 40.71181588 ], [ -74.00873101, 40.71168459 ], [ -74.00903787, 40.71183188 ] ] ] } }, { "type": "Feature", "properties": { "height": 36.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00590518, 40.70891059 ], [ -74.00591407, 40.70891672 ], [ -74.00587508, 40.7089494 ], [ -74.00593168, 40.70898808 ], [ -74.00594201, 40.70899509 ], [ -74.00590455, 40.70902669 ], [ -74.00603157, 40.70911351 ], [ -74.00596177, 40.70917221 ], [ -74.00584068, 40.7090894 ], [ -74.00579738, 40.7091259 ], [ -74.00570449, 40.70906237 ], [ -74.00585487, 40.70893592 ], [ -74.00583628, 40.70892318 ], [ -74.00587553, 40.70889029 ], [ -74.00590518, 40.70891059 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00693483, 40.71041466 ], [ -74.00658412, 40.71069847 ], [ -74.00651001, 40.71064549 ], [ -74.0066294, 40.71054696 ], [ -74.0066621, 40.71056746 ], [ -74.0067407, 40.71050141 ], [ -74.00670971, 40.71048071 ], [ -74.00682038, 40.71038939 ], [ -74.00684544, 40.71036876 ], [ -74.00693483, 40.71041466 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0079731, 40.71384472 ], [ -74.00783952, 40.71401529 ], [ -74.00768339, 40.71394447 ], [ -74.00781715, 40.71377398 ], [ -74.0079731, 40.71384472 ] ] ] } }, { "type": "Feature", "properties": { "height": 237.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00831751, 40.71240167 ], [ -74.00826658, 40.71246609 ], [ -74.00817001, 40.71248461 ], [ -74.00808458, 40.71244579 ], [ -74.00806104, 40.71237511 ], [ -74.00811288, 40.71230947 ], [ -74.00821016, 40.71229082 ], [ -74.00829299, 40.7123284 ], [ -74.00831751, 40.71240167 ] ] ] } }, { "type": "Feature", "properties": { "height": 89.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00864773, 40.71311956 ], [ -74.00850212, 40.7133047 ], [ -74.00835713, 40.71348888 ], [ -74.00828481, 40.71345708 ], [ -74.00829353, 40.71344667 ], [ -74.00857641, 40.71308721 ], [ -74.00864773, 40.71311956 ] ] ] } }, { "type": "Feature", "properties": { "height": 61.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00686404, 40.70941592 ], [ -74.0067345, 40.70954836 ], [ -74.00671025, 40.70957322 ], [ -74.00668788, 40.7095961 ], [ -74.00668267, 40.70959337 ], [ -74.00655798, 40.70952862 ], [ -74.00673783, 40.70934456 ], [ -74.00675777, 40.70935566 ], [ -74.00677546, 40.70936567 ], [ -74.00680439, 40.7093818 ], [ -74.00681813, 40.7093895 ], [ -74.0068626, 40.70941517 ], [ -74.00686404, 40.70941592 ] ] ] } }, { "type": "Feature", "properties": { "height": 101.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0060976, 40.70833756 ], [ -74.00602681, 40.70828758 ], [ -74.00593913, 40.70833348 ], [ -74.00592871, 40.70833858 ], [ -74.00583187, 40.70822629 ], [ -74.00600929, 40.70815602 ], [ -74.00618491, 40.70826531 ], [ -74.0060976, 40.70833756 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00829721, 40.70904058 ], [ -74.00811899, 40.7092162 ], [ -74.00800499, 40.70913407 ], [ -74.00819103, 40.70895076 ], [ -74.00828742, 40.7090305 ], [ -74.00829721, 40.70904058 ] ] ] } }, { "type": "Feature", "properties": { "height": 113.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00482962, 40.70749678 ], [ -74.00462544, 40.70757849 ], [ -74.00453183, 40.70744189 ], [ -74.00473674, 40.7073612 ], [ -74.00482962, 40.70749678 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01282634, 40.71365809 ], [ -74.01274324, 40.71376186 ], [ -74.0125519, 40.71367136 ], [ -74.01252298, 40.71365638 ], [ -74.01255541, 40.71353089 ], [ -74.01257912, 40.71354111 ], [ -74.01282634, 40.71365809 ] ] ] } }, { "type": "Feature", "properties": { "height": 225.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00846035, 40.70653061 ], [ -74.00808144, 40.70631168 ], [ -74.00828239, 40.706295 ], [ -74.00842531, 40.70637549 ], [ -74.00846035, 40.70653061 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00941894, 40.70961762 ], [ -74.00933647, 40.70971676 ], [ -74.0092108, 40.70964826 ], [ -74.00916687, 40.7096949 ], [ -74.0092488, 40.7097395 ], [ -74.00920783, 40.70978309 ], [ -74.0091322, 40.70974196 ], [ -74.00911171, 40.70972629 ], [ -74.00913202, 40.70970471 ], [ -74.00910785, 40.7096915 ], [ -74.00913211, 40.70966562 ], [ -74.00914459, 40.70965228 ], [ -74.00921825, 40.7095741 ], [ -74.00925203, 40.70953808 ], [ -74.00926847, 40.70952058 ], [ -74.00941894, 40.70961762 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01264425, 40.70620327 ], [ -74.01257274, 40.70629506 ], [ -74.01250905, 40.7062666 ], [ -74.01237583, 40.70620701 ], [ -74.0122922, 40.70616956 ], [ -74.0123637, 40.70607776 ], [ -74.01242021, 40.7061031 ], [ -74.01258945, 40.70617882 ], [ -74.01264425, 40.70620327 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00898038, 40.7092608 ], [ -74.00884545, 40.70940421 ], [ -74.00869894, 40.70932746 ], [ -74.00886566, 40.70916492 ], [ -74.00889082, 40.70915757 ], [ -74.00898038, 40.7092608 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00621698, 40.70841472 ], [ -74.00619767, 40.70840191 ], [ -74.00635308, 40.70825878 ], [ -74.00627843, 40.7082109 ], [ -74.00608619, 40.70809487 ], [ -74.00601944, 40.70805851 ], [ -74.00595521, 40.70808329 ], [ -74.00571437, 40.70818081 ], [ -74.00563694, 40.70821281 ], [ -74.00560954, 40.70818748 ], [ -74.00597785, 40.70803399 ], [ -74.00604792, 40.70803311 ], [ -74.00637778, 40.70823481 ], [ -74.00638667, 40.7082677 ], [ -74.00621698, 40.70841472 ] ] ] } }, { "type": "Feature", "properties": { "height": 149.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01422259, 40.70830488 ], [ -74.0141916, 40.70837706 ], [ -74.01392489, 40.70830951 ], [ -74.01397654, 40.70819449 ], [ -74.01398274, 40.7081804 ], [ -74.01405963, 40.70820369 ], [ -74.01410168, 40.70821581 ], [ -74.01409242, 40.70823549 ], [ -74.01423669, 40.70827226 ], [ -74.01422259, 40.70830488 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00896987, 40.71000051 ], [ -74.00889594, 40.71008556 ], [ -74.00872957, 40.7102769 ], [ -74.00864585, 40.71023469 ], [ -74.00869175, 40.71018191 ], [ -74.00875239, 40.71011212 ], [ -74.00881752, 40.71003721 ], [ -74.00887914, 40.7099664 ], [ -74.00889495, 40.70994821 ], [ -74.00896987, 40.71000051 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01334853, 40.71388701 ], [ -74.01331772, 40.71402196 ], [ -74.01329912, 40.71401386 ], [ -74.01306762, 40.71391077 ], [ -74.01315755, 40.71379651 ], [ -74.01333083, 40.71387829 ], [ -74.01334853, 40.71388701 ] ] ] } }, { "type": "Feature", "properties": { "height": 125.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00660083, 40.7088538 ], [ -74.00651172, 40.70895778 ], [ -74.0064916, 40.70898011 ], [ -74.00629523, 40.70887851 ], [ -74.00637149, 40.70881457 ], [ -74.00640734, 40.70878468 ], [ -74.00642961, 40.70876629 ], [ -74.00648935, 40.70879619 ], [ -74.00660083, 40.7088538 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00459615, 40.70586516 ], [ -74.0044791, 40.70576846 ], [ -74.00442933, 40.7058034 ], [ -74.00424877, 40.70565406 ], [ -74.00434822, 40.70559127 ], [ -74.00453498, 40.70574749 ], [ -74.00464008, 40.70583438 ], [ -74.00459615, 40.70586516 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0054694, 40.70793947 ], [ -74.00543365, 40.70787778 ], [ -74.00547291, 40.70785476 ], [ -74.00542152, 40.70779947 ], [ -74.00537634, 40.70775078 ], [ -74.00535074, 40.70769841 ], [ -74.00542691, 40.70765136 ], [ -74.00562338, 40.7078536 ], [ -74.0054694, 40.70793947 ] ] ] } }, { "type": "Feature", "properties": { "height": 53.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00709868, 40.70998778 ], [ -74.00684464, 40.71024667 ], [ -74.00676954, 40.71020867 ], [ -74.00700409, 40.70993997 ], [ -74.00709868, 40.70998778 ] ] ] } }, { "type": "Feature", "properties": { "height": 52.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01095748, 40.70584419 ], [ -74.01092011, 40.70583949 ], [ -74.01092371, 40.70570969 ], [ -74.01116778, 40.70572127 ], [ -74.01114981, 40.70586598 ], [ -74.01095748, 40.70584419 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01051964, 40.71013016 ], [ -74.0104432, 40.71022788 ], [ -74.01029524, 40.71041636 ], [ -74.01021134, 40.7103783 ], [ -74.01043547, 40.7100921 ], [ -74.01051964, 40.71013016 ] ] ] } }, { "type": "Feature", "properties": { "height": 38.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00623594, 40.70842731 ], [ -74.00621698, 40.70841472 ], [ -74.00638667, 40.7082677 ], [ -74.00637778, 40.70823481 ], [ -74.00604792, 40.70803311 ], [ -74.00597785, 40.70803399 ], [ -74.00560954, 40.70818748 ], [ -74.0055825, 40.70816249 ], [ -74.005973, 40.70799831 ], [ -74.00605034, 40.70800321 ], [ -74.0064023, 40.70822486 ], [ -74.00641398, 40.70827491 ], [ -74.00623594, 40.70842731 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0100386, 40.70951758 ], [ -74.00990591, 40.70966446 ], [ -74.0097497, 40.70958336 ], [ -74.00978267, 40.70954687 ], [ -74.00970757, 40.70950778 ], [ -74.00974925, 40.70946182 ], [ -74.00989289, 40.70953638 ], [ -74.00995092, 40.7094721 ], [ -74.0100386, 40.70951758 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00911099, 40.70671128 ], [ -74.00909078, 40.70670065 ], [ -74.00906338, 40.70668629 ], [ -74.0090862, 40.70666129 ], [ -74.00909815, 40.70666735 ], [ -74.00916849, 40.70658782 ], [ -74.00913408, 40.70657032 ], [ -74.00919148, 40.70650542 ], [ -74.00922598, 40.70652292 ], [ -74.00930225, 40.70643678 ], [ -74.00925598, 40.70640988 ], [ -74.0091392, 40.70634171 ], [ -74.00909698, 40.70631699 ], [ -74.00908791, 40.70632632 ], [ -74.00904919, 40.70630671 ], [ -74.00908863, 40.7062602 ], [ -74.00917262, 40.70631039 ], [ -74.0092885, 40.70637957 ], [ -74.00936863, 40.70642738 ], [ -74.00911099, 40.70671128 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00550983, 40.7087014 ], [ -74.00532774, 40.70883228 ], [ -74.0052981, 40.70884052 ], [ -74.00519919, 40.7087157 ], [ -74.00540823, 40.70862799 ], [ -74.00544479, 40.70867872 ], [ -74.00545027, 40.70867641 ], [ -74.00546428, 40.70869568 ], [ -74.0054924, 40.7086839 ], [ -74.00550983, 40.7087014 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01006536, 40.70691809 ], [ -74.0099741, 40.70700968 ], [ -74.00994858, 40.70699511 ], [ -74.00999045, 40.70695309 ], [ -74.01000212, 40.70694077 ], [ -74.00962744, 40.70672796 ], [ -74.00961567, 40.70673967 ], [ -74.00955099, 40.70680062 ], [ -74.0095279, 40.70678741 ], [ -74.00963974, 40.70666906 ], [ -74.00965699, 40.7066792 ], [ -74.00976515, 40.70674247 ], [ -74.00978473, 40.70675397 ], [ -74.00991624, 40.70683018 ], [ -74.00993628, 40.70684209 ], [ -74.01004416, 40.7069057 ], [ -74.01006536, 40.70691809 ] ] ] } }, { "type": "Feature", "properties": { "height": 33.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00740258, 40.7101414 ], [ -74.00739467, 40.71014936 ], [ -74.00714934, 40.7104007 ], [ -74.0070685, 40.71035991 ], [ -74.00731966, 40.71009952 ], [ -74.00740258, 40.7101414 ] ] ] } }, { "type": "Feature", "properties": { "height": 121.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01342102, 40.70648458 ], [ -74.0133302, 40.70660416 ], [ -74.01313275, 40.70651802 ], [ -74.01322348, 40.7063983 ], [ -74.01322932, 40.70640089 ], [ -74.01325771, 40.70641328 ], [ -74.01342102, 40.70648458 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01036325, 40.7080901 ], [ -74.01031995, 40.70812967 ], [ -74.01026973, 40.70811802 ], [ -74.01025212, 40.70810747 ], [ -74.01024458, 40.70811482 ], [ -74.01005, 40.70799068 ], [ -74.01008728, 40.70794928 ], [ -74.01012465, 40.70790788 ], [ -74.01033019, 40.70803522 ], [ -74.0103204, 40.70804468 ], [ -74.01033567, 40.70805381 ], [ -74.01036325, 40.7080901 ] ] ] } }, { "type": "Feature", "properties": { "height": 121.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01314434, 40.70678666 ], [ -74.01312862, 40.70680757 ], [ -74.01308622, 40.706863 ], [ -74.01290548, 40.70678367 ], [ -74.01288149, 40.70681506 ], [ -74.01279184, 40.7067757 ], [ -74.01285832, 40.70668881 ], [ -74.01287395, 40.70666797 ], [ -74.01314434, 40.70678666 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00813093, 40.70940489 ], [ -74.00788857, 40.7096471 ], [ -74.00781149, 40.70960638 ], [ -74.00783745, 40.70958016 ], [ -74.00788758, 40.70952971 ], [ -74.00788057, 40.70952569 ], [ -74.00805467, 40.70935028 ], [ -74.00813093, 40.70940489 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01096646, 40.70843412 ], [ -74.01092128, 40.70848771 ], [ -74.01089442, 40.70851958 ], [ -74.01068942, 40.70839538 ], [ -74.01070011, 40.70838496 ], [ -74.01067793, 40.70837168 ], [ -74.01065403, 40.70834471 ], [ -74.0107029, 40.70829997 ], [ -74.01074764, 40.70831237 ], [ -74.01076605, 40.70832326 ], [ -74.01077432, 40.70831516 ], [ -74.01096646, 40.70843412 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01214029, 40.70945358 ], [ -74.011937, 40.70972112 ], [ -74.01193233, 40.70972732 ], [ -74.01184502, 40.70968891 ], [ -74.01184089, 40.70967992 ], [ -74.01183963, 40.70967039 ], [ -74.01192335, 40.70954659 ], [ -74.0119309, 40.70954986 ], [ -74.01196719, 40.70956586 ], [ -74.01207463, 40.7094247 ], [ -74.01214029, 40.70945358 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00717764, 40.71002768 ], [ -74.0069253, 40.71028746 ], [ -74.00684464, 40.71024667 ], [ -74.00709868, 40.70998778 ], [ -74.00717764, 40.71002768 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01420399, 40.70798408 ], [ -74.01416447, 40.70797059 ], [ -74.01415827, 40.70796848 ], [ -74.01406448, 40.70793648 ], [ -74.0140599, 40.70793491 ], [ -74.01398588, 40.70790971 ], [ -74.01394887, 40.70789712 ], [ -74.01400933, 40.7077964 ], [ -74.01404625, 40.70780907 ], [ -74.01422447, 40.70787049 ], [ -74.014264, 40.70788411 ], [ -74.01420399, 40.70798408 ] ] ] } }, { "type": "Feature", "properties": { "height": 89.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01272294, 40.70748241 ], [ -74.01266617, 40.70756767 ], [ -74.01238679, 40.70747158 ], [ -74.01242668, 40.70739218 ], [ -74.01260876, 40.70743086 ], [ -74.01272294, 40.70748241 ] ] ] } }, { "type": "Feature", "properties": { "height": 97.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0101313, 40.70609778 ], [ -74.01011405, 40.70612652 ], [ -74.01001353, 40.70608927 ], [ -74.00988319, 40.70630528 ], [ -74.01003743, 40.706403 ], [ -74.01001254, 40.7064301 ], [ -74.01000365, 40.70643977 ], [ -74.00980279, 40.7063125 ], [ -74.00988992, 40.70616806 ], [ -74.00990933, 40.70617439 ], [ -74.00998784, 40.70604467 ], [ -74.0101313, 40.70609778 ] ] ] } }, { "type": "Feature", "properties": { "height": 119.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00842073, 40.71087531 ], [ -74.00834464, 40.7109622 ], [ -74.00832668, 40.71095266 ], [ -74.00829344, 40.71093612 ], [ -74.00809491, 40.71083691 ], [ -74.00810578, 40.71082526 ], [ -74.00816121, 40.71076629 ], [ -74.00819085, 40.71078386 ], [ -74.00820783, 40.71076697 ], [ -74.00842073, 40.71087531 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00869175, 40.71018191 ], [ -74.00864585, 40.71023469 ], [ -74.00848774, 40.71015508 ], [ -74.00841534, 40.71011859 ], [ -74.0084899, 40.71003285 ], [ -74.00858198, 40.7099269 ], [ -74.0086454, 40.70995897 ], [ -74.00852601, 40.71009645 ], [ -74.00869175, 40.71018191 ] ] ] } }, { "type": "Feature", "properties": { "height": 36.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0061099, 40.71028167 ], [ -74.00606768, 40.71032389 ], [ -74.00603229, 40.71030339 ], [ -74.00595764, 40.71037796 ], [ -74.00581238, 40.71028848 ], [ -74.00592763, 40.71016911 ], [ -74.00594659, 40.71018076 ], [ -74.0059686, 40.71019437 ], [ -74.00606562, 40.71025477 ], [ -74.0061099, 40.71028167 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01342399, 40.7062096 ], [ -74.01336479, 40.70628907 ], [ -74.01329759, 40.70625959 ], [ -74.01323552, 40.70623269 ], [ -74.01320183, 40.70627736 ], [ -74.0131721, 40.70631631 ], [ -74.01313814, 40.70636098 ], [ -74.01307158, 40.7063317 ], [ -74.01310464, 40.70629282 ], [ -74.01320749, 40.70617092 ], [ -74.01324181, 40.7061302 ], [ -74.01342399, 40.7062096 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01482383, 40.70820008 ], [ -74.01500987, 40.70826606 ], [ -74.01512162, 40.70830576 ], [ -74.01508892, 40.70838789 ], [ -74.01478413, 40.7082935 ], [ -74.01482383, 40.70820008 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00725328, 40.71006588 ], [ -74.0070031, 40.71032682 ], [ -74.0069253, 40.71028746 ], [ -74.00717764, 40.71002768 ], [ -74.00725328, 40.71006588 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01323121, 40.7080852 ], [ -74.01315961, 40.70826327 ], [ -74.01315225, 40.70828159 ], [ -74.01299324, 40.7082378 ], [ -74.01300402, 40.7082235 ], [ -74.0131217, 40.70805176 ], [ -74.01323121, 40.7080852 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00912411, 40.70994569 ], [ -74.00912339, 40.70994631 ], [ -74.0089519, 40.70984641 ], [ -74.00908782, 40.7097124 ], [ -74.00911171, 40.70972629 ], [ -74.00912914, 40.7097489 ], [ -74.0091021, 40.70977662 ], [ -74.00922301, 40.70984437 ], [ -74.00912411, 40.70994569 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00872957, 40.7102769 ], [ -74.00851712, 40.71052116 ], [ -74.00843331, 40.71047901 ], [ -74.00862869, 40.7102543 ], [ -74.00864585, 40.71023469 ], [ -74.00872957, 40.7102769 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00715446, 40.70871679 ], [ -74.00697417, 40.70889976 ], [ -74.00687114, 40.70884147 ], [ -74.00705152, 40.70865836 ], [ -74.00715446, 40.70871679 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01223102, 40.70682868 ], [ -74.0121597, 40.70691659 ], [ -74.01191679, 40.70680491 ], [ -74.01197572, 40.70671639 ], [ -74.01223102, 40.70682868 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00501773, 40.70601886 ], [ -74.00498018, 40.70598787 ], [ -74.00481274, 40.70584929 ], [ -74.00478983, 40.70583036 ], [ -74.00487238, 40.70577262 ], [ -74.00489682, 40.70579087 ], [ -74.00506426, 40.70592951 ], [ -74.00510163, 40.70596132 ], [ -74.00501773, 40.70601886 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00532217, 40.70968796 ], [ -74.00520871, 40.70978097 ], [ -74.00507774, 40.70968871 ], [ -74.00506651, 40.70968081 ], [ -74.005071, 40.70967706 ], [ -74.00505789, 40.7096678 ], [ -74.00508205, 40.70964812 ], [ -74.00506759, 40.70963791 ], [ -74.00507343, 40.70963321 ], [ -74.0050657, 40.70962776 ], [ -74.00511089, 40.70959072 ], [ -74.00512014, 40.70959726 ], [ -74.00515122, 40.70957179 ], [ -74.0051647, 40.70958139 ], [ -74.00516811, 40.7095786 ], [ -74.00518832, 40.70959276 ], [ -74.00532217, 40.70968796 ] ] ] } }, { "type": "Feature", "properties": { "height": 73.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00619767, 40.70840191 ], [ -74.00617575, 40.70838829 ], [ -74.00630421, 40.7082681 ], [ -74.00625336, 40.70823658 ], [ -74.00606355, 40.70811836 ], [ -74.00602331, 40.70809337 ], [ -74.00597174, 40.70811291 ], [ -74.0057318, 40.70820382 ], [ -74.00565751, 40.70823188 ], [ -74.00563694, 40.70821281 ], [ -74.00571437, 40.70818081 ], [ -74.00595521, 40.70808329 ], [ -74.00601944, 40.70805851 ], [ -74.00608619, 40.70809487 ], [ -74.00627843, 40.7082109 ], [ -74.00635308, 40.70825878 ], [ -74.00619767, 40.70840191 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00840115, 40.71013486 ], [ -74.00832263, 40.71022522 ], [ -74.00829182, 40.71020758 ], [ -74.00832353, 40.71017551 ], [ -74.00803113, 40.71000827 ], [ -74.00808701, 40.70995278 ], [ -74.00840115, 40.71013486 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01376427, 40.70727111 ], [ -74.01352864, 40.70717652 ], [ -74.01359592, 40.70707928 ], [ -74.01381188, 40.70715949 ], [ -74.01376427, 40.70727111 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01274324, 40.71376186 ], [ -74.01267785, 40.71384676 ], [ -74.01264272, 40.71388796 ], [ -74.01250851, 40.71382886 ], [ -74.0125519, 40.71367136 ], [ -74.01274324, 40.71376186 ] ] ] } }, { "type": "Feature", "properties": { "height": 6.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00666973, 40.70750597 ], [ -74.00653499, 40.70740328 ], [ -74.00658933, 40.70736018 ], [ -74.00649079, 40.70724965 ], [ -74.0065667, 40.70721036 ], [ -74.00667692, 40.70732511 ], [ -74.00662275, 40.70735541 ], [ -74.00671186, 40.70742711 ], [ -74.00674277, 40.70745061 ], [ -74.00666973, 40.70750597 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01036235, 40.7064158 ], [ -74.01032147, 40.70645162 ], [ -74.01024763, 40.70651638 ], [ -74.01023452, 40.70650767 ], [ -74.01018798, 40.70647709 ], [ -74.01013912, 40.70651911 ], [ -74.01006069, 40.70647008 ], [ -74.01014828, 40.70639456 ], [ -74.0101852, 40.7064205 ], [ -74.01024063, 40.7063729 ], [ -74.01020371, 40.70634839 ], [ -74.01024512, 40.70631086 ], [ -74.01031528, 40.70635731 ], [ -74.01029605, 40.70637426 ], [ -74.01036235, 40.7064158 ] ] ] } }, { "type": "Feature", "properties": { "height": 47.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01248129, 40.7092512 ], [ -74.01243602, 40.70931119 ], [ -74.0123894, 40.7093707 ], [ -74.01224791, 40.70930819 ], [ -74.01221342, 40.70929287 ], [ -74.01230522, 40.7091735 ], [ -74.01233972, 40.70918862 ], [ -74.01248129, 40.7092512 ] ] ] } }, { "type": "Feature", "properties": { "height": 157.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726217, 40.70725367 ], [ -74.00715357, 40.70733491 ], [ -74.00709437, 40.70728935 ], [ -74.00693644, 40.7074075 ], [ -74.00690177, 40.70738088 ], [ -74.00701747, 40.70729446 ], [ -74.00703077, 40.70730468 ], [ -74.0070729, 40.70727328 ], [ -74.00711018, 40.70724536 ], [ -74.00704083, 40.70719211 ], [ -74.00711251, 40.70713852 ], [ -74.00726217, 40.70725367 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00822157, 40.71292536 ], [ -74.00820621, 40.71294388 ], [ -74.00772867, 40.7127279 ], [ -74.00748172, 40.71304146 ], [ -74.00747103, 40.71305508 ], [ -74.00776523, 40.71318819 ], [ -74.00775472, 40.71320161 ], [ -74.00743995, 40.71305787 ], [ -74.00772283, 40.71269828 ], [ -74.00822157, 40.71292536 ] ] ] } }, { "type": "Feature", "properties": { "height": 64.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00682038, 40.71038939 ], [ -74.00670971, 40.71048071 ], [ -74.00668465, 40.71050141 ], [ -74.00653624, 40.71039791 ], [ -74.00665177, 40.71030428 ], [ -74.00682038, 40.71038939 ] ] ] } }, { "type": "Feature", "properties": { "height": 104.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01337143, 40.70800791 ], [ -74.01333505, 40.70809242 ], [ -74.01328178, 40.70807567 ], [ -74.0132401, 40.7080632 ], [ -74.01313509, 40.70803168 ], [ -74.01310365, 40.70802221 ], [ -74.01304157, 40.7080041 ], [ -74.01309655, 40.70791986 ], [ -74.01337143, 40.70800791 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01272438, 40.70623916 ], [ -74.01257508, 40.70642547 ], [ -74.0124388, 40.70636269 ], [ -74.01250905, 40.7062666 ], [ -74.01257274, 40.70629506 ], [ -74.01264425, 40.70620327 ], [ -74.01272438, 40.70623916 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.013014, 40.70701179 ], [ -74.01293189, 40.70711687 ], [ -74.01273803, 40.70702766 ], [ -74.01281798, 40.70692306 ], [ -74.013014, 40.70701179 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00931913, 40.71240119 ], [ -74.00928644, 40.71244089 ], [ -74.00881994, 40.71222361 ], [ -74.00885659, 40.71217976 ], [ -74.00891741, 40.71220877 ], [ -74.0089343, 40.71220659 ], [ -74.00893825, 40.71221891 ], [ -74.00899897, 40.71224792 ], [ -74.00901667, 40.71224567 ], [ -74.00902044, 40.71225807 ], [ -74.00908117, 40.71228707 ], [ -74.00909869, 40.71228489 ], [ -74.00910237, 40.71229729 ], [ -74.00916319, 40.71232629 ], [ -74.00918061, 40.71232411 ], [ -74.0091843, 40.71233651 ], [ -74.00924493, 40.71236572 ], [ -74.00926218, 40.71236347 ], [ -74.00926613, 40.7123758 ], [ -74.00931913, 40.71240119 ] ] ] } }, { "type": "Feature", "properties": { "height": 96.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.011263, 40.70783706 ], [ -74.01119697, 40.70780376 ], [ -74.01117981, 40.70779511 ], [ -74.01113041, 40.70777019 ], [ -74.01105531, 40.70773226 ], [ -74.01113382, 40.70765006 ], [ -74.01116535, 40.70761717 ], [ -74.01120838, 40.70764332 ], [ -74.01125357, 40.70767049 ], [ -74.01121889, 40.7077059 ], [ -74.01124827, 40.7077232 ], [ -74.0113301, 40.70777128 ], [ -74.011263, 40.70783706 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01019257, 40.71028562 ], [ -74.01014388, 40.71034779 ], [ -74.01013579, 40.71034411 ], [ -74.00981707, 40.71019948 ], [ -74.00986567, 40.71013738 ], [ -74.01019257, 40.71028562 ] ] ] } }, { "type": "Feature", "properties": { "height": 86.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00594174, 40.7095485 ], [ -74.00587436, 40.70962456 ], [ -74.0056258, 40.70949831 ], [ -74.00569308, 40.70942218 ], [ -74.00594174, 40.7095485 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01194734, 40.70668091 ], [ -74.0116888, 40.7070837 ], [ -74.01168305, 40.70708091 ], [ -74.01163715, 40.70705939 ], [ -74.01189353, 40.70665721 ], [ -74.01194734, 40.70668091 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00671186, 40.70742711 ], [ -74.00662275, 40.70735541 ], [ -74.00667692, 40.70732511 ], [ -74.00674501, 40.70728697 ], [ -74.00675912, 40.70730127 ], [ -74.00683502, 40.70725919 ], [ -74.00682209, 40.70724897 ], [ -74.00691785, 40.70718387 ], [ -74.0069351, 40.70719702 ], [ -74.00697543, 40.70722759 ], [ -74.00671186, 40.70742711 ] ] ] } }, { "type": "Feature", "properties": { "height": 51.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01373408, 40.70879707 ], [ -74.01372843, 40.70880477 ], [ -74.01349603, 40.70870759 ], [ -74.0135202, 40.7086235 ], [ -74.01365665, 40.70865748 ], [ -74.01372618, 40.70867491 ], [ -74.0137101, 40.70869636 ], [ -74.01378789, 40.70872346 ], [ -74.01373408, 40.70879707 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01024045, 40.71022461 ], [ -74.01019257, 40.71028562 ], [ -74.00986567, 40.71013738 ], [ -74.00991355, 40.71007637 ], [ -74.00992181, 40.71008011 ], [ -74.01024045, 40.71022461 ] ] ] } }, { "type": "Feature", "properties": { "height": 42.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00758853, 40.71076977 ], [ -74.00747364, 40.71085359 ], [ -74.00733592, 40.71074539 ], [ -74.00730475, 40.71071808 ], [ -74.00739521, 40.71065121 ], [ -74.00758853, 40.71076977 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00832587, 40.71366299 ], [ -74.00813884, 40.71390178 ], [ -74.0080561, 40.71386426 ], [ -74.00824322, 40.71362547 ], [ -74.00832587, 40.71366299 ] ] ] } }, { "type": "Feature", "properties": { "height": 88.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01189874, 40.70624842 ], [ -74.01181034, 40.7064235 ], [ -74.01144428, 40.70627307 ], [ -74.01154282, 40.70609717 ], [ -74.01156681, 40.70610759 ], [ -74.0114759, 40.70623058 ], [ -74.01178878, 40.70636357 ], [ -74.01187969, 40.70624059 ], [ -74.01188544, 40.70624297 ], [ -74.01189874, 40.70624842 ] ] ] } }, { "type": "Feature", "properties": { "height": 123.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00651172, 40.70895778 ], [ -74.00660083, 40.7088538 ], [ -74.00665671, 40.7087919 ], [ -74.00667081, 40.7087763 ], [ -74.00677133, 40.70882826 ], [ -74.00661251, 40.70900987 ], [ -74.00651172, 40.70895778 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00914306, 40.71181097 ], [ -74.00903787, 40.71183188 ], [ -74.00873101, 40.71168459 ], [ -74.00870693, 40.71160091 ], [ -74.00914306, 40.71181097 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00848774, 40.71015508 ], [ -74.00847068, 40.71017469 ], [ -74.0082655, 40.71041057 ], [ -74.0081931, 40.71037407 ], [ -74.00820325, 40.7103625 ], [ -74.00830242, 40.71024837 ], [ -74.00832263, 40.71022522 ], [ -74.00840115, 40.71013486 ], [ -74.00841534, 40.71011859 ], [ -74.00848774, 40.71015508 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00863255, 40.71112501 ], [ -74.0088203, 40.71090977 ], [ -74.0085429, 40.7107716 ], [ -74.00855772, 40.7107554 ], [ -74.00857605, 40.71073551 ], [ -74.00888552, 40.71089247 ], [ -74.0086666, 40.7111423 ], [ -74.00863255, 40.71112501 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0071639, 40.71053212 ], [ -74.00706859, 40.71060498 ], [ -74.00702053, 40.71057897 ], [ -74.00690985, 40.71066851 ], [ -74.00684167, 40.71061976 ], [ -74.00703292, 40.71046498 ], [ -74.0071639, 40.71053212 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01376705, 40.7063588 ], [ -74.01373507, 40.70639987 ], [ -74.01363823, 40.70652469 ], [ -74.01360652, 40.70656548 ], [ -74.01356188, 40.70654621 ], [ -74.01355703, 40.7065441 ], [ -74.01359125, 40.70649902 ], [ -74.01362027, 40.70646081 ], [ -74.01365458, 40.7064158 ], [ -74.01359224, 40.70638849 ], [ -74.0135361, 40.70636398 ], [ -74.01359619, 40.70628471 ], [ -74.01368773, 40.70632462 ], [ -74.01373947, 40.70634736 ], [ -74.01375367, 40.70635308 ], [ -74.01376705, 40.7063588 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01409018, 40.71132718 ], [ -74.01403547, 40.71157258 ], [ -74.01392587, 40.71152138 ], [ -74.01400097, 40.71129136 ], [ -74.01409018, 40.71132718 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00577789, 40.70788908 ], [ -74.00550722, 40.70800798 ], [ -74.00549393, 40.70798305 ], [ -74.00572021, 40.707885 ], [ -74.00571249, 40.70787539 ], [ -74.0056355, 40.70779817 ], [ -74.00554064, 40.70770291 ], [ -74.00546069, 40.70762276 ], [ -74.00542691, 40.7075881 ], [ -74.00531723, 40.70762861 ], [ -74.00530519, 40.70760171 ], [ -74.00544012, 40.70755616 ], [ -74.00549069, 40.7076056 ], [ -74.00554612, 40.70766109 ], [ -74.00568823, 40.70780008 ], [ -74.00574483, 40.70785687 ], [ -74.00577789, 40.70788908 ] ] ] } }, { "type": "Feature", "properties": { "height": 124.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0091728, 40.70648227 ], [ -74.00916364, 40.70649262 ], [ -74.0091701, 40.70649589 ], [ -74.00910749, 40.70656637 ], [ -74.00909905, 40.70656201 ], [ -74.00909393, 40.7065678 ], [ -74.00906895, 40.70659647 ], [ -74.00904964, 40.70658741 ], [ -74.00904605, 40.70658557 ], [ -74.00899628, 40.70656119 ], [ -74.00896708, 40.70654682 ], [ -74.00899394, 40.70651665 ], [ -74.0090023, 40.70650726 ], [ -74.0090367, 40.70646858 ], [ -74.00895118, 40.70642241 ], [ -74.00897517, 40.70639408 ], [ -74.00906105, 40.7064412 ], [ -74.00906788, 40.70643351 ], [ -74.00907084, 40.70643017 ], [ -74.00910327, 40.70639408 ], [ -74.00913067, 40.70640988 ], [ -74.00917828, 40.70643718 ], [ -74.00920235, 40.70645101 ], [ -74.0091728, 40.70648227 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01240251, 40.70640886 ], [ -74.01230549, 40.70656357 ], [ -74.01217389, 40.70650297 ], [ -74.01226911, 40.70634859 ], [ -74.01240251, 40.70640886 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01408964, 40.70767158 ], [ -74.01405371, 40.70773021 ], [ -74.01402729, 40.70777271 ], [ -74.01399172, 40.70776038 ], [ -74.01391653, 40.70788602 ], [ -74.0138894, 40.70787676 ], [ -74.01385284, 40.70786429 ], [ -74.01386138, 40.70784461 ], [ -74.01389174, 40.70777706 ], [ -74.01392902, 40.70769228 ], [ -74.01395875, 40.70762521 ], [ -74.01408964, 40.70767158 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01043547, 40.7100921 ], [ -74.01021134, 40.7103783 ], [ -74.01014388, 40.71034779 ], [ -74.01019257, 40.71028562 ], [ -74.01024045, 40.71022461 ], [ -74.01028446, 40.71016829 ], [ -74.0103301, 40.71011001 ], [ -74.0103681, 40.71006145 ], [ -74.01043547, 40.7100921 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00875634, 40.71260159 ], [ -74.00859132, 40.71280368 ], [ -74.00850014, 40.71275922 ], [ -74.00859779, 40.71263652 ], [ -74.00866013, 40.71255746 ], [ -74.00874358, 40.7125958 ], [ -74.00875634, 40.71260159 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00862869, 40.7102543 ], [ -74.00843331, 40.71047901 ], [ -74.00842863, 40.71048452 ], [ -74.00834994, 40.71044475 ], [ -74.00855, 40.71021467 ], [ -74.00862869, 40.7102543 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00832263, 40.71022522 ], [ -74.00830242, 40.71024837 ], [ -74.00825921, 40.71022372 ], [ -74.00821546, 40.71019866 ], [ -74.00808314, 40.71012301 ], [ -74.00797678, 40.7100622 ], [ -74.00803113, 40.71000827 ], [ -74.00832353, 40.71017551 ], [ -74.00829182, 40.71020758 ], [ -74.00832263, 40.71022522 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00942352, 40.7122723 ], [ -74.00937357, 40.71224846 ], [ -74.00935615, 40.71225071 ], [ -74.00935237, 40.71223832 ], [ -74.00928069, 40.712204 ], [ -74.00930018, 40.71217976 ], [ -74.0092965, 40.71216737 ], [ -74.00923559, 40.7121385 ], [ -74.00921825, 40.71214061 ], [ -74.00921448, 40.71212821 ], [ -74.00915357, 40.71209927 ], [ -74.00913615, 40.71210139 ], [ -74.00913228, 40.71208899 ], [ -74.00907147, 40.71206012 ], [ -74.0090544, 40.7120623 ], [ -74.00905072, 40.71204991 ], [ -74.00898981, 40.71202097 ], [ -74.00900562, 40.71200027 ], [ -74.00922005, 40.71210418 ], [ -74.00925248, 40.71206509 ], [ -74.00932812, 40.7121007 ], [ -74.00930422, 40.71212937 ], [ -74.00942567, 40.71218786 ], [ -74.00947553, 40.7122121 ], [ -74.00942352, 40.7122723 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00934563, 40.70901716 ], [ -74.00921861, 40.70914456 ], [ -74.00914827, 40.70921511 ], [ -74.00910552, 40.70916696 ], [ -74.00916328, 40.70911092 ], [ -74.00922625, 40.70904998 ], [ -74.00919939, 40.70903479 ], [ -74.00918672, 40.70902778 ], [ -74.009141, 40.70900252 ], [ -74.00909572, 40.70897746 ], [ -74.00913417, 40.70893946 ], [ -74.00918502, 40.70895819 ], [ -74.00923784, 40.70897759 ], [ -74.0092868, 40.70899557 ], [ -74.00934563, 40.70901716 ] ] ] } }, { "type": "Feature", "properties": { "height": 6.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0090491, 40.71192401 ], [ -74.00899098, 40.71199366 ], [ -74.00872193, 40.71186429 ], [ -74.00877925, 40.71179572 ], [ -74.0089855, 40.71189459 ], [ -74.0090491, 40.71192401 ] ] ] } }, { "type": "Feature", "properties": { "height": 168.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01041319, 40.70640967 ], [ -74.01030189, 40.70649309 ], [ -74.01036558, 40.7065155 ], [ -74.01034241, 40.70655098 ], [ -74.01020595, 40.7066792 ], [ -74.01011073, 40.70661601 ], [ -74.01023452, 40.70650767 ], [ -74.01024763, 40.70651638 ], [ -74.01032147, 40.70645162 ], [ -74.01036235, 40.7064158 ], [ -74.01038319, 40.70639748 ], [ -74.01041319, 40.70640967 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00731966, 40.71009952 ], [ -74.0070685, 40.71035991 ], [ -74.0070031, 40.71032682 ], [ -74.00725328, 40.71006588 ], [ -74.00731966, 40.71009952 ] ] ] } }, { "type": "Feature", "properties": { "height": 117.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01186307, 40.70595471 ], [ -74.01178249, 40.70610732 ], [ -74.01164685, 40.70606612 ], [ -74.01168629, 40.70599142 ], [ -74.01167021, 40.70598651 ], [ -74.01171135, 40.70590861 ], [ -74.01186307, 40.70595471 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01004542, 40.71043829 ], [ -74.01003815, 40.71044761 ], [ -74.00973164, 40.71030857 ], [ -74.00977952, 40.71024749 ], [ -74.01008603, 40.71038647 ], [ -74.01004542, 40.71043829 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01223102, 40.70682868 ], [ -74.01197572, 40.70671639 ], [ -74.01191679, 40.70680491 ], [ -74.01172204, 40.70709916 ], [ -74.01170704, 40.70709221 ], [ -74.0116888, 40.7070837 ], [ -74.01194734, 40.70668091 ], [ -74.01224647, 40.70680961 ], [ -74.01223102, 40.70682868 ] ] ] } }, { "type": "Feature", "properties": { "height": 115.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00673306, 40.70863739 ], [ -74.00662931, 40.7087317 ], [ -74.0065737, 40.7087029 ], [ -74.00655547, 40.70868907 ], [ -74.00654352, 40.70869867 ], [ -74.0065251, 40.70868601 ], [ -74.00647094, 40.70864726 ], [ -74.00649555, 40.70862561 ], [ -74.00652394, 40.70859878 ], [ -74.00658251, 40.70854457 ], [ -74.00673306, 40.70863739 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01397151, 40.706048 ], [ -74.01396289, 40.70605849 ], [ -74.0137605, 40.70598958 ], [ -74.01376894, 40.70597936 ], [ -74.01382931, 40.70590309 ], [ -74.01387692, 40.7058939 ], [ -74.01399954, 40.70594586 ], [ -74.01401975, 40.7059893 ], [ -74.01397151, 40.706048 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01179552, 40.70559188 ], [ -74.01179318, 40.7056275 ], [ -74.01164748, 40.70562968 ], [ -74.01167542, 40.70526868 ], [ -74.01173551, 40.70527148 ], [ -74.01171261, 40.70558848 ], [ -74.01179552, 40.70559188 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0103301, 40.71011001 ], [ -74.01028446, 40.71016829 ], [ -74.00996601, 40.7100238 ], [ -74.01001165, 40.70996558 ], [ -74.01002054, 40.7099696 ], [ -74.0103301, 40.71011001 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00626253, 40.71025947 ], [ -74.00623225, 40.71030142 ], [ -74.00618967, 40.71033009 ], [ -74.00617108, 40.71031939 ], [ -74.0061099, 40.71028167 ], [ -74.00606562, 40.71025477 ], [ -74.00607882, 40.71024041 ], [ -74.00602528, 40.71020956 ], [ -74.00603849, 40.71019621 ], [ -74.00604738, 40.71018702 ], [ -74.00605052, 40.71018947 ], [ -74.00606571, 40.71019676 ], [ -74.00608197, 40.710205 ], [ -74.00614116, 40.71014276 ], [ -74.00629244, 40.7102227 ], [ -74.00626253, 40.71025947 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01338662, 40.71372488 ], [ -74.01336811, 40.71371596 ], [ -74.01337467, 40.71368566 ], [ -74.01328169, 40.71364188 ], [ -74.0129556, 40.71349351 ], [ -74.01263077, 40.71333949 ], [ -74.01262422, 40.713364 ], [ -74.01260122, 40.71335359 ], [ -74.01261559, 40.71330231 ], [ -74.01339991, 40.71366878 ], [ -74.01338662, 40.71372488 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01007264, 40.70727417 ], [ -74.0100112, 40.70733661 ], [ -74.00975293, 40.70719048 ], [ -74.00977162, 40.70717148 ], [ -74.00978024, 40.70716276 ], [ -74.00981402, 40.70712851 ], [ -74.00984061, 40.7071437 ], [ -74.01007264, 40.70727417 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01002647, 40.70922791 ], [ -74.00997437, 40.70928988 ], [ -74.00992235, 40.70926291 ], [ -74.00986262, 40.70923186 ], [ -74.00981069, 40.70928981 ], [ -74.00979812, 40.7092832 ], [ -74.00980809, 40.7092721 ], [ -74.00975051, 40.70924221 ], [ -74.00972805, 40.7092305 ], [ -74.00976793, 40.70918276 ], [ -74.00982255, 40.70912189 ], [ -74.00998568, 40.70920666 ], [ -74.01002647, 40.70922791 ] ] ] } }, { "type": "Feature", "properties": { "height": 112.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00810973, 40.70663487 ], [ -74.0080314, 40.70670951 ], [ -74.00781733, 40.7065774 ], [ -74.0078256, 40.70656957 ], [ -74.00783377, 40.7065744 ], [ -74.00788982, 40.70651931 ], [ -74.00788165, 40.70651448 ], [ -74.00788929, 40.70650658 ], [ -74.00810973, 40.70663487 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00636053, 40.70667199 ], [ -74.00631104, 40.70670876 ], [ -74.00629639, 40.7067204 ], [ -74.00627573, 40.70673681 ], [ -74.0062098, 40.70668731 ], [ -74.00614745, 40.70664039 ], [ -74.00608331, 40.70659218 ], [ -74.00608915, 40.70658782 ], [ -74.0061682, 40.70652741 ], [ -74.00618617, 40.7065409 ], [ -74.00634122, 40.70665748 ], [ -74.00636053, 40.70667199 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01203923, 40.70592938 ], [ -74.01188544, 40.70624297 ], [ -74.01187969, 40.70624059 ], [ -74.0118178, 40.7062143 ], [ -74.01196602, 40.70591739 ], [ -74.01203923, 40.70592938 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00495521, 40.70826851 ], [ -74.00486035, 40.70830549 ], [ -74.00480267, 40.70823481 ], [ -74.00485487, 40.70821778 ], [ -74.00477034, 40.70802568 ], [ -74.00483708, 40.70800056 ], [ -74.00486178, 40.7080566 ], [ -74.00495521, 40.70826851 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00999045, 40.70695309 ], [ -74.00994858, 40.70699511 ], [ -74.00990124, 40.70696807 ], [ -74.00992783, 40.70694226 ], [ -74.00965843, 40.70678877 ], [ -74.00945568, 40.70699341 ], [ -74.00941993, 40.70697318 ], [ -74.00957524, 40.70681499 ], [ -74.00955099, 40.70680062 ], [ -74.00961567, 40.70673967 ], [ -74.00999045, 40.70695309 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726657, 40.70568116 ], [ -74.00716174, 40.70561946 ], [ -74.00712374, 40.70559651 ], [ -74.00711305, 40.70558997 ], [ -74.00709544, 40.70557956 ], [ -74.00720477, 40.70549709 ], [ -74.00723073, 40.70551282 ], [ -74.00736503, 40.70559406 ], [ -74.00726657, 40.70568116 ] ] ] } }, { "type": "Feature", "properties": { "height": 69.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01240584, 40.70668772 ], [ -74.01237089, 40.70672898 ], [ -74.01195955, 40.706546 ], [ -74.01198524, 40.70649711 ], [ -74.01240584, 40.70668772 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01246827, 40.70799838 ], [ -74.01231043, 40.70792402 ], [ -74.01237089, 40.70785027 ], [ -74.0126085, 40.70796222 ], [ -74.01254813, 40.7080359 ], [ -74.01246827, 40.70799838 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01028446, 40.71016829 ], [ -74.01024045, 40.71022461 ], [ -74.00992181, 40.71008011 ], [ -74.00996601, 40.7100238 ], [ -74.01028446, 40.71016829 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00783745, 40.70958016 ], [ -74.00781149, 40.70960638 ], [ -74.00778517, 40.7096328 ], [ -74.00749232, 40.70946447 ], [ -74.00754451, 40.7094119 ], [ -74.00757101, 40.70942709 ], [ -74.00763021, 40.70946107 ], [ -74.00767872, 40.70948899 ], [ -74.00772265, 40.70951418 ], [ -74.00776595, 40.7095391 ], [ -74.00783745, 40.70958016 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00564449, 40.71341037 ], [ -74.00560227, 40.71346301 ], [ -74.0055233, 40.7134771 ], [ -74.00545395, 40.7134451 ], [ -74.00543545, 40.71338518 ], [ -74.00547758, 40.71333261 ], [ -74.00555663, 40.71331859 ], [ -74.00562589, 40.71335052 ], [ -74.00564449, 40.71341037 ] ] ] } }, { "type": "Feature", "properties": { "height": 6.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00552142, 40.70619598 ], [ -74.00557999, 40.70615117 ], [ -74.0055878, 40.70614518 ], [ -74.00560128, 40.70615526 ], [ -74.00566021, 40.70611018 ], [ -74.00564673, 40.7061001 ], [ -74.00565697, 40.70609206 ], [ -74.00572192, 40.70604242 ], [ -74.00580493, 40.70610432 ], [ -74.00560523, 40.7062587 ], [ -74.00552142, 40.70619598 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01372618, 40.70867491 ], [ -74.01365665, 40.70865748 ], [ -74.0135202, 40.7086235 ], [ -74.01343845, 40.70860307 ], [ -74.01346962, 40.70853068 ], [ -74.01375367, 40.7086015 ], [ -74.01376948, 40.70860552 ], [ -74.01373831, 40.7086779 ], [ -74.01372618, 40.70867491 ] ] ] } }, { "type": "Feature", "properties": { "height": 58.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00663039, 40.70850031 ], [ -74.00661305, 40.70851638 ], [ -74.00659248, 40.70853531 ], [ -74.00658251, 40.70854457 ], [ -74.00652394, 40.70859878 ], [ -74.0064854, 40.70857488 ], [ -74.00644399, 40.7085492 ], [ -74.00642907, 40.70854001 ], [ -74.00637814, 40.70850828 ], [ -74.00648459, 40.70840968 ], [ -74.0065737, 40.70846497 ], [ -74.00663039, 40.70850031 ] ] ] } }, { "type": "Feature", "properties": { "height": 51.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00825921, 40.71022372 ], [ -74.00818582, 40.71031211 ], [ -74.00800328, 40.71021916 ], [ -74.00804631, 40.71016727 ], [ -74.00808314, 40.71012301 ], [ -74.00821546, 40.71019866 ], [ -74.00825921, 40.71022372 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00573566, 40.71019206 ], [ -74.00567898, 40.71024919 ], [ -74.00558493, 40.71017456 ], [ -74.0055242, 40.71022406 ], [ -74.00544605, 40.71014998 ], [ -74.00554855, 40.71006636 ], [ -74.00558565, 40.71009128 ], [ -74.00573566, 40.71019206 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01257023, 40.70938691 ], [ -74.01248659, 40.7094975 ], [ -74.01234035, 40.70943349 ], [ -74.01235418, 40.70941578 ], [ -74.0123894, 40.7093707 ], [ -74.01243602, 40.70931119 ], [ -74.01257984, 40.70937411 ], [ -74.01257023, 40.70938691 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00805467, 40.70935028 ], [ -74.00788057, 40.70952569 ], [ -74.00788758, 40.70952971 ], [ -74.00783745, 40.70958016 ], [ -74.00776595, 40.7095391 ], [ -74.00788291, 40.70942116 ], [ -74.00791453, 40.70938936 ], [ -74.00796897, 40.70933448 ], [ -74.00799538, 40.70930792 ], [ -74.00805467, 40.70935028 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00495171, 40.7060651 ], [ -74.00489008, 40.70610827 ], [ -74.00469964, 40.70595076 ], [ -74.00463999, 40.70590146 ], [ -74.00470161, 40.70585842 ], [ -74.00495171, 40.7060651 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00824322, 40.71362547 ], [ -74.0080561, 40.71386426 ], [ -74.00798361, 40.71383138 ], [ -74.00817073, 40.71359258 ], [ -74.00824322, 40.71362547 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00817073, 40.71359258 ], [ -74.00798361, 40.71383138 ], [ -74.00791138, 40.71379856 ], [ -74.00792028, 40.7137865 ], [ -74.00809904, 40.71355976 ], [ -74.00817073, 40.71359258 ] ] ] } }, { "type": "Feature", "properties": { "height": 135.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0096728, 40.70780097 ], [ -74.0095809, 40.70774472 ], [ -74.00959078, 40.70773668 ], [ -74.00966265, 40.70777897 ], [ -74.00972625, 40.70770829 ], [ -74.00970209, 40.7076948 ], [ -74.00969149, 40.70768888 ], [ -74.00971242, 40.70766586 ], [ -74.0097232, 40.70767226 ], [ -74.00973613, 40.70767989 ], [ -74.00974449, 40.70768506 ], [ -74.0097665, 40.70766171 ], [ -74.00987708, 40.70772667 ], [ -74.00976048, 40.70785279 ], [ -74.0096728, 40.70780097 ] ] ] } }, { "type": "Feature", "properties": { "height": 53.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00724448, 40.70960706 ], [ -74.00717818, 40.70967488 ], [ -74.00706427, 40.70979146 ], [ -74.00698091, 40.70974808 ], [ -74.00698522, 40.70974366 ], [ -74.00698953, 40.7097393 ], [ -74.00699367, 40.70973501 ], [ -74.00699798, 40.70973058 ], [ -74.00716354, 40.7095613 ], [ -74.00724448, 40.70960706 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01463878, 40.70866279 ], [ -74.01460868, 40.70874341 ], [ -74.01446783, 40.70871318 ], [ -74.01452209, 40.70856786 ], [ -74.01461605, 40.70858809 ], [ -74.01462153, 40.70857331 ], [ -74.01467741, 40.70858529 ], [ -74.01465953, 40.7086331 ], [ -74.01465064, 40.70863119 ], [ -74.01463878, 40.70866279 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01342372, 40.70921048 ], [ -74.01344402, 40.70917936 ], [ -74.01381412, 40.70933986 ], [ -74.01386668, 40.70919448 ], [ -74.01391222, 40.70920557 ], [ -74.01385284, 40.70936471 ], [ -74.01384557, 40.70937159 ], [ -74.01384188, 40.70937397 ], [ -74.01383317, 40.70937731 ], [ -74.01382365, 40.70937847 ], [ -74.01381412, 40.70937738 ], [ -74.01380954, 40.70937608 ], [ -74.01342372, 40.70921048 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00995793, 40.70897078 ], [ -74.00994149, 40.7089891 ], [ -74.0099308, 40.70900102 ], [ -74.00992505, 40.70900762 ], [ -74.00982255, 40.70912189 ], [ -74.00976793, 40.70918276 ], [ -74.00969194, 40.7091434 ], [ -74.00971592, 40.70911657 ], [ -74.00974691, 40.70908198 ], [ -74.00984977, 40.70896717 ], [ -74.00985507, 40.70896132 ], [ -74.00986612, 40.70896697 ], [ -74.00989028, 40.70894 ], [ -74.00995793, 40.70897078 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01375367, 40.7086015 ], [ -74.01346962, 40.70853068 ], [ -74.01350097, 40.70845782 ], [ -74.01377307, 40.70852571 ], [ -74.01378511, 40.70852871 ], [ -74.01375367, 40.7086015 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00583978, 40.70786212 ], [ -74.0058078, 40.70787689 ], [ -74.00569488, 40.7077659 ], [ -74.00559355, 40.70766627 ], [ -74.00544272, 40.70751816 ], [ -74.00528992, 40.70756658 ], [ -74.00527995, 40.7075437 ], [ -74.00545647, 40.70748166 ], [ -74.00562454, 40.70764802 ], [ -74.00572533, 40.70774846 ], [ -74.00583978, 40.70786212 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00778337, 40.70988169 ], [ -74.00774609, 40.70991927 ], [ -74.00773837, 40.70991492 ], [ -74.00770971, 40.70994386 ], [ -74.00766821, 40.7099856 ], [ -74.0075923, 40.71006207 ], [ -74.00751244, 40.71002162 ], [ -74.00769579, 40.70983681 ], [ -74.00778337, 40.70988169 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01149153, 40.70607477 ], [ -74.01151569, 40.70608539 ], [ -74.01140565, 40.70628029 ], [ -74.01182022, 40.70645169 ], [ -74.01191922, 40.70625659 ], [ -74.01193665, 40.7062636 ], [ -74.01182516, 40.70648247 ], [ -74.01136487, 40.70628689 ], [ -74.01149153, 40.70607477 ] ] ] } }, { "type": "Feature", "properties": { "height": 53.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01441025, 40.70778462 ], [ -74.01436704, 40.70789541 ], [ -74.014385, 40.7078993 ], [ -74.01433452, 40.70802936 ], [ -74.01431601, 40.70802616 ], [ -74.01428484, 40.70810631 ], [ -74.01416384, 40.70806627 ], [ -74.01417103, 40.70805258 ], [ -74.01426921, 40.70808268 ], [ -74.01436452, 40.70784101 ], [ -74.01435563, 40.70783781 ], [ -74.01433524, 40.70783052 ], [ -74.01421217, 40.70778666 ], [ -74.01424855, 40.70772756 ], [ -74.01441025, 40.70778462 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00886899, 40.70575668 ], [ -74.00881509, 40.70586128 ], [ -74.00878598, 40.70587047 ], [ -74.00849601, 40.70573748 ], [ -74.00852898, 40.70569301 ], [ -74.00874547, 40.70579577 ], [ -74.00878814, 40.70578596 ], [ -74.00881437, 40.70573938 ], [ -74.00886899, 40.70575668 ] ] ] } }, { "type": "Feature", "properties": { "height": 118.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00834644, 40.7091895 ], [ -74.00828095, 40.70915069 ], [ -74.00834356, 40.70908852 ], [ -74.00829721, 40.70904058 ], [ -74.00828742, 40.7090305 ], [ -74.00833485, 40.70898358 ], [ -74.00834931, 40.70896942 ], [ -74.00848702, 40.7090478 ], [ -74.00834644, 40.7091895 ] ] ] } }, { "type": "Feature", "properties": { "height": 151.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00966265, 40.70777897 ], [ -74.00959078, 40.70773668 ], [ -74.0094458, 40.70764986 ], [ -74.0095058, 40.70758646 ], [ -74.00969149, 40.70768888 ], [ -74.00970209, 40.7076948 ], [ -74.00972625, 40.70770829 ], [ -74.00966265, 40.70777897 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0122409, 40.70564977 ], [ -74.01219473, 40.70574721 ], [ -74.01199647, 40.70572651 ], [ -74.01200132, 40.70562471 ], [ -74.0121323, 40.70563839 ], [ -74.01220147, 40.70564568 ], [ -74.0122409, 40.70564977 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00812527, 40.71309927 ], [ -74.00796852, 40.7132987 ], [ -74.00788749, 40.7132618 ], [ -74.00804254, 40.71306209 ], [ -74.00809455, 40.71308572 ], [ -74.00812527, 40.71309927 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00990771, 40.71053191 ], [ -74.00965097, 40.71041418 ], [ -74.00969831, 40.71035079 ], [ -74.00995784, 40.71046852 ], [ -74.00990771, 40.71053191 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01458138, 40.70882499 ], [ -74.01455227, 40.70889649 ], [ -74.01453844, 40.70893061 ], [ -74.01434763, 40.70888587 ], [ -74.0143568, 40.7088621 ], [ -74.01436767, 40.7088367 ], [ -74.01439075, 40.70878039 ], [ -74.01458138, 40.70882499 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00948775, 40.71190882 ], [ -74.00932812, 40.7121007 ], [ -74.00925302, 40.71206448 ], [ -74.00941265, 40.71187266 ], [ -74.00942702, 40.71185537 ], [ -74.00950203, 40.71189159 ], [ -74.00948775, 40.71190882 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00843483, 40.7069661 ], [ -74.0083644, 40.70692667 ], [ -74.0085517, 40.70673259 ], [ -74.00861719, 40.70677127 ], [ -74.0086092, 40.70677917 ], [ -74.00861899, 40.70678496 ], [ -74.00843483, 40.7069661 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01455164, 40.70835248 ], [ -74.01448454, 40.7085266 ], [ -74.01445067, 40.7085187 ], [ -74.01442911, 40.70851332 ], [ -74.01436991, 40.70849936 ], [ -74.01444232, 40.70832081 ], [ -74.01455164, 40.70835248 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00392197, 40.70675309 ], [ -74.00381821, 40.70682126 ], [ -74.00369541, 40.70668547 ], [ -74.00380707, 40.70662636 ], [ -74.00392197, 40.70675309 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0056152, 40.70991907 ], [ -74.00540077, 40.71009707 ], [ -74.00534598, 40.71004477 ], [ -74.00551809, 40.70990191 ], [ -74.00554271, 40.70988148 ], [ -74.00556292, 40.70986466 ], [ -74.00562688, 40.7099094 ], [ -74.0056152, 40.70991907 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01013579, 40.71034411 ], [ -74.01005773, 40.71044387 ], [ -74.01004542, 40.71043829 ], [ -74.01008603, 40.71038647 ], [ -74.00977952, 40.71024749 ], [ -74.00981707, 40.71019948 ], [ -74.01013579, 40.71034411 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01003815, 40.71044761 ], [ -74.00996817, 40.7105362 ], [ -74.00995478, 40.71055316 ], [ -74.00990771, 40.71053191 ], [ -74.00995784, 40.71046852 ], [ -74.00969831, 40.71035079 ], [ -74.00973164, 40.71030857 ], [ -74.01003815, 40.71044761 ] ] ] } }, { "type": "Feature", "properties": { "height": 142.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01422447, 40.70787049 ], [ -74.01416447, 40.70797059 ], [ -74.01415827, 40.70796848 ], [ -74.01406448, 40.70793648 ], [ -74.0140599, 40.70793491 ], [ -74.01398588, 40.70790971 ], [ -74.01404625, 40.70780907 ], [ -74.01422447, 40.70787049 ] ] ] } }, { "type": "Feature", "properties": { "height": 155.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00829317, 40.70742929 ], [ -74.00822597, 40.70748752 ], [ -74.00819373, 40.70748697 ], [ -74.00817297, 40.7074726 ], [ -74.00817405, 40.70746069 ], [ -74.00815474, 40.70746157 ], [ -74.00810587, 40.70742916 ], [ -74.00810488, 40.70741547 ], [ -74.00808638, 40.70741547 ], [ -74.00806239, 40.7073992 ], [ -74.00806239, 40.7073772 ], [ -74.00812833, 40.70731857 ], [ -74.00814252, 40.7073185 ], [ -74.00817333, 40.70733852 ], [ -74.0081745, 40.707352 ], [ -74.00819507, 40.70735146 ], [ -74.00824107, 40.7073834 ], [ -74.00824331, 40.70739722 ], [ -74.0082611, 40.70739688 ], [ -74.00829254, 40.70741799 ], [ -74.00829317, 40.70742929 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01028878, 40.70966589 ], [ -74.01022482, 40.70972398 ], [ -74.01028312, 40.7097538 ], [ -74.01019697, 40.70985942 ], [ -74.0100836, 40.70985186 ], [ -74.01011971, 40.70981141 ], [ -74.01008872, 40.7097931 ], [ -74.01010579, 40.70979357 ], [ -74.01023371, 40.7096424 ], [ -74.01028878, 40.70966589 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00504127, 40.70823487 ], [ -74.00495521, 40.70826851 ], [ -74.00486178, 40.7080566 ], [ -74.00494928, 40.70802616 ], [ -74.00504127, 40.70823487 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00519218, 40.70817611 ], [ -74.00512041, 40.70820409 ], [ -74.00502968, 40.70799831 ], [ -74.00500767, 40.70794826 ], [ -74.00507855, 40.70793021 ], [ -74.00509777, 40.707974 ], [ -74.00510388, 40.7079725 ], [ -74.00519218, 40.70817611 ] ] ] } }, { "type": "Feature", "properties": { "height": 84.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00613344, 40.70964567 ], [ -74.00606373, 40.70972071 ], [ -74.00587436, 40.70962456 ], [ -74.00594174, 40.7095485 ], [ -74.00613344, 40.70964567 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00753364, 40.71027581 ], [ -74.00744651, 40.71036352 ], [ -74.00729397, 40.71027636 ], [ -74.00738111, 40.71018872 ], [ -74.00753364, 40.71027581 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00769579, 40.70983681 ], [ -74.00751244, 40.71002162 ], [ -74.00743725, 40.70998355 ], [ -74.00762087, 40.70979841 ], [ -74.00769579, 40.70983681 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00999422, 40.70735412 ], [ -74.00997455, 40.70737461 ], [ -74.0093601, 40.70703331 ], [ -74.00938318, 40.70701036 ], [ -74.00947131, 40.70705966 ], [ -74.0096339, 40.70715119 ], [ -74.00969229, 40.70718292 ], [ -74.00999422, 40.70735412 ] ] ] } }, { "type": "Feature", "properties": { "height": 66.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01379993, 40.70637161 ], [ -74.01377747, 40.70636262 ], [ -74.01391438, 40.7061665 ], [ -74.01376355, 40.70611447 ], [ -74.01376975, 40.70610419 ], [ -74.01363877, 40.7060591 ], [ -74.01363257, 40.70606939 ], [ -74.01348417, 40.70601831 ], [ -74.01346908, 40.70603868 ], [ -74.01344168, 40.70602921 ], [ -74.01339785, 40.70601396 ], [ -74.01337242, 40.70605039 ], [ -74.01331763, 40.70602751 ], [ -74.01335509, 40.70597378 ], [ -74.01345615, 40.70600858 ], [ -74.01346908, 40.70598992 ], [ -74.01395058, 40.7061558 ], [ -74.01379993, 40.70637161 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01237583, 40.70620701 ], [ -74.0123054, 40.70630242 ], [ -74.01218027, 40.70624481 ], [ -74.01232319, 40.70605972 ], [ -74.0123637, 40.70607776 ], [ -74.0122922, 40.70616956 ], [ -74.01237583, 40.70620701 ] ] ] } }, { "type": "Feature", "properties": { "height": 38.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.010202, 40.70598066 ], [ -74.01017882, 40.7060192 ], [ -74.00992945, 40.70592706 ], [ -74.00983854, 40.7060777 ], [ -74.00979928, 40.70606367 ], [ -74.00991364, 40.70587422 ], [ -74.010202, 40.70598066 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0141606, 40.70857508 ], [ -74.01413231, 40.70864536 ], [ -74.0138629, 40.7085778 ], [ -74.01389291, 40.70850862 ], [ -74.0141606, 40.70857508 ] ] ] } }, { "type": "Feature", "properties": { "height": 82.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01137897, 40.70718142 ], [ -74.01126363, 40.70735091 ], [ -74.0111746, 40.70731727 ], [ -74.01116365, 40.70731278 ], [ -74.01126462, 40.70715861 ], [ -74.01131375, 40.70717951 ], [ -74.01132705, 40.70715997 ], [ -74.01137897, 40.70718142 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00567665, 40.7099619 ], [ -74.00560442, 40.71002087 ], [ -74.00554855, 40.71006636 ], [ -74.00544605, 40.71014998 ], [ -74.00539682, 40.7101004 ], [ -74.00540077, 40.71009707 ], [ -74.0056152, 40.70991907 ], [ -74.00567665, 40.7099619 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0103681, 40.71006145 ], [ -74.0103301, 40.71011001 ], [ -74.01002054, 40.7099696 ], [ -74.01005854, 40.70992111 ], [ -74.0103681, 40.71006145 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726657, 40.70568116 ], [ -74.00716174, 40.70561946 ], [ -74.00712374, 40.70559651 ], [ -74.00723073, 40.70551282 ], [ -74.00736503, 40.70559406 ], [ -74.00726657, 40.70568116 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01361605, 40.70761888 ], [ -74.01359395, 40.70767056 ], [ -74.01326714, 40.70755377 ], [ -74.01330424, 40.70750032 ], [ -74.01361605, 40.70761888 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01202702, 40.70788037 ], [ -74.01194141, 40.70798469 ], [ -74.01193377, 40.70798122 ], [ -74.0118019, 40.70791959 ], [ -74.01188688, 40.70781499 ], [ -74.01201884, 40.70787662 ], [ -74.01202702, 40.70788037 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00755359, 40.70585161 ], [ -74.00741821, 40.70598672 ], [ -74.00708952, 40.70580081 ], [ -74.0070976, 40.70579236 ], [ -74.00707631, 40.70578038 ], [ -74.00709185, 40.70576206 ], [ -74.00699223, 40.70570561 ], [ -74.00709311, 40.70560911 ], [ -74.00712221, 40.705629 ], [ -74.00704298, 40.70570806 ], [ -74.00713398, 40.70576111 ], [ -74.00711224, 40.70578406 ], [ -74.00741102, 40.70596057 ], [ -74.00753544, 40.70584078 ], [ -74.00755359, 40.70585161 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00772912, 40.70628342 ], [ -74.00771582, 40.70629636 ], [ -74.00770899, 40.70630296 ], [ -74.00750094, 40.70618161 ], [ -74.00730098, 40.70637358 ], [ -74.00751154, 40.70649691 ], [ -74.00750553, 40.70650269 ], [ -74.00749232, 40.7065157 ], [ -74.00726127, 40.7063776 ], [ -74.007496, 40.70615219 ], [ -74.00772912, 40.70628342 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00872759, 40.71315599 ], [ -74.00858198, 40.71334106 ], [ -74.00850212, 40.7133047 ], [ -74.00864773, 40.71311956 ], [ -74.00872759, 40.71315599 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01191922, 40.70625659 ], [ -74.01182022, 40.70645169 ], [ -74.01140565, 40.70628029 ], [ -74.01151569, 40.70608539 ], [ -74.01153743, 40.70609479 ], [ -74.01154282, 40.70609717 ], [ -74.01144428, 40.70627307 ], [ -74.01181034, 40.7064235 ], [ -74.01189874, 40.70624842 ], [ -74.01191922, 40.70625659 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01423588, 40.70838829 ], [ -74.01421253, 40.70844638 ], [ -74.01411362, 40.70842139 ], [ -74.0139522, 40.70838039 ], [ -74.01389713, 40.70836718 ], [ -74.01392489, 40.70830951 ], [ -74.0141916, 40.70837706 ], [ -74.01423588, 40.70838829 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00858198, 40.71334106 ], [ -74.00843708, 40.71352538 ], [ -74.00835713, 40.71348888 ], [ -74.00850212, 40.7133047 ], [ -74.00858198, 40.71334106 ] ] ] } }, { "type": "Feature", "properties": { "height": 58.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0058078, 40.70787689 ], [ -74.00577789, 40.70788908 ], [ -74.00574483, 40.70785687 ], [ -74.00568823, 40.70780008 ], [ -74.00554612, 40.70766109 ], [ -74.00549069, 40.7076056 ], [ -74.00544012, 40.70755616 ], [ -74.00530519, 40.70760171 ], [ -74.00528992, 40.70756658 ], [ -74.00544272, 40.70751816 ], [ -74.00559355, 40.70766627 ], [ -74.00569488, 40.7077659 ], [ -74.0058078, 40.70787689 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00917621, 40.70863609 ], [ -74.00890995, 40.70885516 ], [ -74.00891705, 40.70874988 ], [ -74.00905584, 40.70863718 ], [ -74.00917621, 40.70863609 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00774232, 40.70627048 ], [ -74.00772912, 40.70628342 ], [ -74.007496, 40.70615219 ], [ -74.00726127, 40.7063776 ], [ -74.00749232, 40.7065157 ], [ -74.00747364, 40.7065347 ], [ -74.00722363, 40.70637392 ], [ -74.00748837, 40.70612782 ], [ -74.00774232, 40.70627048 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00713991, 40.7091323 ], [ -74.0068626, 40.70941517 ], [ -74.00681813, 40.7093895 ], [ -74.00709527, 40.70910752 ], [ -74.00713991, 40.7091323 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00708395, 40.7080724 ], [ -74.00707092, 40.70809071 ], [ -74.00696591, 40.70802582 ], [ -74.0068608, 40.70796079 ], [ -74.0068184, 40.70802167 ], [ -74.00665132, 40.70820049 ], [ -74.00678777, 40.70828738 ], [ -74.00688704, 40.7083505 ], [ -74.00687949, 40.70836106 ], [ -74.0066179, 40.70819817 ], [ -74.00678921, 40.70801261 ], [ -74.00684571, 40.70792476 ], [ -74.00708395, 40.7080724 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00400192, 40.70635199 ], [ -74.00379854, 40.70648158 ], [ -74.00376234, 40.70645019 ], [ -74.00378749, 40.70643351 ], [ -74.00375892, 40.70640858 ], [ -74.00393329, 40.70629241 ], [ -74.00400192, 40.70635199 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00995379, 40.70739416 ], [ -74.00991445, 40.70743678 ], [ -74.00959626, 40.70724618 ], [ -74.0096269, 40.70721009 ], [ -74.00995379, 40.70739416 ] ] ] } }, { "type": "Feature", "properties": { "height": 102.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00602681, 40.70828758 ], [ -74.00593913, 40.70833348 ], [ -74.00585352, 40.7082393 ], [ -74.0060039, 40.70818326 ], [ -74.00610748, 40.7082455 ], [ -74.00602681, 40.70828758 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00512041, 40.70820409 ], [ -74.00504127, 40.70823487 ], [ -74.00494928, 40.70802616 ], [ -74.00502968, 40.70799831 ], [ -74.00512041, 40.70820409 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00408564, 40.70642479 ], [ -74.00401297, 40.70647307 ], [ -74.0039782, 40.70644277 ], [ -74.00384651, 40.70652578 ], [ -74.00379854, 40.70648158 ], [ -74.00400192, 40.70635199 ], [ -74.00408564, 40.70642479 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0064006, 40.70661206 ], [ -74.00634122, 40.70665748 ], [ -74.00631921, 40.7066743 ], [ -74.00627268, 40.7066393 ], [ -74.00621024, 40.70659231 ], [ -74.00616425, 40.70655779 ], [ -74.00618617, 40.7065409 ], [ -74.00624564, 40.70649548 ], [ -74.0064006, 40.70661206 ] ] ] } }, { "type": "Feature", "properties": { "height": 52.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00994113, 40.7065078 ], [ -74.00992783, 40.70652231 ], [ -74.00963462, 40.7063364 ], [ -74.00979928, 40.70606367 ], [ -74.00983854, 40.7060777 ], [ -74.00967909, 40.70634171 ], [ -74.00994113, 40.7065078 ] ] ] } }, { "type": "Feature", "properties": { "height": 59.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01402828, 40.70977151 ], [ -74.01397205, 40.70991648 ], [ -74.01386955, 40.70989401 ], [ -74.01391707, 40.70977369 ], [ -74.01393037, 40.70974087 ], [ -74.01394294, 40.70970961 ], [ -74.01401202, 40.70972541 ], [ -74.01399693, 40.7097645 ], [ -74.01402828, 40.70977151 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00393329, 40.70629241 ], [ -74.00375892, 40.70640858 ], [ -74.0037238, 40.70637808 ], [ -74.00374617, 40.70636316 ], [ -74.00370619, 40.7063285 ], [ -74.00385828, 40.70622717 ], [ -74.00393329, 40.70629241 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00829344, 40.71093612 ], [ -74.00825948, 40.71097466 ], [ -74.00792702, 40.71079026 ], [ -74.00796591, 40.71075002 ], [ -74.00810578, 40.71082526 ], [ -74.00809491, 40.71083691 ], [ -74.00829344, 40.71093612 ] ] ] } }, { "type": "Feature", "properties": { "height": 71.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00612275, 40.70741996 ], [ -74.006109, 40.70743147 ], [ -74.00594569, 40.7073136 ], [ -74.00566173, 40.70742528 ], [ -74.00565688, 40.70744428 ], [ -74.00588874, 40.70767219 ], [ -74.00587392, 40.70768411 ], [ -74.00560783, 40.70742017 ], [ -74.00594569, 40.70728888 ], [ -74.00612275, 40.70741996 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01406448, 40.70793648 ], [ -74.0140228, 40.70800689 ], [ -74.01397995, 40.70799218 ], [ -74.01395552, 40.70803426 ], [ -74.01387871, 40.70801009 ], [ -74.01390315, 40.70796596 ], [ -74.01384763, 40.7079471 ], [ -74.0138894, 40.70787676 ], [ -74.01391653, 40.70788602 ], [ -74.01394887, 40.70789712 ], [ -74.01398588, 40.70790971 ], [ -74.0140599, 40.70793491 ], [ -74.01406448, 40.70793648 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0063732, 40.71025042 ], [ -74.00619093, 40.71040267 ], [ -74.00618698, 40.71040601 ], [ -74.00613542, 40.71035957 ], [ -74.00617108, 40.71031939 ], [ -74.00618967, 40.71033009 ], [ -74.00623225, 40.71030142 ], [ -74.00626253, 40.71025947 ], [ -74.00629244, 40.7102227 ], [ -74.00614116, 40.71014276 ], [ -74.00608197, 40.710205 ], [ -74.00606571, 40.71019676 ], [ -74.00613461, 40.71012642 ], [ -74.0063732, 40.71025042 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01399954, 40.7081441 ], [ -74.01398274, 40.7081804 ], [ -74.01397654, 40.70819449 ], [ -74.01395193, 40.7081868 ], [ -74.01365701, 40.70809569 ], [ -74.01367902, 40.70804482 ], [ -74.01399954, 40.7081441 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01406502, 40.7096548 ], [ -74.01404975, 40.70967577 ], [ -74.01399361, 40.7096501 ], [ -74.01398238, 40.70964826 ], [ -74.01397151, 40.70965112 ], [ -74.01396819, 40.70965357 ], [ -74.01396298, 40.70965909 ], [ -74.01394294, 40.70970961 ], [ -74.01393037, 40.70974087 ], [ -74.01391707, 40.70977369 ], [ -74.01386955, 40.70989401 ], [ -74.01385832, 40.70992179 ], [ -74.01384763, 40.7099491 ], [ -74.01382392, 40.71000902 ], [ -74.01381394, 40.71003422 ], [ -74.01378179, 40.71002067 ], [ -74.01381314, 40.70994079 ], [ -74.01382347, 40.70991376 ], [ -74.0138347, 40.70988591 ], [ -74.01388168, 40.70976552 ], [ -74.0138947, 40.70973222 ], [ -74.01390719, 40.70970055 ], [ -74.01393881, 40.7096183 ], [ -74.0139681, 40.70961019 ], [ -74.01406502, 40.7096548 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0041399, 40.70661206 ], [ -74.00401297, 40.70647307 ], [ -74.00408564, 40.70642479 ], [ -74.00423206, 40.7065522 ], [ -74.0041399, 40.70661206 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01363347, 40.70657719 ], [ -74.01353124, 40.70671339 ], [ -74.01348929, 40.70676916 ], [ -74.01341761, 40.70673777 ], [ -74.0134716, 40.70666606 ], [ -74.01356188, 40.70654621 ], [ -74.01360652, 40.70656548 ], [ -74.01363347, 40.70657719 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00696591, 40.70802582 ], [ -74.00694614, 40.70804448 ], [ -74.00689512, 40.70801438 ], [ -74.00683152, 40.70807308 ], [ -74.00676388, 40.70813552 ], [ -74.00669453, 40.70819946 ], [ -74.00680412, 40.70827219 ], [ -74.00678777, 40.70828738 ], [ -74.00665132, 40.70820049 ], [ -74.0068184, 40.70802167 ], [ -74.0068608, 40.70796079 ], [ -74.00696591, 40.70802582 ] ] ] } }, { "type": "Feature", "properties": { "height": 33.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01359619, 40.70628471 ], [ -74.0135361, 40.70636398 ], [ -74.01336479, 40.70628907 ], [ -74.01342399, 40.7062096 ], [ -74.01357921, 40.70627729 ], [ -74.01359619, 40.70628471 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00899978, 40.70554517 ], [ -74.0088919, 40.70576397 ], [ -74.00886899, 40.70575668 ], [ -74.00881437, 40.70573938 ], [ -74.00889684, 40.70556321 ], [ -74.00897005, 40.70555109 ], [ -74.00899978, 40.70554517 ] ] ] } }, { "type": "Feature", "properties": { "height": 250.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00777664, 40.70644556 ], [ -74.00771169, 40.70650957 ], [ -74.00768959, 40.7065125 ], [ -74.00757577, 40.70644617 ], [ -74.00757371, 40.70642922 ], [ -74.00763857, 40.70636521 ], [ -74.00766084, 40.70636241 ], [ -74.00777457, 40.70642867 ], [ -74.00777664, 40.70644556 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00745809, 40.70925842 ], [ -74.00720809, 40.70951309 ], [ -74.00716345, 40.70948769 ], [ -74.00741201, 40.709232 ], [ -74.00745809, 40.70925842 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00773487, 40.71374701 ], [ -74.00760721, 40.71390988 ], [ -74.00752574, 40.71387291 ], [ -74.00761952, 40.71375321 ], [ -74.0076533, 40.71370997 ], [ -74.00773487, 40.71374701 ] ] ] } }, { "type": "Feature", "properties": { "height": 73.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01476301, 40.7091018 ], [ -74.01472573, 40.70919386 ], [ -74.0147216, 40.70920401 ], [ -74.01470723, 40.7092006 ], [ -74.01459764, 40.70917507 ], [ -74.01458012, 40.70917098 ], [ -74.01458425, 40.7091607 ], [ -74.01462225, 40.709067 ], [ -74.0146271, 40.70905502 ], [ -74.01464399, 40.70905897 ], [ -74.01475367, 40.70908457 ], [ -74.01476858, 40.70908797 ], [ -74.01476301, 40.7091018 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00785434, 40.7105328 ], [ -74.00789818, 40.71048861 ], [ -74.00796223, 40.71042405 ], [ -74.00803841, 40.7104628 ], [ -74.00788174, 40.71062071 ], [ -74.00780871, 40.71057876 ], [ -74.00785434, 40.7105328 ] ] ] } }, { "type": "Feature", "properties": { "height": 41.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00747274, 40.70580367 ], [ -74.00737437, 40.70589867 ], [ -74.00725804, 40.70582948 ], [ -74.00733188, 40.70575811 ], [ -74.00735623, 40.70573462 ], [ -74.00747274, 40.70580367 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00906779, 40.70963062 ], [ -74.00891687, 40.70980072 ], [ -74.00885039, 40.70975367 ], [ -74.00899709, 40.70959208 ], [ -74.00906779, 40.70963062 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00997455, 40.70737461 ], [ -74.00995379, 40.70739416 ], [ -74.0096269, 40.70721009 ], [ -74.0094696, 40.70712197 ], [ -74.00934393, 40.70705156 ], [ -74.0093601, 40.70703331 ], [ -74.00997455, 40.70737461 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00781715, 40.71377398 ], [ -74.00768339, 40.71394447 ], [ -74.00760721, 40.71390988 ], [ -74.00773487, 40.71374701 ], [ -74.00774079, 40.71373939 ], [ -74.00781715, 40.71377398 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01327819, 40.71418871 ], [ -74.01326642, 40.71423917 ], [ -74.0124653, 40.71387986 ], [ -74.01248165, 40.7138166 ], [ -74.01250851, 40.71382886 ], [ -74.01249612, 40.71387216 ], [ -74.01261362, 40.71392446 ], [ -74.01294465, 40.71407589 ], [ -74.01325313, 40.71421711 ], [ -74.01326157, 40.71418068 ], [ -74.01327819, 40.71418871 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00480267, 40.70823481 ], [ -74.00466469, 40.70806538 ], [ -74.00468212, 40.70805878 ], [ -74.00477034, 40.70802568 ], [ -74.00485487, 40.70821778 ], [ -74.00480267, 40.70823481 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01137655, 40.70786491 ], [ -74.01136702, 40.70787492 ], [ -74.0113575, 40.70788479 ], [ -74.01134771, 40.70787989 ], [ -74.0114282, 40.70779668 ], [ -74.01134933, 40.70775296 ], [ -74.01136451, 40.7077375 ], [ -74.01125357, 40.70767049 ], [ -74.01120838, 40.70764332 ], [ -74.01116535, 40.70761717 ], [ -74.0111852, 40.70759627 ], [ -74.01120039, 40.70760498 ], [ -74.01121808, 40.70761506 ], [ -74.01123201, 40.70762296 ], [ -74.01124279, 40.7076169 ], [ -74.01148354, 40.70775956 ], [ -74.01139721, 40.70786239 ], [ -74.01138427, 40.70785667 ], [ -74.01137655, 40.70786491 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00682748, 40.71091841 ], [ -74.00676657, 40.71096152 ], [ -74.00664934, 40.7108636 ], [ -74.00658179, 40.71080728 ], [ -74.00664323, 40.71076466 ], [ -74.00667548, 40.71079156 ], [ -74.00682748, 40.71091841 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0078185, 40.71007201 ], [ -74.00774951, 40.7101416 ], [ -74.0075923, 40.71006207 ], [ -74.00766821, 40.7099856 ], [ -74.0078185, 40.71007201 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00980189, 40.71203622 ], [ -74.0096613, 40.71220516 ], [ -74.0096551, 40.71221272 ], [ -74.00958548, 40.71217908 ], [ -74.00960381, 40.71215722 ], [ -74.00971808, 40.71201981 ], [ -74.00973227, 40.71200258 ], [ -74.00980189, 40.71203622 ] ] ] } }, { "type": "Feature", "properties": { "height": 53.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00724448, 40.70960706 ], [ -74.00717818, 40.70967488 ], [ -74.00717162, 40.70967148 ], [ -74.00716506, 40.70966807 ], [ -74.0071586, 40.70966467 ], [ -74.00715213, 40.70966126 ], [ -74.00705484, 40.70976 ], [ -74.00699798, 40.70973058 ], [ -74.00716354, 40.7095613 ], [ -74.00724448, 40.70960706 ] ] ] } }, { "type": "Feature", "properties": { "height": 63.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00862761, 40.70977491 ], [ -74.00857838, 40.70981482 ], [ -74.00849044, 40.70975237 ], [ -74.00843564, 40.70979691 ], [ -74.00836854, 40.70974938 ], [ -74.00847247, 40.70966501 ], [ -74.00862761, 40.70977491 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01438923, 40.70906257 ], [ -74.01435428, 40.70915587 ], [ -74.01415683, 40.70907115 ], [ -74.01417857, 40.70901586 ], [ -74.01424972, 40.70903077 ], [ -74.01438923, 40.70906257 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00813731, 40.71303131 ], [ -74.00809455, 40.71308572 ], [ -74.00804254, 40.71306209 ], [ -74.00801855, 40.71305126 ], [ -74.00804038, 40.71302348 ], [ -74.00772328, 40.71288001 ], [ -74.00774421, 40.71285339 ], [ -74.00813731, 40.71303131 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0065516, 40.70934272 ], [ -74.0063785, 40.70925276 ], [ -74.00633583, 40.70923057 ], [ -74.0063838, 40.70917711 ], [ -74.00660101, 40.70928981 ], [ -74.0065516, 40.70934272 ] ] ] } }, { "type": "Feature", "properties": { "height": 11.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01250905, 40.7062666 ], [ -74.0124388, 40.70636269 ], [ -74.0123054, 40.70630242 ], [ -74.01237583, 40.70620701 ], [ -74.01250905, 40.7062666 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00702708, 40.71126807 ], [ -74.00688901, 40.71136381 ], [ -74.00690572, 40.71137777 ], [ -74.00682757, 40.7114319 ], [ -74.00676882, 40.71138281 ], [ -74.00695495, 40.71125118 ], [ -74.00693644, 40.71123716 ], [ -74.0069642, 40.71121727 ], [ -74.00702708, 40.71126807 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00623881, 40.70921381 ], [ -74.00617844, 40.7092813 ], [ -74.00614404, 40.70931957 ], [ -74.00607244, 40.70928239 ], [ -74.00623288, 40.70910336 ], [ -74.00628669, 40.70913128 ], [ -74.00622102, 40.70920462 ], [ -74.00623881, 40.70921381 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00557999, 40.70615117 ], [ -74.00550318, 40.70609356 ], [ -74.00551252, 40.70608641 ], [ -74.00544749, 40.70603772 ], [ -74.00551522, 40.70598576 ], [ -74.00565697, 40.70609206 ], [ -74.00564673, 40.7061001 ], [ -74.00566021, 40.70611018 ], [ -74.00560128, 40.70615526 ], [ -74.0055878, 40.70614518 ], [ -74.00557999, 40.70615117 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00976757, 40.7098746 ], [ -74.00960498, 40.70979636 ], [ -74.00965735, 40.70973338 ], [ -74.00966238, 40.70972732 ], [ -74.00983504, 40.70981039 ], [ -74.00977772, 40.70987951 ], [ -74.00976757, 40.7098746 ] ] ] } }, { "type": "Feature", "properties": { "height": 81.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.006109, 40.70743147 ], [ -74.00609391, 40.70744428 ], [ -74.00594632, 40.7073375 ], [ -74.00586278, 40.70736937 ], [ -74.00573962, 40.70741636 ], [ -74.00569021, 40.70743529 ], [ -74.00568608, 40.7074438 ], [ -74.0057362, 40.70749317 ], [ -74.00582711, 40.70758299 ], [ -74.00590455, 40.70765926 ], [ -74.00588874, 40.70767219 ], [ -74.00565688, 40.70744428 ], [ -74.00566173, 40.70742528 ], [ -74.00594569, 40.7073136 ], [ -74.006109, 40.70743147 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00738228, 40.7066521 ], [ -74.0073662, 40.70666858 ], [ -74.00716111, 40.70653538 ], [ -74.00699052, 40.70671209 ], [ -74.00716381, 40.70683317 ], [ -74.00714889, 40.70684897 ], [ -74.00695683, 40.70671271 ], [ -74.00715491, 40.70650617 ], [ -74.00738228, 40.7066521 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00899709, 40.70959208 ], [ -74.00885039, 40.70975367 ], [ -74.0087858, 40.70970811 ], [ -74.00892675, 40.70955429 ], [ -74.00899709, 40.70959208 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01125357, 40.70767049 ], [ -74.01121889, 40.7077059 ], [ -74.01124827, 40.7077232 ], [ -74.01117981, 40.70779511 ], [ -74.01113041, 40.70777019 ], [ -74.01105531, 40.70773226 ], [ -74.01113382, 40.70765006 ], [ -74.0111764, 40.70767601 ], [ -74.01120838, 40.70764332 ], [ -74.01125357, 40.70767049 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01368773, 40.70632462 ], [ -74.01359619, 40.70628471 ], [ -74.01357921, 40.70627729 ], [ -74.01358487, 40.70626837 ], [ -74.0136324, 40.70619489 ], [ -74.01365072, 40.70616656 ], [ -74.01365512, 40.70615996 ], [ -74.01376642, 40.70620558 ], [ -74.01368773, 40.70632462 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01393656, 40.70822221 ], [ -74.01391536, 40.70827151 ], [ -74.01389982, 40.70826756 ], [ -74.01361371, 40.7081962 ], [ -74.01363491, 40.70814696 ], [ -74.01393656, 40.70822221 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01448454, 40.7085266 ], [ -74.01439075, 40.70878039 ], [ -74.01435554, 40.70877208 ], [ -74.01432724, 40.70876548 ], [ -74.01442911, 40.70851332 ], [ -74.01445067, 40.7085187 ], [ -74.01448454, 40.7085266 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01143494, 40.70682677 ], [ -74.01133864, 40.70679272 ], [ -74.01136469, 40.70675377 ], [ -74.01138077, 40.7067328 ], [ -74.0114088, 40.70674512 ], [ -74.0115112, 40.70661172 ], [ -74.01155872, 40.7066299 ], [ -74.01143494, 40.70682677 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00551809, 40.70990191 ], [ -74.00534598, 40.71004477 ], [ -74.00529154, 40.70999288 ], [ -74.00545458, 40.70985751 ], [ -74.00551809, 40.70990191 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00692764, 40.71084746 ], [ -74.00687365, 40.7108858 ], [ -74.00672193, 40.71075928 ], [ -74.00668114, 40.71072516 ], [ -74.00673181, 40.71068417 ], [ -74.00692764, 40.71084746 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01222141, 40.70541769 ], [ -74.01220147, 40.70564568 ], [ -74.0121323, 40.70563839 ], [ -74.01214802, 40.70541517 ], [ -74.01222141, 40.70541769 ] ] ] } }, { "type": "Feature", "properties": { "height": 109.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01496487, 40.70790767 ], [ -74.01491995, 40.7079806 ], [ -74.01479832, 40.70794152 ], [ -74.01476751, 40.70798986 ], [ -74.01473418, 40.70797822 ], [ -74.01480955, 40.70785258 ], [ -74.01496487, 40.70790767 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01229741, 40.7054202 ], [ -74.01228914, 40.70555068 ], [ -74.0122409, 40.70564977 ], [ -74.01220147, 40.70564568 ], [ -74.01222141, 40.70541769 ], [ -74.01229741, 40.7054202 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00770899, 40.70630296 ], [ -74.00770262, 40.7063093 ], [ -74.00769345, 40.70631829 ], [ -74.00765249, 40.7062937 ], [ -74.00750831, 40.70620817 ], [ -74.00734104, 40.70637236 ], [ -74.00748594, 40.70645721 ], [ -74.00752834, 40.70648015 ], [ -74.00751882, 40.70648969 ], [ -74.00751154, 40.70649691 ], [ -74.00730098, 40.70637358 ], [ -74.00750094, 40.70618161 ], [ -74.00770899, 40.70630296 ] ] ] } }, { "type": "Feature", "properties": { "height": 129.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00607253, 40.70752231 ], [ -74.00600453, 40.7075787 ], [ -74.00597857, 40.70756079 ], [ -74.00595369, 40.70758142 ], [ -74.00587652, 40.70752776 ], [ -74.00590131, 40.7075072 ], [ -74.00589009, 40.70749937 ], [ -74.00595818, 40.70744298 ], [ -74.00596941, 40.70745081 ], [ -74.00597929, 40.70744257 ], [ -74.00605663, 40.70749616 ], [ -74.00604675, 40.7075044 ], [ -74.00607253, 40.70752231 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01109367, 40.7128461 ], [ -74.01100518, 40.7129573 ], [ -74.0109008, 40.71290956 ], [ -74.01098928, 40.71279837 ], [ -74.01109367, 40.7128461 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01201381, 40.70788282 ], [ -74.01193889, 40.70797502 ], [ -74.0118151, 40.70791721 ], [ -74.01189011, 40.707825 ], [ -74.01201381, 40.70788282 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0143285, 40.70882792 ], [ -74.01431898, 40.70885345 ], [ -74.01430981, 40.70887702 ], [ -74.01426481, 40.70899216 ], [ -74.01425565, 40.70901579 ], [ -74.01424972, 40.70903077 ], [ -74.01417857, 40.70901586 ], [ -74.01425735, 40.70881198 ], [ -74.0143285, 40.70882792 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0063785, 40.70925276 ], [ -74.00629801, 40.70934279 ], [ -74.00617844, 40.7092813 ], [ -74.00623881, 40.70921381 ], [ -74.00625929, 40.70919087 ], [ -74.00633583, 40.70923057 ], [ -74.0063785, 40.70925276 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0064297, 40.71020377 ], [ -74.00640787, 40.71022188 ], [ -74.00612068, 40.71007521 ], [ -74.00601459, 40.71018341 ], [ -74.00603849, 40.71019621 ], [ -74.00602528, 40.71020956 ], [ -74.00607882, 40.71024041 ], [ -74.00606562, 40.71025477 ], [ -74.0059686, 40.71019437 ], [ -74.00611484, 40.71004429 ], [ -74.0064297, 40.71020377 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00874358, 40.7125958 ], [ -74.00866013, 40.71255746 ], [ -74.00866983, 40.7125448 ], [ -74.00876883, 40.7124204 ], [ -74.00885201, 40.7124588 ], [ -74.00874358, 40.7125958 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00988597, 40.71037516 ], [ -74.00981599, 40.7104534 ], [ -74.0096825, 40.71039171 ], [ -74.00974556, 40.71030557 ], [ -74.00988597, 40.71037516 ] ] ] } }, { "type": "Feature", "properties": { "height": 42.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00974278, 40.7093449 ], [ -74.00967891, 40.70941619 ], [ -74.00958405, 40.70952208 ], [ -74.0095774, 40.70952957 ], [ -74.00951982, 40.70949968 ], [ -74.00968529, 40.709315 ], [ -74.00974278, 40.7093449 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00550722, 40.70800798 ], [ -74.00577789, 40.70788908 ], [ -74.0058078, 40.70787689 ], [ -74.00583978, 40.70786212 ], [ -74.0058723, 40.70789439 ], [ -74.00552708, 40.7080442 ], [ -74.00550722, 40.70800798 ] ] ] } }, { "type": "Feature", "properties": { "height": 63.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0149063, 40.7085285 ], [ -74.01485644, 40.70865829 ], [ -74.01480191, 40.70864631 ], [ -74.0147464, 40.70863398 ], [ -74.01479634, 40.70850419 ], [ -74.0149063, 40.7085285 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0115545, 40.70578167 ], [ -74.01156537, 40.70570908 ], [ -74.01175887, 40.70570697 ], [ -74.01177719, 40.70572978 ], [ -74.01177719, 40.70575648 ], [ -74.01175959, 40.70578086 ], [ -74.0115545, 40.70578167 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00519218, 40.70817611 ], [ -74.00510388, 40.7079725 ], [ -74.00516739, 40.70795037 ], [ -74.0052601, 40.70814962 ], [ -74.00519218, 40.70817611 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01316931, 40.71368498 ], [ -74.01295605, 40.71358857 ], [ -74.012998, 40.71353532 ], [ -74.01321118, 40.71363167 ], [ -74.01316931, 40.71368498 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01294662, 40.71396851 ], [ -74.01290458, 40.71402169 ], [ -74.01269141, 40.71392527 ], [ -74.01273327, 40.71387196 ], [ -74.01294662, 40.71396851 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0099741, 40.70700968 ], [ -74.00984061, 40.7071437 ], [ -74.00981402, 40.70712851 ], [ -74.00976811, 40.70710236 ], [ -74.00990124, 40.70696807 ], [ -74.00994858, 40.70699511 ], [ -74.0099741, 40.70700968 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01160912, 40.70653606 ], [ -74.01160373, 40.70654328 ], [ -74.01159834, 40.70655036 ], [ -74.01135651, 40.70644556 ], [ -74.01124054, 40.7066154 ], [ -74.0112648, 40.70662588 ], [ -74.01129444, 40.7066378 ], [ -74.01127252, 40.70666627 ], [ -74.01124413, 40.70665496 ], [ -74.01121889, 40.70668949 ], [ -74.01116499, 40.70666572 ], [ -74.01123362, 40.70656031 ], [ -74.01125267, 40.70656732 ], [ -74.0113496, 40.70642418 ], [ -74.01160912, 40.70653606 ] ] ] } }, { "type": "Feature", "properties": { "height": 95.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0116164, 40.70720546 ], [ -74.01157067, 40.70726266 ], [ -74.01156789, 40.70727696 ], [ -74.0114997, 40.70736229 ], [ -74.01148901, 40.70736487 ], [ -74.01142164, 40.70744931 ], [ -74.01140987, 40.70744039 ], [ -74.0113929, 40.70742378 ], [ -74.0115254, 40.70722609 ], [ -74.0115978, 40.70719647 ], [ -74.0116164, 40.70720546 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00740375, 40.70662997 ], [ -74.0073918, 40.70664216 ], [ -74.00715357, 40.70648839 ], [ -74.00694031, 40.70671318 ], [ -74.00713919, 40.70685919 ], [ -74.00712662, 40.70687267 ], [ -74.00691354, 40.7067153 ], [ -74.0071488, 40.70646756 ], [ -74.00740375, 40.70662997 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00873101, 40.71168459 ], [ -74.00862141, 40.71181588 ], [ -74.00855395, 40.7117834 ], [ -74.00870693, 40.71160091 ], [ -74.00873101, 40.71168459 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00718285, 40.71066681 ], [ -74.00706859, 40.71060498 ], [ -74.0071639, 40.71053212 ], [ -74.00728517, 40.71059429 ], [ -74.00718285, 40.71066681 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0085429, 40.7107716 ], [ -74.00852008, 40.71079836 ], [ -74.00812015, 40.71059449 ], [ -74.00814342, 40.710571 ], [ -74.0085429, 40.7107716 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00795917, 40.70680539 ], [ -74.00793258, 40.70683038 ], [ -74.00747364, 40.7065347 ], [ -74.00760578, 40.706603 ], [ -74.00761907, 40.70659 ], [ -74.00795917, 40.70680539 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01497825, 40.70805422 ], [ -74.0149398, 40.70811857 ], [ -74.01474792, 40.70804918 ], [ -74.01478404, 40.70798837 ], [ -74.01497825, 40.70805422 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01395193, 40.7081868 ], [ -74.01393656, 40.70822221 ], [ -74.01363491, 40.70814696 ], [ -74.01365701, 40.70809569 ], [ -74.01395193, 40.7081868 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00622507, 40.70693477 ], [ -74.00613919, 40.70686136 ], [ -74.00619461, 40.70682316 ], [ -74.00635631, 40.70695902 ], [ -74.00635398, 40.706968 ], [ -74.00627699, 40.70699797 ], [ -74.00622507, 40.70693477 ] ] ] } }, { "type": "Feature", "properties": { "height": 81.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01011019, 40.70936042 ], [ -74.01007273, 40.70940359 ], [ -74.01003338, 40.70938276 ], [ -74.00999682, 40.70942382 ], [ -74.00998712, 40.70941892 ], [ -74.00990115, 40.70937431 ], [ -74.00993628, 40.70933366 ], [ -74.00997437, 40.70928988 ], [ -74.01011019, 40.70936042 ] ] ] } }, { "type": "Feature", "properties": { "height": 71.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01433524, 40.70783052 ], [ -74.0143126, 40.70787097 ], [ -74.01402729, 40.70777271 ], [ -74.01405371, 40.70773021 ], [ -74.01421217, 40.70778666 ], [ -74.01433524, 40.70783052 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00668267, 40.70959337 ], [ -74.0065658, 40.70952787 ], [ -74.00663353, 40.70945882 ], [ -74.00664449, 40.70946617 ], [ -74.00664871, 40.70946331 ], [ -74.00676603, 40.70953182 ], [ -74.0067107, 40.7095897 ], [ -74.00669237, 40.709582 ], [ -74.00668267, 40.70959337 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00698235, 40.71080878 ], [ -74.00692764, 40.71084746 ], [ -74.00673181, 40.71068417 ], [ -74.00676765, 40.71065516 ], [ -74.00698235, 40.71080878 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01212044, 40.70813021 ], [ -74.01229489, 40.7082124 ], [ -74.01234762, 40.70823712 ], [ -74.01231079, 40.70828186 ], [ -74.0120837, 40.70817488 ], [ -74.01212044, 40.70813021 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0064492, 40.7101875 ], [ -74.0064297, 40.71020377 ], [ -74.00611484, 40.71004429 ], [ -74.0059686, 40.71019437 ], [ -74.00594659, 40.71018076 ], [ -74.00611278, 40.71001556 ], [ -74.0064492, 40.7101875 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00934563, 40.70901716 ], [ -74.00921861, 40.70914456 ], [ -74.00916328, 40.70911092 ], [ -74.00922625, 40.70904998 ], [ -74.00919939, 40.70903479 ], [ -74.00918672, 40.70902778 ], [ -74.00923784, 40.70897759 ], [ -74.0092868, 40.70899557 ], [ -74.00934563, 40.70901716 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01355092, 40.70777148 ], [ -74.01349944, 40.70789242 ], [ -74.0133956, 40.70785946 ], [ -74.01345722, 40.70773798 ], [ -74.01355092, 40.70777148 ] ] ] } }, { "type": "Feature", "properties": { "height": 3.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00591668, 40.70870719 ], [ -74.00576827, 40.70859367 ], [ -74.00582882, 40.70854369 ], [ -74.00597309, 40.7086617 ], [ -74.00591668, 40.70870719 ] ] ] } }, { "type": "Feature", "properties": { "height": 135.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01179157, 40.70728636 ], [ -74.01178025, 40.70728077 ], [ -74.01169437, 40.70723998 ], [ -74.01168161, 40.70723358 ], [ -74.01174432, 40.70715902 ], [ -74.01178519, 40.70715289 ], [ -74.01184627, 40.70718156 ], [ -74.01185193, 40.70721138 ], [ -74.01179157, 40.70728636 ] ] ] } }, { "type": "Feature", "properties": { "height": 136.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01240072, 40.70612802 ], [ -74.01257005, 40.70620381 ], [ -74.01258685, 40.7062113 ], [ -74.01254795, 40.70626122 ], [ -74.012347, 40.70617126 ], [ -74.0123858, 40.70612141 ], [ -74.01240072, 40.70612802 ] ] ] } }, { "type": "Feature", "properties": { "height": 73.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00990322, 40.7121321 ], [ -74.00981842, 40.71223328 ], [ -74.00972302, 40.71218739 ], [ -74.00980782, 40.7120862 ], [ -74.00990322, 40.7121321 ] ] ] } }, { "type": "Feature", "properties": { "height": 59.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0099308, 40.70900102 ], [ -74.00992505, 40.70900762 ], [ -74.00982255, 40.70912189 ], [ -74.00980333, 40.70911167 ], [ -74.00974691, 40.70908198 ], [ -74.00984977, 40.70896717 ], [ -74.00985507, 40.70896132 ], [ -74.00986612, 40.70896697 ], [ -74.0099308, 40.70900102 ] ] ] } }, { "type": "Feature", "properties": { "height": 134.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0091728, 40.70648227 ], [ -74.00916364, 40.70649262 ], [ -74.0091701, 40.70649589 ], [ -74.00910749, 40.70656637 ], [ -74.00909905, 40.70656201 ], [ -74.00909393, 40.7065678 ], [ -74.00907264, 40.7065569 ], [ -74.00902323, 40.7065317 ], [ -74.00899394, 40.70651665 ], [ -74.0090023, 40.70650726 ], [ -74.0090367, 40.70646858 ], [ -74.00906105, 40.7064412 ], [ -74.00906788, 40.70643351 ], [ -74.00907084, 40.70643017 ], [ -74.00909914, 40.70644461 ], [ -74.00914819, 40.70646967 ], [ -74.0091728, 40.70648227 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01373408, 40.70879707 ], [ -74.01360841, 40.70874409 ], [ -74.01365665, 40.70865748 ], [ -74.01372618, 40.70867491 ], [ -74.0137101, 40.70869636 ], [ -74.01378789, 40.70872346 ], [ -74.01373408, 40.70879707 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01376894, 40.70597936 ], [ -74.0137605, 40.70598958 ], [ -74.01343135, 40.70587755 ], [ -74.01350367, 40.7057878 ], [ -74.01351687, 40.70579441 ], [ -74.01358631, 40.70582907 ], [ -74.01353753, 40.70589887 ], [ -74.01376894, 40.70597936 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0072831, 40.71344912 ], [ -74.00728005, 40.71345307 ], [ -74.00722175, 40.71352531 ], [ -74.00709401, 40.71346689 ], [ -74.00715339, 40.7133909 ], [ -74.0072831, 40.71344912 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01429751, 40.70738891 ], [ -74.01426984, 40.70743658 ], [ -74.01418773, 40.70740907 ], [ -74.01413141, 40.70739041 ], [ -74.01417794, 40.70731026 ], [ -74.01431628, 40.7073565 ], [ -74.01429751, 40.70738891 ] ] ] } }, { "type": "Feature", "properties": { "height": 84.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00919148, 40.70650542 ], [ -74.00924278, 40.70644842 ], [ -74.00909977, 40.70636309 ], [ -74.00907892, 40.70638516 ], [ -74.00904793, 40.70636868 ], [ -74.00908791, 40.70632632 ], [ -74.00909698, 40.70631699 ], [ -74.0091392, 40.70634171 ], [ -74.00925598, 40.70640988 ], [ -74.00930225, 40.70643678 ], [ -74.00922598, 40.70652292 ], [ -74.00919148, 40.70650542 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00473898, 40.70779967 ], [ -74.0046788, 40.70782221 ], [ -74.00469461, 40.7078472 ], [ -74.00462984, 40.70787131 ], [ -74.00464286, 40.70789242 ], [ -74.0045904, 40.70791298 ], [ -74.0046028, 40.70793117 ], [ -74.0045675, 40.70794581 ], [ -74.00453767, 40.70790931 ], [ -74.00458214, 40.70789269 ], [ -74.00456525, 40.70786389 ], [ -74.00461322, 40.70784591 ], [ -74.00459831, 40.70782357 ], [ -74.00464125, 40.70780662 ], [ -74.00462427, 40.70777877 ], [ -74.00470404, 40.70774948 ], [ -74.00473898, 40.70779967 ] ] ] } }, { "type": "Feature", "properties": { "height": 109.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00606768, 40.70746641 ], [ -74.00605582, 40.70747642 ], [ -74.00593644, 40.70739218 ], [ -74.00576531, 40.7074534 ], [ -74.00594129, 40.70762957 ], [ -74.00593033, 40.70763842 ], [ -74.00585721, 40.70756358 ], [ -74.00584229, 40.70757345 ], [ -74.00575498, 40.70748336 ], [ -74.00576809, 40.7074771 ], [ -74.00574007, 40.70745061 ], [ -74.00575848, 40.70744196 ], [ -74.00574959, 40.70743168 ], [ -74.00587032, 40.7073821 ], [ -74.00587931, 40.70739252 ], [ -74.00593895, 40.7073708 ], [ -74.00606768, 40.70746641 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00667809, 40.71028296 ], [ -74.00665177, 40.71030428 ], [ -74.00653624, 40.71039791 ], [ -74.00649465, 40.71043161 ], [ -74.00644695, 40.71039736 ], [ -74.00662311, 40.71025477 ], [ -74.00667809, 40.71028296 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00402833, 40.70668472 ], [ -74.00397308, 40.70671979 ], [ -74.00384435, 40.70657856 ], [ -74.00383411, 40.70656739 ], [ -74.00389304, 40.70653627 ], [ -74.00389879, 40.70654267 ], [ -74.00402833, 40.70668472 ] ] ] } }, { "type": "Feature", "properties": { "height": 252.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00776451, 40.70644216 ], [ -74.00770522, 40.70650072 ], [ -74.00769282, 40.70650229 ], [ -74.00758718, 40.70644079 ], [ -74.00758601, 40.70643119 ], [ -74.0076453, 40.70637276 ], [ -74.00765779, 40.7063712 ], [ -74.00776343, 40.70643269 ], [ -74.00776451, 40.70644216 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00646537, 40.71017401 ], [ -74.0064492, 40.7101875 ], [ -74.00611278, 40.71001556 ], [ -74.00594659, 40.71018076 ], [ -74.00592763, 40.71016911 ], [ -74.00610685, 40.70998996 ], [ -74.00646537, 40.71017401 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00948748, 40.70921238 ], [ -74.00933692, 40.70938051 ], [ -74.00929084, 40.70934292 ], [ -74.00936567, 40.70925917 ], [ -74.00943304, 40.70918406 ], [ -74.00948748, 40.70921238 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00408627, 40.70664686 ], [ -74.00402833, 40.70668472 ], [ -74.00389879, 40.70654267 ], [ -74.00395817, 40.70650651 ], [ -74.00408627, 40.70664686 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01232669, 40.70721608 ], [ -74.01230091, 40.70720376 ], [ -74.01234322, 40.70715139 ], [ -74.01236891, 40.70716372 ], [ -74.01252235, 40.70723692 ], [ -74.01248067, 40.70728929 ], [ -74.01232669, 40.70721608 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00909474, 40.70964526 ], [ -74.00904712, 40.7096964 ], [ -74.00908782, 40.7097124 ], [ -74.0089519, 40.70984641 ], [ -74.00891687, 40.70980072 ], [ -74.00906779, 40.70963062 ], [ -74.00909474, 40.70964526 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00772498, 40.70699667 ], [ -74.00764908, 40.70706232 ], [ -74.00754334, 40.70699286 ], [ -74.00760919, 40.7069204 ], [ -74.00772498, 40.70699667 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01309655, 40.70791986 ], [ -74.01304157, 40.7080041 ], [ -74.01293189, 40.7081725 ], [ -74.01287583, 40.70818932 ], [ -74.01307849, 40.70787819 ], [ -74.01309655, 40.70791986 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00622632, 40.71048602 ], [ -74.00619515, 40.71050747 ], [ -74.00602366, 40.710358 ], [ -74.00597138, 40.71039307 ], [ -74.00596069, 40.71038708 ], [ -74.00595764, 40.71037796 ], [ -74.00603229, 40.71030339 ], [ -74.00622632, 40.71048602 ] ] ] } }, { "type": "Feature", "properties": { "height": 95.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01186182, 40.70732109 ], [ -74.01184735, 40.70737727 ], [ -74.01169284, 40.70756596 ], [ -74.01166014, 40.70755827 ], [ -74.01164595, 40.70755432 ], [ -74.01171485, 40.70747356 ], [ -74.01171395, 40.70746511 ], [ -74.01178663, 40.70737931 ], [ -74.01179714, 40.70737706 ], [ -74.01185113, 40.70731387 ], [ -74.01186182, 40.70732109 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00682478, 40.70817229 ], [ -74.00688883, 40.70811325 ], [ -74.00691695, 40.70808738 ], [ -74.00698109, 40.70812742 ], [ -74.00685613, 40.7082427 ], [ -74.0067919, 40.70820266 ], [ -74.00682478, 40.70817229 ] ] ] } }, { "type": "Feature", "properties": { "height": 41.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01200249, 40.70788479 ], [ -74.01193611, 40.70796637 ], [ -74.01182651, 40.70791516 ], [ -74.01189281, 40.70783358 ], [ -74.01200249, 40.70788479 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00573566, 40.71019206 ], [ -74.00558565, 40.71009128 ], [ -74.00563981, 40.71004457 ], [ -74.005776, 40.71013609 ], [ -74.00578525, 40.71014221 ], [ -74.00573566, 40.71019206 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00708125, 40.70909948 ], [ -74.00680439, 40.7093818 ], [ -74.00677546, 40.70936567 ], [ -74.00705412, 40.7090843 ], [ -74.00708125, 40.70909948 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00937708, 40.70898658 ], [ -74.00934563, 40.70901716 ], [ -74.0092868, 40.70899557 ], [ -74.00923784, 40.70897759 ], [ -74.00918502, 40.70895819 ], [ -74.00913417, 40.70893946 ], [ -74.00919121, 40.70888716 ], [ -74.00937708, 40.70898658 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00790357, 40.71096438 ], [ -74.00785838, 40.7110083 ], [ -74.0078706, 40.71101551 ], [ -74.00780224, 40.7110819 ], [ -74.00778975, 40.71107448 ], [ -74.00776622, 40.71109729 ], [ -74.00773855, 40.71103669 ], [ -74.00784751, 40.71093087 ], [ -74.00790357, 40.71096438 ] ] ] } }, { "type": "Feature", "properties": { "height": 63.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0116305, 40.70650767 ], [ -74.01162691, 40.70651236 ], [ -74.01161972, 40.7065221 ], [ -74.01133828, 40.70639959 ], [ -74.01123362, 40.70656031 ], [ -74.01116499, 40.70666572 ], [ -74.01114487, 40.7066568 ], [ -74.01132669, 40.70637848 ], [ -74.0116305, 40.70650767 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00640787, 40.71022188 ], [ -74.00638703, 40.71023932 ], [ -74.00612679, 40.71010939 ], [ -74.00605052, 40.71018947 ], [ -74.00604738, 40.71018702 ], [ -74.00603849, 40.71019621 ], [ -74.00601459, 40.71018341 ], [ -74.00612068, 40.71007521 ], [ -74.00640787, 40.71022188 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00943304, 40.70918406 ], [ -74.00936567, 40.70925917 ], [ -74.00925473, 40.70920156 ], [ -74.00932641, 40.70912876 ], [ -74.00943304, 40.70918406 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0041399, 40.70661206 ], [ -74.00408627, 40.70664686 ], [ -74.00395817, 40.70650651 ], [ -74.00401297, 40.70647307 ], [ -74.0041399, 40.70661206 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00765249, 40.7062937 ], [ -74.00762922, 40.7062937 ], [ -74.00761799, 40.70630412 ], [ -74.0075729, 40.70627416 ], [ -74.00751083, 40.70623786 ], [ -74.00737949, 40.70636677 ], [ -74.00744157, 40.70640307 ], [ -74.00749124, 40.7064286 ], [ -74.00748064, 40.7064393 ], [ -74.00748594, 40.70645721 ], [ -74.00734104, 40.70637236 ], [ -74.00750831, 40.70620817 ], [ -74.00765249, 40.7062937 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00476162, 40.70910187 ], [ -74.00465149, 40.70919407 ], [ -74.0045816, 40.70914817 ], [ -74.00468769, 40.70905338 ], [ -74.00476162, 40.70910187 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01310365, 40.70802221 ], [ -74.01298911, 40.70818782 ], [ -74.01293189, 40.7081725 ], [ -74.01304157, 40.7080041 ], [ -74.01310365, 40.70802221 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00936567, 40.70925917 ], [ -74.00929084, 40.70934292 ], [ -74.00919894, 40.70925821 ], [ -74.00925473, 40.70920156 ], [ -74.00936567, 40.70925917 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00857605, 40.71073551 ], [ -74.00855772, 40.7107554 ], [ -74.00816004, 40.71055432 ], [ -74.00817971, 40.71053437 ], [ -74.00857605, 40.71073551 ] ] ] } }, { "type": "Feature", "properties": { "height": 11.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00505753, 40.70712272 ], [ -74.00491577, 40.70721241 ], [ -74.00486268, 40.70716392 ], [ -74.00500444, 40.70707417 ], [ -74.00505753, 40.70712272 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00397308, 40.70671979 ], [ -74.00392197, 40.70675309 ], [ -74.00380707, 40.70662636 ], [ -74.00378973, 40.70660729 ], [ -74.00384435, 40.70657856 ], [ -74.00397308, 40.70671979 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00395763, 40.70980658 ], [ -74.00385127, 40.70990021 ], [ -74.00378012, 40.70985377 ], [ -74.00388639, 40.70976021 ], [ -74.00395763, 40.70980658 ] ] ] } }, { "type": "Feature", "properties": { "height": 84.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00563218, 40.70939141 ], [ -74.0055649, 40.7094674 ], [ -74.00545764, 40.70941286 ], [ -74.00552995, 40.70933952 ], [ -74.00563218, 40.70939141 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01026802, 40.71042882 ], [ -74.01020622, 40.71050686 ], [ -74.01019463, 40.71050161 ], [ -74.0101357, 40.71057597 ], [ -74.01008612, 40.7105535 ], [ -74.01020685, 40.71040097 ], [ -74.01026802, 40.71042882 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01300573, 40.70745279 ], [ -74.01296872, 40.70750522 ], [ -74.0129362, 40.70749072 ], [ -74.01279831, 40.7074295 ], [ -74.01283784, 40.70737972 ], [ -74.01297294, 40.70743849 ], [ -74.01300573, 40.70745279 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01342255, 40.70798619 ], [ -74.01337143, 40.70800791 ], [ -74.01309655, 40.70791986 ], [ -74.01307849, 40.70787819 ], [ -74.01342255, 40.70798619 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01424855, 40.70772756 ], [ -74.01421217, 40.70778666 ], [ -74.01405371, 40.70773021 ], [ -74.01408964, 40.70767158 ], [ -74.01424855, 40.70772756 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01442139, 40.7068282 ], [ -74.01432554, 40.70680716 ], [ -74.01430137, 40.70680137 ], [ -74.01433811, 40.706714 ], [ -74.01437665, 40.7067234 ], [ -74.01445723, 40.70674308 ], [ -74.01442139, 40.7068282 ] ] ] } }, { "type": "Feature", "properties": { "height": 61.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00663039, 40.70850031 ], [ -74.00661305, 40.70851638 ], [ -74.00659248, 40.70853531 ], [ -74.00658251, 40.70854457 ], [ -74.00652394, 40.70859878 ], [ -74.0064854, 40.70857488 ], [ -74.00644399, 40.7085492 ], [ -74.00649959, 40.70849766 ], [ -74.00652277, 40.70851209 ], [ -74.0065737, 40.70846497 ], [ -74.00663039, 40.70850031 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01426562, 40.70831468 ], [ -74.01422259, 40.70830488 ], [ -74.01423669, 40.70827226 ], [ -74.01409242, 40.70823549 ], [ -74.01410168, 40.70821581 ], [ -74.01412135, 40.70822146 ], [ -74.01413878, 40.70818646 ], [ -74.01429778, 40.70823487 ], [ -74.01426562, 40.70831468 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00910309, 40.71115912 ], [ -74.00897023, 40.71131499 ], [ -74.00891929, 40.71128986 ], [ -74.00905269, 40.7111342 ], [ -74.00910309, 40.71115912 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00750678, 40.70928579 ], [ -74.00725454, 40.70953978 ], [ -74.00722669, 40.70952378 ], [ -74.0074784, 40.70926979 ], [ -74.00750678, 40.70928579 ] ] ] } }, { "type": "Feature", "properties": { "height": 38.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00741183, 40.70662159 ], [ -74.00740375, 40.70662997 ], [ -74.0071488, 40.70646756 ], [ -74.00691354, 40.7067153 ], [ -74.00712662, 40.70687267 ], [ -74.00711907, 40.7068807 ], [ -74.00689377, 40.70671536 ], [ -74.00714854, 40.70645298 ], [ -74.00741183, 40.70662159 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01342255, 40.70798619 ], [ -74.01328771, 40.70829752 ], [ -74.01326867, 40.70825912 ], [ -74.01333505, 40.70809242 ], [ -74.01337143, 40.70800791 ], [ -74.01342255, 40.70798619 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01395875, 40.70762521 ], [ -74.01392902, 40.70769228 ], [ -74.01389174, 40.70777706 ], [ -74.01386138, 40.70784461 ], [ -74.01385284, 40.70786429 ], [ -74.01383398, 40.70785789 ], [ -74.01381287, 40.70785068 ], [ -74.01382517, 40.70782262 ], [ -74.0138444, 40.70777979 ], [ -74.01389273, 40.70767049 ], [ -74.01391168, 40.70762759 ], [ -74.01391914, 40.70761091 ], [ -74.01393423, 40.70761636 ], [ -74.01395875, 40.70762521 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00592153, 40.7077313 ], [ -74.00587392, 40.70768411 ], [ -74.00588874, 40.70767219 ], [ -74.00590455, 40.70765926 ], [ -74.0059182, 40.70764816 ], [ -74.00593033, 40.70763842 ], [ -74.00594129, 40.70762957 ], [ -74.00599339, 40.70758741 ], [ -74.00605223, 40.70763236 ], [ -74.00592153, 40.7077313 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0080217, 40.70731632 ], [ -74.00794372, 40.70738401 ], [ -74.0079457, 40.70739497 ], [ -74.00785263, 40.70733532 ], [ -74.00793519, 40.70726082 ], [ -74.0080217, 40.70731632 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01261299, 40.7064429 ], [ -74.01257409, 40.7064888 ], [ -74.01245048, 40.70643078 ], [ -74.01240251, 40.70640886 ], [ -74.0124388, 40.70636269 ], [ -74.01257508, 40.70642547 ], [ -74.01261299, 40.7064429 ] ] ] } }, { "type": "Feature", "properties": { "height": 129.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00994499, 40.71109062 ], [ -74.00991076, 40.71113359 ], [ -74.00988579, 40.71116491 ], [ -74.00977817, 40.71111561 ], [ -74.00983737, 40.71104132 ], [ -74.00994499, 40.71109062 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0115863, 40.70585522 ], [ -74.01153743, 40.70609479 ], [ -74.01151569, 40.70608539 ], [ -74.01149153, 40.70607477 ], [ -74.01154462, 40.70584841 ], [ -74.0115863, 40.70585522 ] ] ] } }, { "type": "Feature", "properties": { "height": 256.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0077584, 40.70644079 ], [ -74.00770199, 40.7064965 ], [ -74.00769444, 40.70649752 ], [ -74.00759284, 40.70643827 ], [ -74.00759212, 40.70643262 ], [ -74.00764854, 40.70637692 ], [ -74.00765617, 40.7063759 ], [ -74.00775768, 40.70643507 ], [ -74.0077584, 40.70644079 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00687365, 40.7108858 ], [ -74.00682748, 40.71091841 ], [ -74.00667548, 40.71079156 ], [ -74.00672193, 40.71075928 ], [ -74.00687365, 40.7108858 ] ] ] } }, { "type": "Feature", "properties": { "height": 58.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00982731, 40.70670658 ], [ -74.00981447, 40.70672081 ], [ -74.00978473, 40.70675397 ], [ -74.00976515, 40.70674247 ], [ -74.00965699, 40.7066792 ], [ -74.00963974, 40.70666906 ], [ -74.00967657, 40.70663242 ], [ -74.00968888, 40.70662016 ], [ -74.00982731, 40.70670658 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00797957, 40.70678591 ], [ -74.00795917, 40.70680539 ], [ -74.00761907, 40.70659 ], [ -74.00763228, 40.70657706 ], [ -74.00763785, 40.70657168 ], [ -74.00797957, 40.70678591 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0123054, 40.70630242 ], [ -74.01226911, 40.70634859 ], [ -74.01220623, 40.70631917 ], [ -74.01210373, 40.70627082 ], [ -74.0121296, 40.70622152 ], [ -74.01214083, 40.70622656 ], [ -74.01218027, 40.70624481 ], [ -74.0123054, 40.70630242 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00617575, 40.70838829 ], [ -74.00616829, 40.70838387 ], [ -74.00628903, 40.70827192 ], [ -74.00602241, 40.70810808 ], [ -74.00566901, 40.7082427 ], [ -74.00565751, 40.70823188 ], [ -74.0057318, 40.70820382 ], [ -74.00597174, 40.70811291 ], [ -74.00602331, 40.70809337 ], [ -74.00606355, 40.70811836 ], [ -74.00625336, 40.70823658 ], [ -74.00630421, 40.7082681 ], [ -74.00617575, 40.70838829 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01416384, 40.70806627 ], [ -74.01405748, 40.7080329 ], [ -74.01406907, 40.70800886 ], [ -74.01409161, 40.70801629 ], [ -74.01412431, 40.70802711 ], [ -74.01421037, 40.70805551 ], [ -74.01422178, 40.70803597 ], [ -74.01424442, 40.70804318 ], [ -74.01426553, 40.70800498 ], [ -74.01435563, 40.70783781 ], [ -74.01436452, 40.70784101 ], [ -74.01426921, 40.70808268 ], [ -74.01417103, 40.70805258 ], [ -74.01416384, 40.70806627 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00825948, 40.71097466 ], [ -74.00824161, 40.71099509 ], [ -74.00790653, 40.71081151 ], [ -74.00792702, 40.71079026 ], [ -74.00825948, 40.71097466 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0048926, 40.70774492 ], [ -74.00473898, 40.70779967 ], [ -74.00470404, 40.70774948 ], [ -74.0048625, 40.70768581 ], [ -74.0048926, 40.70774492 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0073918, 40.70664216 ], [ -74.00738228, 40.7066521 ], [ -74.00715491, 40.70650617 ], [ -74.00695683, 40.70671271 ], [ -74.00714889, 40.70684897 ], [ -74.00713919, 40.70685919 ], [ -74.00694031, 40.70671318 ], [ -74.00715357, 40.70648839 ], [ -74.0073918, 40.70664216 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01012528, 40.70927932 ], [ -74.01011729, 40.7092751 ], [ -74.01007812, 40.70925481 ], [ -74.01006519, 40.709248 ], [ -74.01002647, 40.70922791 ], [ -74.00998568, 40.70920666 ], [ -74.01002323, 40.70916526 ], [ -74.01004695, 40.70917759 ], [ -74.01005971, 40.70916349 ], [ -74.01012537, 40.70919761 ], [ -74.01011935, 40.70920442 ], [ -74.01016948, 40.7092305 ], [ -74.01012528, 40.70927932 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.014431, 40.70572052 ], [ -74.01424038, 40.70615288 ], [ -74.01396289, 40.70605849 ], [ -74.01397151, 40.706048 ], [ -74.01423175, 40.70613558 ], [ -74.01441761, 40.70571698 ], [ -74.014431, 40.70572052 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00630708, 40.70783522 ], [ -74.00618644, 40.7079266 ], [ -74.00612589, 40.70788881 ], [ -74.0062522, 40.7077932 ], [ -74.00630708, 40.70783522 ] ] ] } }, { "type": "Feature", "properties": { "height": 51.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00770073, 40.71069296 ], [ -74.00779694, 40.71059776 ], [ -74.00786539, 40.71063712 ], [ -74.00777107, 40.71073231 ], [ -74.00770073, 40.71069296 ] ] ] } }, { "type": "Feature", "properties": { "height": 63.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01232319, 40.70605972 ], [ -74.01218027, 40.70624481 ], [ -74.01214083, 40.70622656 ], [ -74.01227989, 40.70604031 ], [ -74.01232319, 40.70605972 ] ] ] } }, { "type": "Feature", "properties": { "height": 33.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00651873, 40.70936846 ], [ -74.00645477, 40.70943989 ], [ -74.00635541, 40.70938889 ], [ -74.00641937, 40.70931739 ], [ -74.00651873, 40.70936846 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00852008, 40.71079836 ], [ -74.00850562, 40.71081532 ], [ -74.00848523, 40.7108047 ], [ -74.0081021, 40.71061267 ], [ -74.00812015, 40.71059449 ], [ -74.00852008, 40.71079836 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00567898, 40.71024919 ], [ -74.00561682, 40.7103119 ], [ -74.0055242, 40.71022406 ], [ -74.00558493, 40.71017456 ], [ -74.00567898, 40.71024919 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01333505, 40.70809242 ], [ -74.01326867, 40.70825912 ], [ -74.01321261, 40.70824529 ], [ -74.01328178, 40.70807567 ], [ -74.01333505, 40.70809242 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01166014, 40.70755827 ], [ -74.01160858, 40.7076184 ], [ -74.01151938, 40.70758619 ], [ -74.01145677, 40.7075565 ], [ -74.01136424, 40.7075025 ], [ -74.01140987, 40.70744039 ], [ -74.01142164, 40.70744931 ], [ -74.01140305, 40.70747247 ], [ -74.0114158, 40.70749746 ], [ -74.01149449, 40.70754009 ], [ -74.01158693, 40.70757972 ], [ -74.01162942, 40.70757359 ], [ -74.01164595, 40.70755432 ], [ -74.01166014, 40.70755827 ] ] ] } }, { "type": "Feature", "properties": { "height": 128.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00665671, 40.7087919 ], [ -74.00660083, 40.7088538 ], [ -74.00648935, 40.70879619 ], [ -74.00654514, 40.70873422 ], [ -74.00665671, 40.7087919 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01391914, 40.70761091 ], [ -74.01391168, 40.70762759 ], [ -74.01389273, 40.70767049 ], [ -74.0138444, 40.70777979 ], [ -74.01382517, 40.70782262 ], [ -74.01381287, 40.70785068 ], [ -74.01377622, 40.70783821 ], [ -74.01388231, 40.70759851 ], [ -74.01391914, 40.70761091 ] ] ] } }, { "type": "Feature", "properties": { "height": 131.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01344492, 40.706495 ], [ -74.01342102, 40.70648458 ], [ -74.01325771, 40.70641328 ], [ -74.01329777, 40.70636051 ], [ -74.01335473, 40.70638536 ], [ -74.01333065, 40.70641716 ], [ -74.0134027, 40.70644869 ], [ -74.01342695, 40.70641689 ], [ -74.01348498, 40.70644216 ], [ -74.01344492, 40.706495 ] ] ] } }, { "type": "Feature", "properties": { "height": 125.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01443495, 40.70958221 ], [ -74.01444241, 40.70955878 ], [ -74.01436443, 40.70953842 ], [ -74.01436955, 40.70952719 ], [ -74.01438976, 40.70946767 ], [ -74.01450583, 40.70949341 ], [ -74.01447178, 40.70959038 ], [ -74.01443495, 40.70958221 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00686054, 40.70707281 ], [ -74.00675579, 40.70715132 ], [ -74.00669255, 40.70710291 ], [ -74.0067972, 40.70702432 ], [ -74.00686054, 40.70707281 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00726217, 40.70725367 ], [ -74.00711251, 40.70713852 ], [ -74.00706203, 40.707101 ], [ -74.00709455, 40.70707526 ], [ -74.00729532, 40.7072282 ], [ -74.00726217, 40.70725367 ] ] ] } }, { "type": "Feature", "properties": { "height": 81.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01141374, 40.70791319 ], [ -74.0113575, 40.70788479 ], [ -74.01136702, 40.70787492 ], [ -74.01140808, 40.70789521 ], [ -74.01152827, 40.70775439 ], [ -74.01123641, 40.70757972 ], [ -74.01120039, 40.70760498 ], [ -74.0111852, 40.70759627 ], [ -74.01122302, 40.70755691 ], [ -74.01155306, 40.70775316 ], [ -74.01141374, 40.70791319 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00786, 40.7100302 ], [ -74.0078185, 40.71007201 ], [ -74.00766821, 40.7099856 ], [ -74.00770971, 40.70994386 ], [ -74.00786, 40.7100302 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00819597, 40.706552 ], [ -74.00817881, 40.70656848 ], [ -74.00783548, 40.70637767 ], [ -74.00784239, 40.70637086 ], [ -74.0078556, 40.70635799 ], [ -74.00819597, 40.706552 ] ] ] } }, { "type": "Feature", "properties": { "height": 104.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01115233, 40.70728636 ], [ -74.0109344, 40.70714097 ], [ -74.01100249, 40.70713042 ], [ -74.01113481, 40.7072186 ], [ -74.01115233, 40.70728636 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00563119, 40.71063998 ], [ -74.0054571, 40.71074798 ], [ -74.00542099, 40.71071447 ], [ -74.00559508, 40.71060648 ], [ -74.00563119, 40.71063998 ] ] ] } }, { "type": "Feature", "properties": { "height": 43.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00855772, 40.7107554 ], [ -74.0085429, 40.7107716 ], [ -74.00814342, 40.710571 ], [ -74.00816004, 40.71055432 ], [ -74.00855772, 40.7107554 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00709311, 40.70560911 ], [ -74.00699223, 40.70570561 ], [ -74.00709185, 40.70576206 ], [ -74.00707631, 40.70578038 ], [ -74.00692647, 40.70569621 ], [ -74.00706679, 40.70559052 ], [ -74.0070738, 40.7055959 ], [ -74.00709311, 40.70560911 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00643815, 40.70839286 ], [ -74.00626154, 40.70854348 ], [ -74.00617054, 40.70862091 ], [ -74.0061594, 40.70861321 ], [ -74.00614808, 40.70860538 ], [ -74.00641389, 40.70837549 ], [ -74.00642674, 40.70838468 ], [ -74.00643815, 40.70839286 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00626253, 40.71025947 ], [ -74.00623225, 40.71030142 ], [ -74.00618967, 40.71033009 ], [ -74.00617108, 40.71031939 ], [ -74.0061099, 40.71028167 ], [ -74.00617144, 40.71021269 ], [ -74.00626253, 40.71025947 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01163849, 40.70649697 ], [ -74.0116305, 40.70650767 ], [ -74.01132669, 40.70637848 ], [ -74.01114487, 40.7066568 ], [ -74.01113202, 40.70665196 ], [ -74.01132058, 40.70635976 ], [ -74.01163849, 40.70649697 ] ] ] } }, { "type": "Feature", "properties": { "height": 6.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00668465, 40.71050141 ], [ -74.00664171, 40.71053682 ], [ -74.00649465, 40.71043161 ], [ -74.00653624, 40.71039791 ], [ -74.00668465, 40.71050141 ] ] ] } }, { "type": "Feature", "properties": { "height": 43.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01158738, 40.70688077 ], [ -74.01157912, 40.70687778 ], [ -74.01157004, 40.70687458 ], [ -74.01175608, 40.706568 ], [ -74.01162691, 40.70651236 ], [ -74.0116305, 40.70650767 ], [ -74.01163849, 40.70649697 ], [ -74.01178339, 40.70655949 ], [ -74.01158738, 40.70688077 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00883881, 40.70555218 ], [ -74.00874727, 40.70573237 ], [ -74.00870972, 40.70567769 ], [ -74.00872301, 40.70565079 ], [ -74.00876793, 40.70556512 ], [ -74.00883881, 40.70555218 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01448454, 40.7085266 ], [ -74.01439075, 40.70878039 ], [ -74.01435554, 40.70877208 ], [ -74.01445067, 40.7085187 ], [ -74.01448454, 40.7085266 ] ] ] } }, { "type": "Feature", "properties": { "height": 104.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0112436, 40.7071471 ], [ -74.01116921, 40.7071661 ], [ -74.01101614, 40.70710869 ], [ -74.01099018, 40.7070521 ], [ -74.0112436, 40.7071471 ] ] ] } }, { "type": "Feature", "properties": { "height": 63.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01276112, 40.70625557 ], [ -74.01261299, 40.7064429 ], [ -74.01257508, 40.70642547 ], [ -74.01272438, 40.70623916 ], [ -74.01276112, 40.70625557 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00491577, 40.70721241 ], [ -74.00505753, 40.70712272 ], [ -74.00510657, 40.70716767 ], [ -74.00495278, 40.70724618 ], [ -74.00491577, 40.70721241 ] ] ] } }, { "type": "Feature", "properties": { "height": 58.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01010399, 40.70687927 ], [ -74.0100907, 40.70689262 ], [ -74.01006536, 40.70691809 ], [ -74.01004416, 40.7069057 ], [ -74.00993628, 40.70684209 ], [ -74.00991624, 40.70683018 ], [ -74.0099467, 40.70680171 ], [ -74.00995891, 40.70679027 ], [ -74.01010399, 40.70687927 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01482706, 40.70904576 ], [ -74.01471873, 40.70902049 ], [ -74.0147499, 40.70894116 ], [ -74.01485913, 40.70896588 ], [ -74.01482706, 40.70904576 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00453767, 40.70790931 ], [ -74.00447766, 40.70783597 ], [ -74.00462427, 40.70777877 ], [ -74.00464125, 40.70780662 ], [ -74.00459831, 40.70782357 ], [ -74.00461322, 40.70784591 ], [ -74.00456525, 40.70786389 ], [ -74.00458214, 40.70789269 ], [ -74.00453767, 40.70790931 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00834473, 40.70790801 ], [ -74.00831437, 40.70793096 ], [ -74.00825328, 40.7079311 ], [ -74.00822427, 40.70790849 ], [ -74.00822588, 40.70786402 ], [ -74.00825625, 40.70784101 ], [ -74.00831563, 40.70784141 ], [ -74.00834455, 40.70786402 ], [ -74.00834473, 40.70790801 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00731347, 40.70672306 ], [ -74.00724385, 40.70679511 ], [ -74.00721465, 40.70677917 ], [ -74.0072019, 40.70677229 ], [ -74.00715967, 40.70674941 ], [ -74.00716758, 40.7067411 ], [ -74.00721851, 40.70668717 ], [ -74.0072284, 40.70667682 ], [ -74.00731347, 40.70672306 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01394294, 40.70970961 ], [ -74.01393037, 40.70974087 ], [ -74.01391707, 40.70977369 ], [ -74.01386955, 40.70989401 ], [ -74.01385832, 40.70992179 ], [ -74.01384763, 40.7099491 ], [ -74.01381314, 40.70994079 ], [ -74.01382347, 40.70991376 ], [ -74.0138347, 40.70988591 ], [ -74.01388168, 40.70976552 ], [ -74.0138947, 40.70973222 ], [ -74.01390719, 40.70970055 ], [ -74.01394294, 40.70970961 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00799628, 40.70676977 ], [ -74.00797957, 40.70678591 ], [ -74.00763785, 40.70657168 ], [ -74.00764557, 40.70656412 ], [ -74.00765465, 40.70655499 ], [ -74.00769471, 40.70658026 ], [ -74.00799628, 40.70676977 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00995891, 40.70679027 ], [ -74.0099467, 40.70680171 ], [ -74.00991624, 40.70683018 ], [ -74.00978473, 40.70675397 ], [ -74.00981447, 40.70672081 ], [ -74.00982731, 40.70670658 ], [ -74.00995891, 40.70679027 ] ] ] } }, { "type": "Feature", "properties": { "height": 112.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0096693, 40.7071138 ], [ -74.0096339, 40.70715119 ], [ -74.00947131, 40.70705966 ], [ -74.00951362, 40.70702596 ], [ -74.0096693, 40.7071138 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01295444, 40.70733512 ], [ -74.01290754, 40.70739279 ], [ -74.0127931, 40.70733927 ], [ -74.01284008, 40.70728159 ], [ -74.01295444, 40.70733512 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00793187, 40.70995768 ], [ -74.00788875, 40.71000126 ], [ -74.00774609, 40.70991927 ], [ -74.00778337, 40.70988169 ], [ -74.00793187, 40.70995768 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00703571, 40.70907381 ], [ -74.00675777, 40.70935566 ], [ -74.00673783, 40.70934456 ], [ -74.00701451, 40.70906162 ], [ -74.00703571, 40.70907381 ] ] ] } }, { "type": "Feature", "properties": { "height": 167.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00701747, 40.70729446 ], [ -74.00695549, 40.70724741 ], [ -74.00703463, 40.70718762 ], [ -74.00704083, 40.70719211 ], [ -74.00711018, 40.70724536 ], [ -74.0070729, 40.70727328 ], [ -74.00703077, 40.70730468 ], [ -74.00701747, 40.70729446 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01161972, 40.7065221 ], [ -74.01161532, 40.70652789 ], [ -74.01160912, 40.70653606 ], [ -74.0113496, 40.70642418 ], [ -74.01125267, 40.70656732 ], [ -74.01123362, 40.70656031 ], [ -74.01133828, 40.70639959 ], [ -74.01161972, 40.7065221 ] ] ] } }, { "type": "Feature", "properties": { "height": 41.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00731922, 40.70571262 ], [ -74.00729595, 40.70573516 ], [ -74.00728265, 40.7057481 ], [ -74.00712518, 40.70565508 ], [ -74.00713973, 40.70564098 ], [ -74.00716174, 40.70561946 ], [ -74.00726657, 40.70568116 ], [ -74.00731248, 40.7057086 ], [ -74.00731922, 40.70571262 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01264362, 40.70718966 ], [ -74.01259691, 40.707247 ], [ -74.01248264, 40.70719347 ], [ -74.01252917, 40.7071362 ], [ -74.01264362, 40.70718966 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0129556, 40.71349351 ], [ -74.01293943, 40.71351421 ], [ -74.01262422, 40.713364 ], [ -74.01263077, 40.71333949 ], [ -74.0129556, 40.71349351 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01157004, 40.70687458 ], [ -74.01155262, 40.70686851 ], [ -74.01172878, 40.70657658 ], [ -74.01161532, 40.70652789 ], [ -74.01161972, 40.7065221 ], [ -74.01162691, 40.70651236 ], [ -74.01175608, 40.706568 ], [ -74.01157004, 40.70687458 ] ] ] } }, { "type": "Feature", "properties": { "height": 198.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00930332, 40.7122932 ], [ -74.00929174, 40.71230716 ], [ -74.0092567, 40.7123491 ], [ -74.00919867, 40.71232119 ], [ -74.00917801, 40.71231131 ], [ -74.00911638, 40.71228169 ], [ -74.00909653, 40.71227216 ], [ -74.00903491, 40.71224247 ], [ -74.00901479, 40.71223301 ], [ -74.00895532, 40.71220448 ], [ -74.00898828, 40.71216512 ], [ -74.00899978, 40.71215096 ], [ -74.0090429, 40.71209948 ], [ -74.0091021, 40.71212787 ], [ -74.00911962, 40.71213632 ], [ -74.00918412, 40.71216716 ], [ -74.00920119, 40.71217547 ], [ -74.00926577, 40.71220638 ], [ -74.00928311, 40.71221469 ], [ -74.00934429, 40.71224411 ], [ -74.00930332, 40.7122932 ] ], [ [ -74.00927754, 40.71222232 ], [ -74.00925931, 40.71221346 ], [ -74.00919508, 40.7121831 ], [ -74.00917738, 40.71217458 ], [ -74.00911342, 40.71214401 ], [ -74.00909563, 40.71213536 ], [ -74.0090465, 40.7121116 ], [ -74.00900904, 40.71215552 ], [ -74.00899727, 40.71216968 ], [ -74.00897095, 40.71220087 ], [ -74.00902134, 40.71222531 ], [ -74.00904102, 40.71223457 ], [ -74.00910291, 40.71226426 ], [ -74.00912267, 40.71227386 ], [ -74.00918457, 40.71230369 ], [ -74.00920487, 40.71231336 ], [ -74.00925347, 40.71233651 ], [ -74.00928167, 40.71230226 ], [ -74.00929317, 40.71228857 ], [ -74.0093283, 40.71224656 ], [ -74.00927754, 40.71222232 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00821421, 40.70653477 ], [ -74.00819597, 40.706552 ], [ -74.0078556, 40.70635799 ], [ -74.00787105, 40.70634246 ], [ -74.00821421, 40.70653477 ] ] ] } }, { "type": "Feature", "properties": { "height": 83.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01159834, 40.70655036 ], [ -74.01159214, 40.70655867 ], [ -74.01158864, 40.7065633 ], [ -74.01136981, 40.70646837 ], [ -74.0112648, 40.70662588 ], [ -74.01124054, 40.7066154 ], [ -74.01135651, 40.70644556 ], [ -74.01159834, 40.70655036 ] ] ] } }, { "type": "Feature", "properties": { "height": 64.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01397205, 40.70991648 ], [ -74.01402828, 40.70977151 ], [ -74.01408407, 40.70978397 ], [ -74.01402792, 40.70992888 ], [ -74.01397205, 40.70991648 ] ] ] } }, { "type": "Feature", "properties": { "height": 116.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00904964, 40.70658741 ], [ -74.00901496, 40.70662432 ], [ -74.00900733, 40.7066205 ], [ -74.00889423, 40.70656099 ], [ -74.00891408, 40.70653906 ], [ -74.00896187, 40.70648622 ], [ -74.0090023, 40.70650726 ], [ -74.00899394, 40.70651665 ], [ -74.00896708, 40.70654682 ], [ -74.00899628, 40.70656119 ], [ -74.00904605, 40.70658557 ], [ -74.00904964, 40.70658741 ] ] ] } }, { "type": "Feature", "properties": { "height": 82.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00574483, 40.70785687 ], [ -74.00571249, 40.70787539 ], [ -74.0056355, 40.70779817 ], [ -74.00554064, 40.70770291 ], [ -74.00546069, 40.70762276 ], [ -74.00549069, 40.7076056 ], [ -74.00554612, 40.70766109 ], [ -74.00553094, 40.70766981 ], [ -74.00567072, 40.70781009 ], [ -74.00568823, 40.70780008 ], [ -74.00574483, 40.70785687 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00817881, 40.70656848 ], [ -74.00816139, 40.70658509 ], [ -74.0078194, 40.70639306 ], [ -74.0078291, 40.70638386 ], [ -74.00783548, 40.70637767 ], [ -74.00817881, 40.70656848 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01278151, 40.70736678 ], [ -74.01274809, 40.70740778 ], [ -74.0125952, 40.70733627 ], [ -74.01262862, 40.70729528 ], [ -74.01278151, 40.70736678 ] ] ] } }, { "type": "Feature", "properties": { "height": 58.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00627573, 40.70673681 ], [ -74.00624384, 40.70676147 ], [ -74.00605789, 40.70661478 ], [ -74.00608331, 40.70659218 ], [ -74.00614745, 40.70664039 ], [ -74.0062098, 40.70668731 ], [ -74.00627573, 40.70673681 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00801262, 40.70675418 ], [ -74.00799628, 40.70676977 ], [ -74.00769471, 40.70658026 ], [ -74.00771888, 40.70657958 ], [ -74.00773001, 40.70656916 ], [ -74.0077752, 40.70659912 ], [ -74.00801262, 40.70675418 ] ] ] } }, { "type": "Feature", "properties": { "height": 43.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0123894, 40.7093707 ], [ -74.01235418, 40.70941578 ], [ -74.01221297, 40.70935348 ], [ -74.01224791, 40.70930819 ], [ -74.0123894, 40.7093707 ] ] ] } }, { "type": "Feature", "properties": { "height": 43.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0125157, 40.70920571 ], [ -74.01248129, 40.7092512 ], [ -74.01233972, 40.70918862 ], [ -74.01237448, 40.70914327 ], [ -74.0125157, 40.70920571 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01328178, 40.70807567 ], [ -74.01321261, 40.70824529 ], [ -74.01315961, 40.70826327 ], [ -74.01323121, 40.7080852 ], [ -74.0132401, 40.7080632 ], [ -74.01328178, 40.70807567 ] ] ] } }, { "type": "Feature", "properties": { "height": 104.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00919148, 40.70650542 ], [ -74.00913408, 40.70657032 ], [ -74.00908728, 40.70662459 ], [ -74.00907578, 40.7066188 ], [ -74.00905368, 40.70664366 ], [ -74.00902413, 40.70662888 ], [ -74.00905368, 40.70659708 ], [ -74.00907228, 40.706606 ], [ -74.00910192, 40.70657086 ], [ -74.00911019, 40.70657508 ], [ -74.00918259, 40.70649377 ], [ -74.00917522, 40.7064901 ], [ -74.00921232, 40.7064491 ], [ -74.0091021, 40.70638679 ], [ -74.00909474, 40.70639367 ], [ -74.00907892, 40.70638516 ], [ -74.00909977, 40.70636309 ], [ -74.00924278, 40.70644842 ], [ -74.00919148, 40.70650542 ] ] ] } }, { "type": "Feature", "properties": { "height": 73.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00848523, 40.7108047 ], [ -74.0084705, 40.71082077 ], [ -74.00808844, 40.7106265 ], [ -74.0081021, 40.71061267 ], [ -74.00848523, 40.7108047 ] ] ] } }, { "type": "Feature", "properties": { "height": 84.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01136702, 40.70787492 ], [ -74.01137655, 40.70786491 ], [ -74.01139981, 40.70787737 ], [ -74.01150644, 40.70775636 ], [ -74.01124252, 40.70759981 ], [ -74.01121808, 40.70761506 ], [ -74.01120039, 40.70760498 ], [ -74.01123641, 40.70757972 ], [ -74.01152827, 40.70775439 ], [ -74.01140808, 40.70789521 ], [ -74.01136702, 40.70787492 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00821546, 40.71019866 ], [ -74.00818393, 40.7102402 ], [ -74.00804631, 40.71016727 ], [ -74.00808314, 40.71012301 ], [ -74.00821546, 40.71019866 ] ] ] } }, { "type": "Feature", "properties": { "height": 69.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0124388, 40.70636269 ], [ -74.01240251, 40.70640886 ], [ -74.01226911, 40.70634859 ], [ -74.0123054, 40.70630242 ], [ -74.0124388, 40.70636269 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01155262, 40.70686851 ], [ -74.01153519, 40.70686232 ], [ -74.01170147, 40.70658509 ], [ -74.01160373, 40.70654328 ], [ -74.01160912, 40.70653606 ], [ -74.01161532, 40.70652789 ], [ -74.01172878, 40.70657658 ], [ -74.01155262, 40.70686851 ] ] ] } }, { "type": "Feature", "properties": { "height": 134.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0090367, 40.70646858 ], [ -74.0090023, 40.70650726 ], [ -74.00896187, 40.70648622 ], [ -74.00891408, 40.70653906 ], [ -74.00887141, 40.70651659 ], [ -74.00895118, 40.70642241 ], [ -74.0090367, 40.70646858 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00694093, 40.71069241 ], [ -74.00688677, 40.7107362 ], [ -74.00678678, 40.71066531 ], [ -74.00684104, 40.71062139 ], [ -74.00694093, 40.71069241 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01377747, 40.70636262 ], [ -74.01376705, 40.7063588 ], [ -74.01375367, 40.70635308 ], [ -74.0138126, 40.70626878 ], [ -74.01385554, 40.70620742 ], [ -74.01387961, 40.70617276 ], [ -74.01375448, 40.70612959 ], [ -74.01376355, 40.70611447 ], [ -74.01391438, 40.7061665 ], [ -74.01377747, 40.70636262 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00913444, 40.7090715 ], [ -74.00907093, 40.70912822 ], [ -74.00899188, 40.70903935 ], [ -74.00903581, 40.70900572 ], [ -74.00913444, 40.7090715 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01379993, 40.70637161 ], [ -74.01376597, 40.70641349 ], [ -74.01366608, 40.70653688 ], [ -74.01363347, 40.70657719 ], [ -74.01360652, 40.70656548 ], [ -74.01363823, 40.70652469 ], [ -74.01373507, 40.70639987 ], [ -74.01376705, 40.7063588 ], [ -74.01377747, 40.70636262 ], [ -74.01379993, 40.70637161 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00816139, 40.70658509 ], [ -74.00814405, 40.70660191 ], [ -74.00790626, 40.70647001 ], [ -74.00785668, 40.70644461 ], [ -74.00786719, 40.70643392 ], [ -74.00786189, 40.70641601 ], [ -74.00816139, 40.70658509 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00919939, 40.70903479 ], [ -74.00916462, 40.70907361 ], [ -74.00914306, 40.70906366 ], [ -74.00913444, 40.7090715 ], [ -74.00903581, 40.70900572 ], [ -74.00908, 40.70896881 ], [ -74.00909572, 40.70897746 ], [ -74.009141, 40.70900252 ], [ -74.00918672, 40.70902778 ], [ -74.00919939, 40.70903479 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01418773, 40.70971131 ], [ -74.01411183, 40.70990021 ], [ -74.01410904, 40.70990729 ], [ -74.01405811, 40.70989578 ], [ -74.01406691, 40.70987168 ], [ -74.01408757, 40.70987637 ], [ -74.01413994, 40.7097472 ], [ -74.01415009, 40.70972187 ], [ -74.01411632, 40.70970641 ], [ -74.01413249, 40.70968591 ], [ -74.01418773, 40.70971131 ] ] ] } }, { "type": "Feature", "properties": { "height": 140.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00915366, 40.7064997 ], [ -74.00911117, 40.70654757 ], [ -74.0090986, 40.7065411 ], [ -74.00908899, 40.70655186 ], [ -74.00902583, 40.70651972 ], [ -74.00903455, 40.70650991 ], [ -74.00902062, 40.70650276 ], [ -74.00906311, 40.70645489 ], [ -74.00907569, 40.70646136 ], [ -74.00908494, 40.70645101 ], [ -74.00914801, 40.70648322 ], [ -74.00913974, 40.70649262 ], [ -74.00915366, 40.7064997 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00784751, 40.71093087 ], [ -74.00773855, 40.71103669 ], [ -74.00771187, 40.71097847 ], [ -74.00772705, 40.7109639 ], [ -74.00779388, 40.71089887 ], [ -74.00784751, 40.71093087 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00593491, 40.70921157 ], [ -74.00607613, 40.70908266 ], [ -74.0061082, 40.70910139 ], [ -74.00598126, 40.7092356 ], [ -74.00593491, 40.70921157 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0075729, 40.70627416 ], [ -74.00755314, 40.7062747 ], [ -74.00752583, 40.70630072 ], [ -74.00750103, 40.70628642 ], [ -74.00743887, 40.70634832 ], [ -74.00746313, 40.70636207 ], [ -74.00743707, 40.70638849 ], [ -74.00744157, 40.70640307 ], [ -74.00737949, 40.70636677 ], [ -74.00751083, 40.70623786 ], [ -74.0075729, 40.70627416 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01168305, 40.70708091 ], [ -74.0115978, 40.70719647 ], [ -74.0115254, 40.70722609 ], [ -74.01163715, 40.70705939 ], [ -74.01168305, 40.70708091 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00597174, 40.70811291 ], [ -74.0057318, 40.70820382 ], [ -74.00571437, 40.70818081 ], [ -74.00595521, 40.70808329 ], [ -74.00597174, 40.70811291 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00705412, 40.7090843 ], [ -74.00677546, 40.70936567 ], [ -74.00675777, 40.70935566 ], [ -74.00703571, 40.70907381 ], [ -74.00705412, 40.7090843 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0096269, 40.70721009 ], [ -74.00959626, 40.70724618 ], [ -74.00944122, 40.70715296 ], [ -74.0094696, 40.70712197 ], [ -74.0096269, 40.70721009 ] ] ] } }, { "type": "Feature", "properties": { "height": 125.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01180792, 40.70729412 ], [ -74.01179157, 40.70728636 ], [ -74.01185193, 40.70721138 ], [ -74.01184627, 40.70718156 ], [ -74.01178519, 40.70715289 ], [ -74.01174432, 40.70715902 ], [ -74.01168161, 40.70723358 ], [ -74.01166383, 40.70722528 ], [ -74.01173605, 40.70713859 ], [ -74.01178214, 40.70712742 ], [ -74.01186685, 40.70716739 ], [ -74.01187493, 40.70717107 ], [ -74.01188104, 40.7072075 ], [ -74.01180792, 40.70729412 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01227989, 40.70604031 ], [ -74.01214083, 40.70622656 ], [ -74.0121296, 40.70622152 ], [ -74.01222779, 40.70601702 ], [ -74.01227989, 40.70604031 ] ] ] } }, { "type": "Feature", "properties": { "height": 77.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01161819, 40.70586046 ], [ -74.01156681, 40.70610759 ], [ -74.01154282, 40.70609717 ], [ -74.01153743, 40.70609479 ], [ -74.0115863, 40.70585522 ], [ -74.01161819, 40.70586046 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00685227, 40.70884801 ], [ -74.00665383, 40.70906428 ], [ -74.00664054, 40.7090574 ], [ -74.00663075, 40.70905229 ], [ -74.00682667, 40.70883439 ], [ -74.00685227, 40.70884801 ] ] ] } }, { "type": "Feature", "properties": { "height": 64.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00981447, 40.70672081 ], [ -74.00978473, 40.70675397 ], [ -74.00976515, 40.70674247 ], [ -74.00965699, 40.7066792 ], [ -74.00963974, 40.70666906 ], [ -74.00967657, 40.70663242 ], [ -74.00981447, 40.70672081 ] ] ] } }, { "type": "Feature", "properties": { "height": 88.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00687778, 40.70886156 ], [ -74.00667683, 40.70907619 ], [ -74.00665383, 40.70906428 ], [ -74.00685227, 40.70884801 ], [ -74.00687778, 40.70886156 ] ] ] } }, { "type": "Feature", "properties": { "height": 108.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00682667, 40.70883439 ], [ -74.00663075, 40.70905229 ], [ -74.00660775, 40.70904038 ], [ -74.00680125, 40.70882077 ], [ -74.00682667, 40.70883439 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0069801, 40.7089161 ], [ -74.00676873, 40.70912427 ], [ -74.00674582, 40.70911228 ], [ -74.0069545, 40.70890248 ], [ -74.0069801, 40.7089161 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00692899, 40.70888886 ], [ -74.00672282, 40.70910016 ], [ -74.00670737, 40.70909206 ], [ -74.00669992, 40.70908818 ], [ -74.00690338, 40.70887518 ], [ -74.00692899, 40.70888886 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00690338, 40.70887518 ], [ -74.00669992, 40.70908818 ], [ -74.00667683, 40.70907619 ], [ -74.00687778, 40.70886156 ], [ -74.00690338, 40.70887518 ] ] ] } }, { "type": "Feature", "properties": { "height": 58.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0069545, 40.70890248 ], [ -74.00674582, 40.70911228 ], [ -74.00672282, 40.70910016 ], [ -74.00692899, 40.70888886 ], [ -74.0069545, 40.70890248 ] ] ] } }, { "type": "Feature", "properties": { "height": 108.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00902413, 40.70662888 ], [ -74.00901496, 40.70662432 ], [ -74.00904964, 40.70658741 ], [ -74.00906895, 40.70659647 ], [ -74.00909393, 40.7065678 ], [ -74.00909905, 40.70656201 ], [ -74.00910749, 40.70656637 ], [ -74.0091701, 40.70649589 ], [ -74.00916364, 40.70649262 ], [ -74.0091728, 40.70648227 ], [ -74.00920235, 40.70645101 ], [ -74.00917828, 40.70643718 ], [ -74.00913067, 40.70640988 ], [ -74.00910327, 40.70639408 ], [ -74.00907084, 40.70643017 ], [ -74.00906788, 40.70643351 ], [ -74.00898191, 40.70638611 ], [ -74.00901263, 40.70634988 ], [ -74.00904793, 40.70636868 ], [ -74.00907892, 40.70638516 ], [ -74.00909474, 40.70639367 ], [ -74.0091021, 40.70638679 ], [ -74.00921232, 40.7064491 ], [ -74.00917522, 40.7064901 ], [ -74.00918259, 40.70649377 ], [ -74.00911019, 40.70657508 ], [ -74.00910192, 40.70657086 ], [ -74.00907228, 40.706606 ], [ -74.00905368, 40.70659708 ], [ -74.00902413, 40.70662888 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01207463, 40.7094247 ], [ -74.01196719, 40.70956586 ], [ -74.0119309, 40.70954986 ], [ -74.01202899, 40.70940462 ], [ -74.01207463, 40.7094247 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01164595, 40.70755432 ], [ -74.01162942, 40.70757359 ], [ -74.01158693, 40.70757972 ], [ -74.01149449, 40.70754009 ], [ -74.0114158, 40.70749746 ], [ -74.01140305, 40.70747247 ], [ -74.01142164, 40.70744931 ], [ -74.01142865, 40.70746607 ], [ -74.01148839, 40.70750066 ], [ -74.01155333, 40.70753192 ], [ -74.01162035, 40.70755718 ], [ -74.01164595, 40.70755432 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0084705, 40.71082077 ], [ -74.00845882, 40.7108337 ], [ -74.00807425, 40.7106408 ], [ -74.00808844, 40.7106265 ], [ -74.0084705, 40.71082077 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0074784, 40.70926979 ], [ -74.00722669, 40.70952378 ], [ -74.00720809, 40.70951309 ], [ -74.00745809, 40.70925842 ], [ -74.0074784, 40.70926979 ] ] ] } }, { "type": "Feature", "properties": { "height": 6.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01051039, 40.71117376 ], [ -74.01048263, 40.71120856 ], [ -74.01045478, 40.71124356 ], [ -74.01037394, 40.71120658 ], [ -74.01042963, 40.71113679 ], [ -74.01051039, 40.71117376 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01058827, 40.71070228 ], [ -74.01055827, 40.71074049 ], [ -74.0105368, 40.71076779 ], [ -74.01050814, 40.71080429 ], [ -74.01047086, 40.7107874 ], [ -74.01055234, 40.71068281 ], [ -74.01056734, 40.71068962 ], [ -74.01057615, 40.71067832 ], [ -74.0106128, 40.71063181 ], [ -74.01062178, 40.71062037 ], [ -74.01062834, 40.71061186 ], [ -74.01065098, 40.71062262 ], [ -74.01058827, 40.71070228 ] ] ] } }, { "type": "Feature", "properties": { "height": 64.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00686404, 40.70941592 ], [ -74.0067345, 40.70954836 ], [ -74.00670647, 40.70953182 ], [ -74.00679819, 40.7094403 ], [ -74.00676424, 40.70942001 ], [ -74.00680439, 40.7093818 ], [ -74.00681813, 40.7093895 ], [ -74.0068626, 40.70941517 ], [ -74.00686404, 40.70941592 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00914306, 40.71181097 ], [ -74.0090491, 40.71192401 ], [ -74.0089855, 40.71189459 ], [ -74.00903787, 40.71183188 ], [ -74.00914306, 40.71181097 ] ] ] } }, { "type": "Feature", "properties": { "height": 63.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01153519, 40.70686232 ], [ -74.01151785, 40.70685612 ], [ -74.01167425, 40.70659367 ], [ -74.01159214, 40.70655867 ], [ -74.01159834, 40.70655036 ], [ -74.01160373, 40.70654328 ], [ -74.01170147, 40.70658509 ], [ -74.01153519, 40.70686232 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01300259, 40.70646068 ], [ -74.01294815, 40.70653211 ], [ -74.01288949, 40.7065059 ], [ -74.01297267, 40.70640627 ], [ -74.01302433, 40.70642997 ], [ -74.01300259, 40.70646068 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00884545, 40.70940421 ], [ -74.00881311, 40.7094386 ], [ -74.00866884, 40.70935797 ], [ -74.00866202, 40.70935416 ], [ -74.00869157, 40.70932358 ], [ -74.00869894, 40.70932746 ], [ -74.00884545, 40.70940421 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00627843, 40.7082109 ], [ -74.00625336, 40.70823658 ], [ -74.00606355, 40.70811836 ], [ -74.00608619, 40.70809487 ], [ -74.00627843, 40.7082109 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00754011, 40.70930458 ], [ -74.00729047, 40.70956001 ], [ -74.00727071, 40.70954891 ], [ -74.00752214, 40.70929437 ], [ -74.00754011, 40.70930458 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01324181, 40.7061302 ], [ -74.01320749, 40.70617092 ], [ -74.01310464, 40.70629282 ], [ -74.01307158, 40.7063317 ], [ -74.01304481, 40.70631992 ], [ -74.01307858, 40.70628022 ], [ -74.01318153, 40.70615826 ], [ -74.01321513, 40.70611849 ], [ -74.01324181, 40.7061302 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0064854, 40.70857488 ], [ -74.00641057, 40.7086442 ], [ -74.00638784, 40.70866531 ], [ -74.00634508, 40.70863868 ], [ -74.00636781, 40.70861771 ], [ -74.00639718, 40.70859047 ], [ -74.00638362, 40.70858209 ], [ -74.00642907, 40.70854001 ], [ -74.00644399, 40.7085492 ], [ -74.0064854, 40.70857488 ] ] ] } }, { "type": "Feature", "properties": { "height": 96.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01130594, 40.70858931 ], [ -74.01127099, 40.70863412 ], [ -74.01124907, 40.70863827 ], [ -74.01118988, 40.70861192 ], [ -74.01118458, 40.70859551 ], [ -74.01121952, 40.70855057 ], [ -74.01124081, 40.70854641 ], [ -74.01130001, 40.70857277 ], [ -74.01130594, 40.70858931 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00721762, 40.70961237 ], [ -74.00717189, 40.70965909 ], [ -74.00715384, 40.70964901 ], [ -74.00714413, 40.70965888 ], [ -74.00712024, 40.70964547 ], [ -74.00710245, 40.70966372 ], [ -74.00712105, 40.7096742 ], [ -74.0070844, 40.70971172 ], [ -74.00704478, 40.70968939 ], [ -74.00713272, 40.7095995 ], [ -74.00715815, 40.7096138 ], [ -74.00717998, 40.7095914 ], [ -74.00721762, 40.70961237 ] ] ] } }, { "type": "Feature", "properties": { "height": 84.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00906338, 40.70668629 ], [ -74.00903113, 40.7066694 ], [ -74.00898487, 40.70664509 ], [ -74.00900733, 40.7066205 ], [ -74.00901496, 40.70662432 ], [ -74.00902413, 40.70662888 ], [ -74.00905368, 40.70664366 ], [ -74.00907578, 40.7066188 ], [ -74.00908728, 40.70662459 ], [ -74.00913408, 40.70657032 ], [ -74.00916849, 40.70658782 ], [ -74.00909815, 40.70666735 ], [ -74.0090862, 40.70666129 ], [ -74.00906338, 40.70668629 ] ] ] } }, { "type": "Feature", "properties": { "height": 84.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00921825, 40.7095741 ], [ -74.00914459, 40.70965228 ], [ -74.00908414, 40.70961959 ], [ -74.00910758, 40.70959467 ], [ -74.00915771, 40.70954142 ], [ -74.00921825, 40.7095741 ] ] ] } }, { "type": "Feature", "properties": { "height": 180.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00567934, 40.71068451 ], [ -74.00550525, 40.71079251 ], [ -74.00547893, 40.7107682 ], [ -74.00565302, 40.7106602 ], [ -74.00567934, 40.71068451 ] ] ] } }, { "type": "Feature", "properties": { "height": 39.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00420008, 40.7081172 ], [ -74.00415445, 40.70806177 ], [ -74.0042088, 40.7080361 ], [ -74.00419739, 40.70802221 ], [ -74.0042344, 40.70800471 ], [ -74.00427159, 40.70804986 ], [ -74.00425183, 40.70805932 ], [ -74.00427168, 40.70808336 ], [ -74.00420008, 40.7081172 ] ] ] } }, { "type": "Feature", "properties": { "height": 51.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0078203, 40.71051298 ], [ -74.00775849, 40.71057577 ], [ -74.00771232, 40.71062282 ], [ -74.00768142, 40.71060532 ], [ -74.00767055, 40.71059906 ], [ -74.00777816, 40.7104899 ], [ -74.0078203, 40.71051298 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01151785, 40.70685612 ], [ -74.01150042, 40.70684999 ], [ -74.01164694, 40.70660219 ], [ -74.01158055, 40.7065742 ], [ -74.01158864, 40.7065633 ], [ -74.01159214, 40.70655867 ], [ -74.01167425, 40.70659367 ], [ -74.01151785, 40.70685612 ] ] ] } }, { "type": "Feature", "properties": { "height": 104.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01116921, 40.7071661 ], [ -74.01113481, 40.7072186 ], [ -74.01100249, 40.70713042 ], [ -74.01101614, 40.70710869 ], [ -74.01116921, 40.7071661 ] ] ] } }, { "type": "Feature", "properties": { "height": 123.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00999045, 40.70695309 ], [ -74.00961567, 40.70673967 ], [ -74.00962744, 40.70672796 ], [ -74.01000212, 40.70694077 ], [ -74.00999045, 40.70695309 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01313509, 40.70803168 ], [ -74.0131217, 40.70805176 ], [ -74.01300402, 40.7082235 ], [ -74.01298911, 40.70818782 ], [ -74.01310365, 40.70802221 ], [ -74.01313509, 40.70803168 ] ] ] } }, { "type": "Feature", "properties": { "height": 32.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01393037, 40.70974087 ], [ -74.01391707, 40.70977369 ], [ -74.01386955, 40.70989401 ], [ -74.01385832, 40.70992179 ], [ -74.01382347, 40.70991376 ], [ -74.0138347, 40.70988591 ], [ -74.01388168, 40.70976552 ], [ -74.0138947, 40.70973222 ], [ -74.01393037, 40.70974087 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00634023, 40.71081811 ], [ -74.00638874, 40.71078447 ], [ -74.00648711, 40.71086387 ], [ -74.00644183, 40.71089587 ], [ -74.00634023, 40.71081811 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01439075, 40.70878039 ], [ -74.01436767, 40.7088367 ], [ -74.0143285, 40.70882792 ], [ -74.01425735, 40.70881198 ], [ -74.01427972, 40.70875438 ], [ -74.01432724, 40.70876548 ], [ -74.01435554, 40.70877208 ], [ -74.01439075, 40.70878039 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00788875, 40.71000126 ], [ -74.00786, 40.7100302 ], [ -74.00770971, 40.70994386 ], [ -74.00773837, 40.70991492 ], [ -74.00774609, 40.70991927 ], [ -74.00788875, 40.71000126 ] ] ] } }, { "type": "Feature", "properties": { "height": 139.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00966265, 40.70777897 ], [ -74.00972625, 40.70770829 ], [ -74.00970209, 40.7076948 ], [ -74.0097232, 40.70767226 ], [ -74.00973613, 40.70767989 ], [ -74.00974449, 40.70768506 ], [ -74.00978734, 40.70771067 ], [ -74.00970083, 40.70780628 ], [ -74.00965879, 40.70778251 ], [ -74.00966265, 40.70777897 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00916328, 40.70911092 ], [ -74.00910552, 40.70916696 ], [ -74.00907093, 40.70912822 ], [ -74.00913444, 40.7090715 ], [ -74.00914306, 40.70906366 ], [ -74.00916462, 40.70907361 ], [ -74.00919939, 40.70903479 ], [ -74.00922625, 40.70904998 ], [ -74.00916328, 40.70911092 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0080287, 40.70673852 ], [ -74.00779927, 40.70659449 ], [ -74.00781733, 40.7065774 ], [ -74.0080314, 40.70670951 ], [ -74.00804883, 40.70671911 ], [ -74.0080287, 40.70673852 ] ] ] } }, { "type": "Feature", "properties": { "height": 118.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0065737, 40.7087029 ], [ -74.00654514, 40.70873422 ], [ -74.00648935, 40.70879619 ], [ -74.00642961, 40.70876629 ], [ -74.0065251, 40.70868601 ], [ -74.00654352, 40.70869867 ], [ -74.00655547, 40.70868907 ], [ -74.0065737, 40.7087029 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00633637, 40.71061819 ], [ -74.00626738, 40.7106602 ], [ -74.00620432, 40.71060062 ], [ -74.0062734, 40.71055861 ], [ -74.00633637, 40.71061819 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00699358, 40.70809882 ], [ -74.00698253, 40.70811046 ], [ -74.00690051, 40.70806082 ], [ -74.00675094, 40.70819388 ], [ -74.00683134, 40.70824359 ], [ -74.00681957, 40.7082553 ], [ -74.00672552, 40.70819756 ], [ -74.00678148, 40.70814642 ], [ -74.00684913, 40.70808411 ], [ -74.00689764, 40.70804012 ], [ -74.00699358, 40.70809882 ] ] ] } }, { "type": "Feature", "properties": { "height": 42.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01434108, 40.70807246 ], [ -74.01431503, 40.70813961 ], [ -74.01430559, 40.70814451 ], [ -74.01421675, 40.70811645 ], [ -74.01422412, 40.70810297 ], [ -74.01415557, 40.70808139 ], [ -74.01416384, 40.70806627 ], [ -74.01428484, 40.70810631 ], [ -74.01431601, 40.70802616 ], [ -74.01433452, 40.70802936 ], [ -74.01431961, 40.7080677 ], [ -74.01434108, 40.70807246 ] ] ] } }, { "type": "Feature", "properties": { "height": 87.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01137655, 40.70786491 ], [ -74.01138427, 40.70785667 ], [ -74.01139721, 40.70786239 ], [ -74.01148354, 40.70775956 ], [ -74.01124279, 40.7076169 ], [ -74.01123201, 40.70762296 ], [ -74.01121808, 40.70761506 ], [ -74.01124252, 40.70759981 ], [ -74.01150644, 40.70775636 ], [ -74.01139981, 40.70787737 ], [ -74.01137655, 40.70786491 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01032147, 40.70645162 ], [ -74.01024763, 40.70651638 ], [ -74.01023452, 40.70650767 ], [ -74.01018798, 40.70647709 ], [ -74.01026093, 40.70641206 ], [ -74.01032147, 40.70645162 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00779388, 40.71089887 ], [ -74.00772705, 40.7109639 ], [ -74.00765572, 40.71092127 ], [ -74.00773693, 40.71086489 ], [ -74.00779388, 40.71089887 ] ] ] } }, { "type": "Feature", "properties": { "height": 82.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00569308, 40.70942218 ], [ -74.0056258, 40.70949831 ], [ -74.0055649, 40.7094674 ], [ -74.00563218, 40.70939141 ], [ -74.00569308, 40.70942218 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00492835, 40.70781091 ], [ -74.00465535, 40.7079106 ], [ -74.00464286, 40.70789242 ], [ -74.00470817, 40.70786831 ], [ -74.00491649, 40.70778857 ], [ -74.00492835, 40.70781091 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01358487, 40.70626837 ], [ -74.0136324, 40.70619489 ], [ -74.01370507, 40.70622281 ], [ -74.01365665, 40.70629636 ], [ -74.01358487, 40.70626837 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0079148, 40.71322428 ], [ -74.00788749, 40.7132618 ], [ -74.00775472, 40.71320161 ], [ -74.00776523, 40.71318819 ], [ -74.00778346, 40.71316491 ], [ -74.0079148, 40.71322428 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01473768, 40.70926591 ], [ -74.0147234, 40.70930186 ], [ -74.01471549, 40.70930772 ], [ -74.0147101, 40.7093086 ], [ -74.01452802, 40.70923036 ], [ -74.01453278, 40.70921817 ], [ -74.01473768, 40.70926591 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00675939, 40.71064999 ], [ -74.0066762, 40.7107174 ], [ -74.00662464, 40.71068077 ], [ -74.00670782, 40.71061335 ], [ -74.00675939, 40.71064999 ] ] ] } }, { "type": "Feature", "properties": { "height": 64.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0100907, 40.70689262 ], [ -74.01006536, 40.70691809 ], [ -74.01004416, 40.7069057 ], [ -74.00993628, 40.70684209 ], [ -74.00991624, 40.70683018 ], [ -74.0099467, 40.70680171 ], [ -74.0100907, 40.70689262 ] ] ] } }, { "type": "Feature", "properties": { "height": 76.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01150042, 40.70684999 ], [ -74.011483, 40.7068438 ], [ -74.01161963, 40.7066107 ], [ -74.01156879, 40.70658959 ], [ -74.01158055, 40.7065742 ], [ -74.01164694, 40.70660219 ], [ -74.01150042, 40.70684999 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00881752, 40.71003721 ], [ -74.00875239, 40.71011212 ], [ -74.00869337, 40.7100827 ], [ -74.0087585, 40.7100078 ], [ -74.00881752, 40.71003721 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00752214, 40.70929437 ], [ -74.00727071, 40.70954891 ], [ -74.00725454, 40.70953978 ], [ -74.00750678, 40.70928579 ], [ -74.00752214, 40.70929437 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01264272, 40.71388796 ], [ -74.01261362, 40.71392446 ], [ -74.01249612, 40.71387216 ], [ -74.01250851, 40.71382886 ], [ -74.01264272, 40.71388796 ] ] ] } }, { "type": "Feature", "properties": { "height": 69.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01257409, 40.7064888 ], [ -74.01254355, 40.7065251 ], [ -74.01242192, 40.70646769 ], [ -74.01245048, 40.70643078 ], [ -74.01257409, 40.7064888 ] ] ] } }, { "type": "Feature", "properties": { "height": 73.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0073662, 40.70666858 ], [ -74.00735901, 40.70667607 ], [ -74.00716264, 40.70654662 ], [ -74.00700292, 40.70671162 ], [ -74.00717099, 40.70682548 ], [ -74.00716381, 40.70683317 ], [ -74.00699052, 40.70671209 ], [ -74.00716111, 40.70653538 ], [ -74.0073662, 40.70666858 ] ] ] } }, { "type": "Feature", "properties": { "height": 11.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00979812, 40.7092832 ], [ -74.00974278, 40.7093449 ], [ -74.00968529, 40.709315 ], [ -74.00975051, 40.70924221 ], [ -74.00980809, 40.7092721 ], [ -74.00979812, 40.7092832 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00812761, 40.70661792 ], [ -74.00810973, 40.70663487 ], [ -74.00788929, 40.70650658 ], [ -74.0079068, 40.70648867 ], [ -74.00812761, 40.70661792 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00709527, 40.70910752 ], [ -74.00681813, 40.7093895 ], [ -74.00680439, 40.7093818 ], [ -74.00708125, 40.70909948 ], [ -74.00709527, 40.70910752 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00925203, 40.70953808 ], [ -74.00921825, 40.7095741 ], [ -74.00915771, 40.70954142 ], [ -74.00910758, 40.70959467 ], [ -74.00908647, 40.7095833 ], [ -74.00917055, 40.70949396 ], [ -74.00925203, 40.70953808 ] ] ] } }, { "type": "Feature", "properties": { "height": 59.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00707604, 40.70963396 ], [ -74.00701981, 40.70960168 ], [ -74.00708889, 40.7095327 ], [ -74.00714512, 40.70956498 ], [ -74.00707604, 40.70963396 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01045811, 40.71023462 ], [ -74.01022338, 40.71053369 ], [ -74.01020847, 40.71052701 ], [ -74.01029524, 40.71041636 ], [ -74.0104432, 40.71022788 ], [ -74.01045811, 40.71023462 ] ] ] } }, { "type": "Feature", "properties": { "height": 147.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00914459, 40.70650106 ], [ -74.00910938, 40.70654056 ], [ -74.0090968, 40.70653416 ], [ -74.00908719, 40.70654498 ], [ -74.009035, 40.70651829 ], [ -74.00904362, 40.70650862 ], [ -74.0090297, 40.70650147 ], [ -74.00906491, 40.7064619 ], [ -74.0090774, 40.70646831 ], [ -74.00908674, 40.70645789 ], [ -74.00913893, 40.70648458 ], [ -74.00913058, 40.70649391 ], [ -74.00914459, 40.70650106 ] ] ] } }, { "type": "Feature", "properties": { "height": 204.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00930925, 40.71230709 ], [ -74.00929174, 40.71230716 ], [ -74.00928167, 40.71230226 ], [ -74.00923209, 40.7122787 ], [ -74.00921295, 40.71226971 ], [ -74.00906707, 40.71220148 ], [ -74.00904793, 40.71219249 ], [ -74.00899727, 40.71216968 ], [ -74.00898828, 40.71216512 ], [ -74.00898164, 40.71215028 ], [ -74.00899978, 40.71215096 ], [ -74.00900904, 40.71215552 ], [ -74.00905898, 40.71217908 ], [ -74.00907803, 40.71218786 ], [ -74.00922409, 40.71225609 ], [ -74.00924305, 40.71226501 ], [ -74.00929317, 40.71228857 ], [ -74.00930332, 40.7122932 ], [ -74.00930925, 40.71230709 ] ] ] } }, { "type": "Feature", "properties": { "height": 63.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00406435, 40.70813566 ], [ -74.00398808, 40.70817168 ], [ -74.003942, 40.70811571 ], [ -74.00401818, 40.70807961 ], [ -74.00406435, 40.70813566 ] ] ] } }, { "type": "Feature", "properties": { "height": 69.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00627268, 40.7066393 ], [ -74.0062098, 40.70668731 ], [ -74.00614745, 40.70664039 ], [ -74.00621024, 40.70659231 ], [ -74.00627268, 40.7066393 ] ] ] } }, { "type": "Feature", "properties": { "height": 104.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0112436, 40.7071471 ], [ -74.01115233, 40.70728636 ], [ -74.01113481, 40.7072186 ], [ -74.01116921, 40.7071661 ], [ -74.0112436, 40.7071471 ] ] ] } }, { "type": "Feature", "properties": { "height": 140.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00565302, 40.7106602 ], [ -74.00547893, 40.7107682 ], [ -74.0054571, 40.71074798 ], [ -74.00563119, 40.71063998 ], [ -74.00565302, 40.7106602 ] ] ] } }, { "type": "Feature", "properties": { "height": 57.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0064854, 40.70857488 ], [ -74.00641057, 40.7086442 ], [ -74.00636781, 40.70861771 ], [ -74.00639718, 40.70859047 ], [ -74.00638362, 40.70858209 ], [ -74.00642907, 40.70854001 ], [ -74.00644399, 40.7085492 ], [ -74.0064854, 40.70857488 ] ] ] } }, { "type": "Feature", "properties": { "height": 64.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0092885, 40.70637957 ], [ -74.00925598, 40.70640988 ], [ -74.0091392, 40.70634171 ], [ -74.00917262, 40.70631039 ], [ -74.0092885, 40.70637957 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00903113, 40.7066694 ], [ -74.00899107, 40.70671516 ], [ -74.0089033, 40.70666749 ], [ -74.00890914, 40.70666116 ], [ -74.00894355, 40.7066233 ], [ -74.00898487, 40.70664509 ], [ -74.00903113, 40.7066694 ] ] ] } }, { "type": "Feature", "properties": { "height": 83.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.011483, 40.7068438 ], [ -74.01146557, 40.7068376 ], [ -74.01159232, 40.70661928 ], [ -74.0115572, 40.70660511 ], [ -74.01156879, 40.70658959 ], [ -74.01161963, 40.7066107 ], [ -74.011483, 40.7068438 ] ] ] } }, { "type": "Feature", "properties": { "height": 87.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00721851, 40.70668717 ], [ -74.00716758, 40.7067411 ], [ -74.00709742, 40.7067029 ], [ -74.00714827, 40.7066491 ], [ -74.00721851, 40.70668717 ] ] ] } }, { "type": "Feature", "properties": { "height": 103.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01119697, 40.70780376 ], [ -74.01113768, 40.70786361 ], [ -74.01107525, 40.70782718 ], [ -74.01113041, 40.70777019 ], [ -74.01117981, 40.70779511 ], [ -74.01119697, 40.70780376 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00921861, 40.70914456 ], [ -74.00914827, 40.70921511 ], [ -74.00910552, 40.70916696 ], [ -74.00916328, 40.70911092 ], [ -74.00921861, 40.70914456 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00653274, 40.71094449 ], [ -74.0064748, 40.71098467 ], [ -74.00642728, 40.71094551 ], [ -74.00640985, 40.71093108 ], [ -74.0064677, 40.71089077 ], [ -74.00653274, 40.71094449 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00684544, 40.71036876 ], [ -74.00682038, 40.71038939 ], [ -74.00665177, 40.71030428 ], [ -74.00667809, 40.71028296 ], [ -74.00684544, 40.71036876 ] ] ] } }, { "type": "Feature", "properties": { "height": 134.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01258945, 40.70617882 ], [ -74.01257005, 40.70620381 ], [ -74.01240072, 40.70612802 ], [ -74.01242021, 40.7061031 ], [ -74.01258945, 40.70617882 ] ] ] } }, { "type": "Feature", "properties": { "height": 135.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01342695, 40.70641689 ], [ -74.0134027, 40.70644869 ], [ -74.01333065, 40.70641716 ], [ -74.01335473, 40.70638536 ], [ -74.01337557, 40.70635792 ], [ -74.0134477, 40.70638938 ], [ -74.01342695, 40.70641689 ] ] ] } }, { "type": "Feature", "properties": { "height": 34.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00671654, 40.70842289 ], [ -74.0067036, 40.70843446 ], [ -74.00664072, 40.70839381 ], [ -74.00656238, 40.70834321 ], [ -74.0065128, 40.70831107 ], [ -74.00642674, 40.70838468 ], [ -74.00641389, 40.70837549 ], [ -74.00651109, 40.70829139 ], [ -74.00657478, 40.70833218 ], [ -74.00665338, 40.70838251 ], [ -74.00671654, 40.70842289 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0094299, 40.71139145 ], [ -74.009383, 40.7114462 ], [ -74.00931078, 40.71141066 ], [ -74.00935767, 40.71135598 ], [ -74.00940762, 40.71138056 ], [ -74.0094299, 40.71139145 ] ] ] } }, { "type": "Feature", "properties": { "height": 64.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00638703, 40.71023932 ], [ -74.0063732, 40.71025042 ], [ -74.00613461, 40.71012642 ], [ -74.00606571, 40.71019676 ], [ -74.00605052, 40.71018947 ], [ -74.00612679, 40.71010939 ], [ -74.00638703, 40.71023932 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00872265, 40.70573659 ], [ -74.00857147, 40.7056657 ], [ -74.00864675, 40.70564902 ], [ -74.00870972, 40.70567769 ], [ -74.00872265, 40.70573659 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0094696, 40.70712197 ], [ -74.00944122, 40.70715296 ], [ -74.0093194, 40.70707982 ], [ -74.00934393, 40.70705156 ], [ -74.0094696, 40.70712197 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00649708, 40.70937159 ], [ -74.00645063, 40.70942361 ], [ -74.00637697, 40.70938569 ], [ -74.00642359, 40.7093338 ], [ -74.00649708, 40.70937159 ] ] ] } }, { "type": "Feature", "properties": { "height": 42.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00889495, 40.70994821 ], [ -74.00887914, 40.7099664 ], [ -74.00882695, 40.70992888 ], [ -74.00872571, 40.70985622 ], [ -74.00867513, 40.70981986 ], [ -74.00868852, 40.70980447 ], [ -74.00874008, 40.70984042 ], [ -74.0088433, 40.70991226 ], [ -74.00889495, 40.70994821 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00782272, 40.7131152 ], [ -74.00780745, 40.71313461 ], [ -74.0075976, 40.71303962 ], [ -74.00761287, 40.71302021 ], [ -74.00782272, 40.7131152 ] ] ] } }, { "type": "Feature", "properties": { "height": 128.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01163194, 40.70749269 ], [ -74.01160768, 40.70752102 ], [ -74.01155729, 40.70750011 ], [ -74.01152297, 40.70748336 ], [ -74.01147608, 40.70745817 ], [ -74.01149908, 40.70742936 ], [ -74.01152108, 40.70743999 ], [ -74.01160669, 40.70748078 ], [ -74.01163194, 40.70749269 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01396118, 40.7100398 ], [ -74.01394294, 40.71008828 ], [ -74.01381394, 40.71003422 ], [ -74.01382392, 40.71000902 ], [ -74.01396118, 40.7100398 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00793869, 40.71319398 ], [ -74.0079148, 40.71322428 ], [ -74.00778346, 40.71316491 ], [ -74.00780745, 40.71313461 ], [ -74.00793869, 40.71319398 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00415337, 40.70589989 ], [ -74.00410837, 40.70586278 ], [ -74.00410918, 40.70584146 ], [ -74.00412139, 40.70583302 ], [ -74.00411304, 40.705826 ], [ -74.00414403, 40.70580428 ], [ -74.00421086, 40.70585958 ], [ -74.00415337, 40.70589989 ] ] ] } }, { "type": "Feature", "properties": { "height": 115.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01178214, 40.70712742 ], [ -74.01173605, 40.70713859 ], [ -74.01166383, 40.70722528 ], [ -74.01163328, 40.70721091 ], [ -74.01164532, 40.70719579 ], [ -74.01172204, 40.70709916 ], [ -74.0117559, 40.70711509 ], [ -74.01178214, 40.70712742 ] ] ] } }, { "type": "Feature", "properties": { "height": 258.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00773693, 40.70643998 ], [ -74.00769534, 40.70648097 ], [ -74.00761359, 40.70643351 ], [ -74.00765527, 40.70639238 ], [ -74.00773693, 40.70643998 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0080287, 40.70673852 ], [ -74.00801262, 40.70675418 ], [ -74.0077752, 40.70659912 ], [ -74.00779505, 40.70659858 ], [ -74.00779927, 40.70659449 ], [ -74.0080287, 40.70673852 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00491649, 40.70778857 ], [ -74.00470817, 40.70786831 ], [ -74.00469461, 40.7078472 ], [ -74.00475506, 40.70782439 ], [ -74.00490625, 40.70776787 ], [ -74.00491649, 40.70778857 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00686215, 40.7096518 ], [ -74.0068396, 40.70967482 ], [ -74.00668788, 40.7095961 ], [ -74.00671025, 40.70957322 ], [ -74.00686215, 40.7096518 ] ] ] } }, { "type": "Feature", "properties": { "height": 125.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.006685, 40.7087605 ], [ -74.00667081, 40.7087763 ], [ -74.00665671, 40.7087919 ], [ -74.00654514, 40.70873422 ], [ -74.0065737, 40.7087029 ], [ -74.00662931, 40.7087317 ], [ -74.006685, 40.7087605 ] ] ] } }, { "type": "Feature", "properties": { "height": 69.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01220623, 40.70631917 ], [ -74.01217793, 40.70635622 ], [ -74.01208172, 40.70631277 ], [ -74.01210373, 40.70627082 ], [ -74.01220623, 40.70631917 ] ] ] } }, { "type": "Feature", "properties": { "height": 155.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00969167, 40.70770597 ], [ -74.00965142, 40.70775071 ], [ -74.00957417, 40.70771081 ], [ -74.0096145, 40.70766607 ], [ -74.00969167, 40.70770597 ] ] ] } }, { "type": "Feature", "properties": { "height": 88.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00549393, 40.70798305 ], [ -74.00548773, 40.70797127 ], [ -74.00569524, 40.70788016 ], [ -74.00562158, 40.70780621 ], [ -74.0056355, 40.70779817 ], [ -74.00571249, 40.70787539 ], [ -74.00572021, 40.707885 ], [ -74.00549393, 40.70798305 ] ] ] } }, { "type": "Feature", "properties": { "height": 66.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0125519, 40.71367136 ], [ -74.01250851, 40.71382886 ], [ -74.01248165, 40.7138166 ], [ -74.01252298, 40.71365638 ], [ -74.0125519, 40.71367136 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0134716, 40.70666606 ], [ -74.01341761, 40.70673777 ], [ -74.01336488, 40.70671461 ], [ -74.01339407, 40.7066758 ], [ -74.01341869, 40.70664318 ], [ -74.0134716, 40.70666606 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01303043, 40.70651659 ], [ -74.01300088, 40.7065552 ], [ -74.01294815, 40.70653211 ], [ -74.01300259, 40.70646068 ], [ -74.01305541, 40.70648376 ], [ -74.01303043, 40.70651659 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00606472, 40.71273416 ], [ -74.00603561, 40.71276467 ], [ -74.00601369, 40.71276657 ], [ -74.00597093, 40.71274342 ], [ -74.00596617, 40.7127247 ], [ -74.00599088, 40.71269549 ], [ -74.00601333, 40.7126929 ], [ -74.00606005, 40.71271598 ], [ -74.00606472, 40.71273416 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00814405, 40.70660191 ], [ -74.00812761, 40.70661792 ], [ -74.0079068, 40.70648867 ], [ -74.00791067, 40.70648472 ], [ -74.00790626, 40.70647001 ], [ -74.00814405, 40.70660191 ] ] ] } }, { "type": "Feature", "properties": { "height": 115.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01193233, 40.70719688 ], [ -74.01185391, 40.70728649 ], [ -74.01183567, 40.70730726 ], [ -74.01180792, 40.70729412 ], [ -74.01188104, 40.7072075 ], [ -74.01187493, 40.70717107 ], [ -74.01193233, 40.70719688 ] ] ] } }, { "type": "Feature", "properties": { "height": 95.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00694543, 40.70815282 ], [ -74.00688713, 40.70820661 ], [ -74.00683233, 40.70817236 ], [ -74.00689063, 40.7081187 ], [ -74.00694543, 40.70815282 ] ] ] } }, { "type": "Feature", "properties": { "height": 106.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00566515, 40.70841267 ], [ -74.00570413, 40.70844686 ], [ -74.00572569, 40.70846585 ], [ -74.00567305, 40.70850038 ], [ -74.00561242, 40.7084472 ], [ -74.00566515, 40.70841267 ] ] ] } }, { "type": "Feature", "properties": { "height": 52.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00572533, 40.70774846 ], [ -74.00569488, 40.7077659 ], [ -74.00559355, 40.70766627 ], [ -74.00562454, 40.70764802 ], [ -74.00572533, 40.70774846 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00852107, 40.71113958 ], [ -74.00850769, 40.71115449 ], [ -74.00828742, 40.71104078 ], [ -74.0083008, 40.71102586 ], [ -74.00852107, 40.71113958 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00942567, 40.7113922 ], [ -74.0093822, 40.71144286 ], [ -74.00931527, 40.71140991 ], [ -74.00935884, 40.71135918 ], [ -74.00942567, 40.7113922 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01442192, 40.70786409 ], [ -74.01434108, 40.70807246 ], [ -74.01431961, 40.7080677 ], [ -74.01433452, 40.70802936 ], [ -74.014385, 40.7078993 ], [ -74.01440054, 40.70785926 ], [ -74.01442192, 40.70786409 ] ] ] } }, { "type": "Feature", "properties": { "height": 6.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01045478, 40.71124356 ], [ -74.01048263, 40.71120856 ], [ -74.01051039, 40.71117376 ], [ -74.01056088, 40.71119691 ], [ -74.01050527, 40.71126671 ], [ -74.01045478, 40.71124356 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00834473, 40.70794989 ], [ -74.00833189, 40.70803787 ], [ -74.00822418, 40.70802289 ], [ -74.00834473, 40.70794989 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00682613, 40.70855486 ], [ -74.00680529, 40.70857317 ], [ -74.00665419, 40.70847886 ], [ -74.00667494, 40.7084602 ], [ -74.00682613, 40.70855486 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00684679, 40.70853647 ], [ -74.00682613, 40.70855486 ], [ -74.00667494, 40.7084602 ], [ -74.0066921, 40.70844488 ], [ -74.00669569, 40.70844161 ], [ -74.00684679, 40.70853647 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00686754, 40.70851822 ], [ -74.00684679, 40.70853647 ], [ -74.00669569, 40.70844161 ], [ -74.0067036, 40.70843446 ], [ -74.00671654, 40.70842289 ], [ -74.00686754, 40.70851822 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00680529, 40.70857317 ], [ -74.00678463, 40.70859149 ], [ -74.00663344, 40.70849759 ], [ -74.00665419, 40.70847886 ], [ -74.00680529, 40.70857317 ] ] ] } }, { "type": "Feature", "properties": { "height": 95.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00676379, 40.70860981 ], [ -74.00674313, 40.70862819 ], [ -74.00659248, 40.70853531 ], [ -74.00661305, 40.70851638 ], [ -74.00676379, 40.70860981 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00678463, 40.70859149 ], [ -74.00676379, 40.70860981 ], [ -74.00661305, 40.70851638 ], [ -74.00663039, 40.70850031 ], [ -74.00663344, 40.70849759 ], [ -74.00678463, 40.70859149 ] ] ] } }, { "type": "Feature", "properties": { "height": 238.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00781257, 40.7065443 ], [ -74.00778158, 40.70652619 ], [ -74.00776415, 40.70654342 ], [ -74.00774358, 40.70653136 ], [ -74.00776128, 40.7065142 ], [ -74.00775669, 40.70649868 ], [ -74.00777502, 40.70648097 ], [ -74.00779478, 40.70648131 ], [ -74.00781194, 40.70646429 ], [ -74.0078326, 40.70647627 ], [ -74.00781517, 40.7064935 ], [ -74.00784599, 40.70651141 ], [ -74.00785201, 40.70651502 ], [ -74.00781859, 40.70654778 ], [ -74.00781257, 40.7065443 ] ] ] } }, { "type": "Feature", "properties": { "height": 238.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00760434, 40.70634192 ], [ -74.00758682, 40.70635908 ], [ -74.00759131, 40.7063746 ], [ -74.00757308, 40.70639231 ], [ -74.0075535, 40.70639176 ], [ -74.00753598, 40.70640899 ], [ -74.00751532, 40.7063968 ], [ -74.00753274, 40.70637978 ], [ -74.00750202, 40.7063618 ], [ -74.00749591, 40.70635819 ], [ -74.00752942, 40.70632537 ], [ -74.00753544, 40.70632891 ], [ -74.00756634, 40.70634709 ], [ -74.00758377, 40.70632986 ], [ -74.00760434, 40.70634192 ] ] ] } }, { "type": "Feature", "properties": { "height": 65.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01435563, 40.70783781 ], [ -74.01426553, 40.70800498 ], [ -74.01423795, 40.70799558 ], [ -74.0143126, 40.70787097 ], [ -74.01433524, 40.70783052 ], [ -74.01435563, 40.70783781 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0138894, 40.70787676 ], [ -74.01384763, 40.7079471 ], [ -74.01379283, 40.70792912 ], [ -74.01383398, 40.70785789 ], [ -74.01385284, 40.70786429 ], [ -74.0138894, 40.70787676 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01429751, 40.70738891 ], [ -74.01426984, 40.70743658 ], [ -74.01418773, 40.70740907 ], [ -74.0142154, 40.70736147 ], [ -74.01429751, 40.70738891 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0078123, 40.70935429 ], [ -74.00779568, 40.70937111 ], [ -74.00773738, 40.70942988 ], [ -74.00771169, 40.70941517 ], [ -74.00773765, 40.70938909 ], [ -74.00771699, 40.70937731 ], [ -74.00776622, 40.70932767 ], [ -74.00778625, 40.70933911 ], [ -74.0078123, 40.70935429 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00578507, 40.71107258 ], [ -74.00597273, 40.7109562 ], [ -74.00598863, 40.71097091 ], [ -74.00580097, 40.71108728 ], [ -74.00578507, 40.71107258 ] ] ] } }, { "type": "Feature", "properties": { "height": 66.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01262422, 40.713364 ], [ -74.01257912, 40.71354111 ], [ -74.01255541, 40.71353089 ], [ -74.01260122, 40.71335359 ], [ -74.01262422, 40.713364 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01391707, 40.70977369 ], [ -74.01386955, 40.70989401 ], [ -74.0138347, 40.70988591 ], [ -74.01388168, 40.70976552 ], [ -74.01391707, 40.70977369 ] ] ] } }, { "type": "Feature", "properties": { "height": 87.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0136235, 40.70608451 ], [ -74.01361784, 40.70609397 ], [ -74.01350268, 40.70605441 ], [ -74.01347537, 40.70609336 ], [ -74.01341464, 40.70606796 ], [ -74.01344168, 40.70602921 ], [ -74.01346908, 40.70603868 ], [ -74.01348866, 40.70604617 ], [ -74.01349423, 40.70603997 ], [ -74.0136235, 40.70608451 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01468495, 40.70939447 ], [ -74.01466788, 40.70943825 ], [ -74.01465099, 40.70948218 ], [ -74.01463402, 40.70952596 ], [ -74.01461704, 40.70956988 ], [ -74.01459997, 40.70961367 ], [ -74.01458308, 40.70965759 ], [ -74.0145661, 40.70970137 ], [ -74.01455389, 40.70969606 ], [ -74.01456979, 40.70965439 ], [ -74.01458695, 40.70961026 ], [ -74.01460338, 40.70956668 ], [ -74.01461991, 40.70952358 ], [ -74.01463698, 40.70947911 ], [ -74.01465423, 40.70943587 ], [ -74.01466941, 40.70939427 ], [ -74.01468495, 40.70939447 ] ] ] } }, { "type": "Feature", "properties": { "height": 103.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00547291, 40.70785476 ], [ -74.00542152, 40.70779947 ], [ -74.00545557, 40.70778129 ], [ -74.00547147, 40.70779851 ], [ -74.00550201, 40.70778217 ], [ -74.00553741, 40.70782037 ], [ -74.00547291, 40.70785476 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00601324, 40.71063371 ], [ -74.00598252, 40.71065278 ], [ -74.00588685, 40.71056446 ], [ -74.00591748, 40.7105454 ], [ -74.00601324, 40.71063371 ] ] ] } }, { "type": "Feature", "properties": { "height": 6.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.010247, 40.7112887 ], [ -74.0101932, 40.7113553 ], [ -74.0101437, 40.71133242 ], [ -74.0101976, 40.71126569 ], [ -74.010247, 40.7112887 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01488671, 40.70866517 ], [ -74.01486767, 40.708714 ], [ -74.01478305, 40.70869506 ], [ -74.01480191, 40.70864631 ], [ -74.01485644, 40.70865829 ], [ -74.01488671, 40.70866517 ] ] ] } }, { "type": "Feature", "properties": { "height": 140.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00597273, 40.7109562 ], [ -74.00578507, 40.71107258 ], [ -74.00576971, 40.71105828 ], [ -74.00595728, 40.71094191 ], [ -74.00597273, 40.7109562 ] ] ] } }, { "type": "Feature", "properties": { "height": 86.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01195982, 40.70790577 ], [ -74.0119423, 40.70792728 ], [ -74.01190799, 40.70793382 ], [ -74.01187745, 40.70791959 ], [ -74.01186972, 40.70789337 ], [ -74.01188724, 40.70787192 ], [ -74.01192146, 40.70786538 ], [ -74.0119521, 40.70787962 ], [ -74.01195982, 40.70790577 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00490625, 40.70776787 ], [ -74.00475506, 40.70782439 ], [ -74.00473898, 40.70779967 ], [ -74.0048926, 40.70774492 ], [ -74.00490625, 40.70776787 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00609391, 40.70744428 ], [ -74.00607954, 40.7074564 ], [ -74.00594327, 40.70735691 ], [ -74.00587032, 40.7073821 ], [ -74.00586278, 40.70736937 ], [ -74.00594632, 40.7073375 ], [ -74.00609391, 40.70744428 ] ] ] } }, { "type": "Feature", "properties": { "height": 39.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00595, 40.70894096 ], [ -74.00591407, 40.70891672 ], [ -74.00590518, 40.70891059 ], [ -74.00597013, 40.70885557 ], [ -74.00601495, 40.70888587 ], [ -74.00595, 40.70894096 ] ] ] } }, { "type": "Feature", "properties": { "height": 145.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0141138, 40.70786402 ], [ -74.0140811, 40.70791857 ], [ -74.01401571, 40.7078961 ], [ -74.01404849, 40.70784148 ], [ -74.0141138, 40.70786402 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01246827, 40.70799838 ], [ -74.01245399, 40.70801826 ], [ -74.01229642, 40.7079441 ], [ -74.01231043, 40.70792402 ], [ -74.01246827, 40.70799838 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00700984, 40.70808329 ], [ -74.00699358, 40.70809882 ], [ -74.00689764, 40.70804012 ], [ -74.00684913, 40.70808411 ], [ -74.00683152, 40.70807308 ], [ -74.00689512, 40.70801438 ], [ -74.00694614, 40.70804448 ], [ -74.00700984, 40.70808329 ] ] ] } }, { "type": "Feature", "properties": { "height": 39.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01085705, 40.70714601 ], [ -74.01083298, 40.70713777 ], [ -74.01093179, 40.70699306 ], [ -74.01095452, 40.70700212 ], [ -74.01085705, 40.70714601 ] ] ] } }, { "type": "Feature", "properties": { "height": 180.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00551297, 40.71110778 ], [ -74.00549348, 40.7111199 ], [ -74.0053555, 40.71099209 ], [ -74.00537499, 40.71097997 ], [ -74.00551297, 40.71110778 ] ] ] } }, { "type": "Feature", "properties": { "height": 88.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00554064, 40.70770291 ], [ -74.005526, 40.70771128 ], [ -74.0054191, 40.70760519 ], [ -74.00532307, 40.70764189 ], [ -74.00531723, 40.70762861 ], [ -74.00542691, 40.7075881 ], [ -74.00546069, 40.70762276 ], [ -74.00554064, 40.70770291 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00681957, 40.7082553 ], [ -74.00680412, 40.70827219 ], [ -74.00669453, 40.70819946 ], [ -74.00676388, 40.70813552 ], [ -74.00678148, 40.70814642 ], [ -74.00672552, 40.70819756 ], [ -74.00681957, 40.7082553 ] ] ] } }, { "type": "Feature", "properties": { "height": 86.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00899107, 40.70671516 ], [ -74.00896143, 40.70674648 ], [ -74.00887357, 40.70669882 ], [ -74.0089033, 40.70666749 ], [ -74.00899107, 40.70671516 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01080243, 40.71038987 ], [ -74.01079354, 40.71040131 ], [ -74.01078429, 40.71041289 ], [ -74.01075779, 40.71044687 ], [ -74.01074889, 40.71045831 ], [ -74.01071215, 40.71050481 ], [ -74.01070317, 40.71051612 ], [ -74.01066679, 40.71056256 ], [ -74.01065789, 40.710574 ], [ -74.01062834, 40.71061186 ], [ -74.01062178, 40.71062037 ], [ -74.0106128, 40.71063181 ], [ -74.01057615, 40.71067832 ], [ -74.01056734, 40.71068962 ], [ -74.01055234, 40.71068281 ], [ -74.01060408, 40.71062786 ], [ -74.01061298, 40.71061649 ], [ -74.01064909, 40.71056998 ], [ -74.01065798, 40.71055868 ], [ -74.01069437, 40.71051217 ], [ -74.01070335, 40.7105008 ], [ -74.01074018, 40.71045436 ], [ -74.01074907, 40.71044298 ], [ -74.01078698, 40.71038286 ], [ -74.01080243, 40.71038987 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01184735, 40.70737727 ], [ -74.01186182, 40.70732109 ], [ -74.01195883, 40.70720968 ], [ -74.01197725, 40.70721847 ], [ -74.01184735, 40.70737727 ] ] ] } }, { "type": "Feature", "properties": { "height": 51.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01014037, 40.71061451 ], [ -74.01012699, 40.71063147 ], [ -74.00995478, 40.71055316 ], [ -74.00996817, 40.7105362 ], [ -74.01014037, 40.71061451 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00982255, 40.70912189 ], [ -74.00976793, 40.70918276 ], [ -74.00969194, 40.7091434 ], [ -74.00971592, 40.70911657 ], [ -74.00977224, 40.70914558 ], [ -74.00980333, 40.70911167 ], [ -74.00982255, 40.70912189 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00606472, 40.71273416 ], [ -74.00605322, 40.71273491 ], [ -74.00603426, 40.71275547 ], [ -74.00603561, 40.71276467 ], [ -74.00601369, 40.71276657 ], [ -74.00601208, 40.71275752 ], [ -74.00598243, 40.71274152 ], [ -74.00597093, 40.71274342 ], [ -74.00596617, 40.7127247 ], [ -74.00597704, 40.71272368 ], [ -74.0059933, 40.71270447 ], [ -74.00599088, 40.71269549 ], [ -74.00601333, 40.7126929 ], [ -74.00601531, 40.71270039 ], [ -74.00604765, 40.7127168 ], [ -74.00606005, 40.71271598 ], [ -74.00606472, 40.71273416 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00615105, 40.71270209 ], [ -74.00597938, 40.71261521 ], [ -74.00599555, 40.71260091 ], [ -74.00616174, 40.71268411 ], [ -74.00615105, 40.71270209 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01213068, 40.707866 ], [ -74.01206439, 40.70783481 ], [ -74.01206744, 40.70783106 ], [ -74.01209529, 40.70779708 ], [ -74.01209834, 40.70779341 ], [ -74.01210391, 40.70779606 ], [ -74.01216464, 40.70782466 ], [ -74.01213068, 40.707866 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0119715, 40.70806 ], [ -74.01194123, 40.70809712 ], [ -74.0119379, 40.70810107 ], [ -74.01193233, 40.70809848 ], [ -74.01187709, 40.70807246 ], [ -74.01187152, 40.70806988 ], [ -74.01187475, 40.708066 ], [ -74.01190529, 40.70802882 ], [ -74.0119715, 40.70806 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00426593, 40.7091178 ], [ -74.00423575, 40.70914558 ], [ -74.0042459, 40.70915198 ], [ -74.00423081, 40.70916581 ], [ -74.00416954, 40.7091274 ], [ -74.00421482, 40.7090858 ], [ -74.00426593, 40.7091178 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0086639, 40.70562579 ], [ -74.00864675, 40.70564902 ], [ -74.00857147, 40.7056657 ], [ -74.00864207, 40.70556866 ], [ -74.0086639, 40.70562579 ] ] ] } }, { "type": "Feature", "properties": { "height": 156.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00913022, 40.70650317 ], [ -74.00910659, 40.70652966 ], [ -74.0090844, 40.70653409 ], [ -74.00904937, 40.70651618 ], [ -74.00904407, 40.70649929 ], [ -74.0090677, 40.7064728 ], [ -74.00908953, 40.70646892 ], [ -74.00912438, 40.70648669 ], [ -74.00913022, 40.70650317 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00468212, 40.70805878 ], [ -74.00466469, 40.70806538 ], [ -74.0045675, 40.70794581 ], [ -74.0046028, 40.70793117 ], [ -74.00462014, 40.7079567 ], [ -74.00462202, 40.70797298 ], [ -74.00462984, 40.70799279 ], [ -74.00464242, 40.70800948 ], [ -74.00465257, 40.70801942 ], [ -74.004662, 40.70802752 ], [ -74.00468212, 40.70805878 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01401508, 40.70999942 ], [ -74.0139742, 40.71010136 ], [ -74.01394294, 40.71008828 ], [ -74.01396118, 40.7100398 ], [ -74.01397959, 40.70999118 ], [ -74.01401508, 40.70999942 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0066294, 40.71054696 ], [ -74.00664171, 40.71053682 ], [ -74.00668465, 40.71050141 ], [ -74.00670971, 40.71048071 ], [ -74.0067407, 40.71050141 ], [ -74.0066621, 40.71056746 ], [ -74.0066294, 40.71054696 ] ] ] } }, { "type": "Feature", "properties": { "height": 57.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01346908, 40.70598992 ], [ -74.01345615, 40.70600858 ], [ -74.01335509, 40.70597378 ], [ -74.01331763, 40.70602751 ], [ -74.01329858, 40.70601961 ], [ -74.01335652, 40.7059511 ], [ -74.01346908, 40.70598992 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00727412, 40.70666211 ], [ -74.00725085, 40.70668676 ], [ -74.00715168, 40.7066329 ], [ -74.00717504, 40.70660831 ], [ -74.00727412, 40.70666211 ] ] ] } }, { "type": "Feature", "properties": { "height": 42.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01444762, 40.70779776 ], [ -74.01442192, 40.70786409 ], [ -74.01440054, 40.70785926 ], [ -74.014385, 40.7078993 ], [ -74.01436704, 40.70789541 ], [ -74.01441025, 40.70778462 ], [ -74.01444762, 40.70779776 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0061682, 40.70652741 ], [ -74.00608915, 40.70658782 ], [ -74.00605942, 40.70656541 ], [ -74.00607613, 40.70655261 ], [ -74.00613838, 40.70650501 ], [ -74.0061682, 40.70652741 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01426562, 40.70831468 ], [ -74.01423588, 40.70838829 ], [ -74.0141916, 40.70837706 ], [ -74.01422259, 40.70830488 ], [ -74.01426562, 40.70831468 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00795396, 40.71317451 ], [ -74.00793869, 40.71319398 ], [ -74.00780745, 40.71313461 ], [ -74.00782272, 40.7131152 ], [ -74.00793007, 40.71316382 ], [ -74.00795396, 40.71317451 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00940968, 40.71140678 ], [ -74.00939298, 40.71142632 ], [ -74.00936297, 40.71143122 ], [ -74.00933728, 40.71141856 ], [ -74.00933081, 40.71139588 ], [ -74.00934743, 40.71137641 ], [ -74.00937744, 40.7113715 ], [ -74.00940322, 40.7113841 ], [ -74.00940968, 40.71140678 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00876793, 40.70556512 ], [ -74.00872301, 40.70565079 ], [ -74.00870046, 40.70559406 ], [ -74.00872229, 40.70555041 ], [ -74.00876793, 40.70556512 ] ] ] } }, { "type": "Feature", "properties": { "height": 88.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00997437, 40.70928988 ], [ -74.00993628, 40.70933366 ], [ -74.00988103, 40.70930581 ], [ -74.00992235, 40.70926291 ], [ -74.00997437, 40.70928988 ] ] ] } }, { "type": "Feature", "properties": { "height": 104.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01101614, 40.70710869 ], [ -74.01100249, 40.70713042 ], [ -74.0109344, 40.70714097 ], [ -74.01099018, 40.7070521 ], [ -74.01101614, 40.70710869 ] ] ] } }, { "type": "Feature", "properties": { "height": 120.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01160768, 40.70752102 ], [ -74.01155333, 40.70753192 ], [ -74.01148839, 40.70750066 ], [ -74.01147608, 40.70745817 ], [ -74.01152297, 40.70748336 ], [ -74.01155729, 40.70750011 ], [ -74.01160768, 40.70752102 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00923784, 40.70897759 ], [ -74.00918672, 40.70902778 ], [ -74.009141, 40.70900252 ], [ -74.00918502, 40.70895819 ], [ -74.00923784, 40.70897759 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00593168, 40.70898808 ], [ -74.00587508, 40.7089494 ], [ -74.00591407, 40.70891672 ], [ -74.00595, 40.70894096 ], [ -74.00597057, 40.70895526 ], [ -74.00593168, 40.70898808 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01170704, 40.70709221 ], [ -74.0116164, 40.70720546 ], [ -74.0115978, 40.70719647 ], [ -74.01168305, 40.70708091 ], [ -74.0116888, 40.7070837 ], [ -74.01170704, 40.70709221 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00781904, 40.71044687 ], [ -74.00777816, 40.7104899 ], [ -74.00772759, 40.71046226 ], [ -74.00776837, 40.71041929 ], [ -74.00781904, 40.71044687 ] ] ] } }, { "type": "Feature", "properties": { "height": 41.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00664072, 40.70839381 ], [ -74.00663021, 40.70840341 ], [ -74.00651531, 40.70832701 ], [ -74.00643815, 40.70839286 ], [ -74.00642674, 40.70838468 ], [ -74.0065128, 40.70831107 ], [ -74.00656238, 40.70834321 ], [ -74.00664072, 40.70839381 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01062699, 40.71076691 ], [ -74.01055827, 40.71074049 ], [ -74.01058827, 40.71070228 ], [ -74.01065403, 40.71072986 ], [ -74.01062699, 40.71076691 ] ] ] } }, { "type": "Feature", "properties": { "height": 117.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01466788, 40.70943825 ], [ -74.01465099, 40.70948218 ], [ -74.01463402, 40.70952596 ], [ -74.01461704, 40.70956988 ], [ -74.01459997, 40.70961367 ], [ -74.01458308, 40.70965759 ], [ -74.01456979, 40.70965439 ], [ -74.01458695, 40.70961026 ], [ -74.01460338, 40.70956668 ], [ -74.01461991, 40.70952358 ], [ -74.01463698, 40.70947911 ], [ -74.01465423, 40.70943587 ], [ -74.01466788, 40.70943825 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00761907, 40.70659 ], [ -74.00760578, 40.706603 ], [ -74.00747364, 40.7065347 ], [ -74.00749232, 40.7065157 ], [ -74.00761907, 40.70659 ] ] ] } }, { "type": "Feature", "properties": { "height": 108.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0097267, 40.70714622 ], [ -74.00969229, 40.70718292 ], [ -74.0096339, 40.70715119 ], [ -74.0096693, 40.7071138 ], [ -74.0097267, 40.70714622 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00463774, 40.70959746 ], [ -74.00457369, 40.70965398 ], [ -74.00454073, 40.7096326 ], [ -74.00460469, 40.70957608 ], [ -74.00463774, 40.70959746 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00607954, 40.7074564 ], [ -74.00606768, 40.70746641 ], [ -74.00593895, 40.7073708 ], [ -74.00587931, 40.70739252 ], [ -74.00587032, 40.7073821 ], [ -74.00594327, 40.70735691 ], [ -74.00607954, 40.7074564 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01336811, 40.71371596 ], [ -74.01326364, 40.7136649 ], [ -74.01328169, 40.71364188 ], [ -74.01337467, 40.71368566 ], [ -74.01336811, 40.71371596 ] ] ] } }, { "type": "Feature", "properties": { "height": 66.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01338662, 40.71372488 ], [ -74.01334853, 40.71388701 ], [ -74.01333083, 40.71387829 ], [ -74.01336811, 40.71371596 ], [ -74.01338662, 40.71372488 ] ] ] } }, { "type": "Feature", "properties": { "height": 61.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00707092, 40.70809071 ], [ -74.0070561, 40.70811148 ], [ -74.00700984, 40.70808329 ], [ -74.00694614, 40.70804448 ], [ -74.00696591, 40.70802582 ], [ -74.00707092, 40.70809071 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01078429, 40.71041289 ], [ -74.01079354, 40.71040131 ], [ -74.01080243, 40.71038987 ], [ -74.01081375, 40.71037475 ], [ -74.01087879, 40.71040172 ], [ -74.01085184, 40.71043869 ], [ -74.01078429, 40.71041289 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01407751, 40.7081678 ], [ -74.01405963, 40.70820369 ], [ -74.01398274, 40.7081804 ], [ -74.01399954, 40.7081441 ], [ -74.01407751, 40.7081678 ] ] ] } }, { "type": "Feature", "properties": { "height": 111.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01322932, 40.70640089 ], [ -74.01322348, 40.7063983 ], [ -74.01315611, 40.70636881 ], [ -74.01319033, 40.7063238 ], [ -74.01321028, 40.70633177 ], [ -74.01321971, 40.7063665 ], [ -74.01324657, 40.70637821 ], [ -74.01322932, 40.70640089 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01128267, 40.70859626 ], [ -74.01126794, 40.70861526 ], [ -74.01123901, 40.7086205 ], [ -74.01121332, 40.70860899 ], [ -74.01120658, 40.70858747 ], [ -74.01122195, 40.70856786 ], [ -74.01125051, 40.70856276 ], [ -74.01127584, 40.70857406 ], [ -74.01128267, 40.70859626 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00528552, 40.70971302 ], [ -74.00523809, 40.70975197 ], [ -74.00519398, 40.70972119 ], [ -74.00524141, 40.70968217 ], [ -74.00528552, 40.70971302 ] ] ] } }, { "type": "Feature", "properties": { "height": 7.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.009383, 40.7114462 ], [ -74.0094299, 40.71139145 ], [ -74.00946969, 40.71141107 ], [ -74.0094228, 40.71146581 ], [ -74.009383, 40.7114462 ] ] ] } }, { "type": "Feature", "properties": { "height": 116.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0083883, 40.70940319 ], [ -74.00839117, 40.70939747 ], [ -74.00839567, 40.70939236 ], [ -74.0084016, 40.7093882 ], [ -74.00840851, 40.70938507 ], [ -74.00841624, 40.70938317 ], [ -74.00842423, 40.70938269 ], [ -74.00843223, 40.70938351 ], [ -74.00843977, 40.70938562 ], [ -74.00844651, 40.70938902 ], [ -74.00845208, 40.70939338 ], [ -74.00845702, 40.70939978 ], [ -74.00845855, 40.70940346 ], [ -74.00845963, 40.70941081 ], [ -74.0084581, 40.70941796 ], [ -74.00845424, 40.7094247 ], [ -74.00844804, 40.70943029 ], [ -74.00844418, 40.70943267 ], [ -74.00843555, 40.70943608 ], [ -74.00842585, 40.70943757 ], [ -74.00841543, 40.70943696 ], [ -74.00840573, 40.70943417 ], [ -74.00840133, 40.70943199 ], [ -74.00839414, 40.70942641 ], [ -74.0083892, 40.70941926 ], [ -74.00838722, 40.70941129 ], [ -74.0083883, 40.70940319 ] ] ] } }, { "type": "Feature", "properties": { "height": 116.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00822867, 40.7092892 ], [ -74.00822184, 40.70929171 ], [ -74.00821322, 40.70929321 ], [ -74.00820441, 40.70929301 ], [ -74.00819561, 40.7092911 ], [ -74.00818842, 40.70928811 ], [ -74.00818232, 40.70928388 ], [ -74.00817774, 40.70927871 ], [ -74.00817468, 40.70927292 ], [ -74.00817342, 40.70926679 ], [ -74.00817414, 40.70926046 ], [ -74.00817765, 40.70925297 ], [ -74.00818232, 40.70924779 ], [ -74.00818842, 40.7092435 ], [ -74.0081957, 40.70924051 ], [ -74.0082037, 40.70923867 ], [ -74.00821205, 40.7092384 ], [ -74.00822014, 40.70923949 ], [ -74.00822777, 40.70924201 ], [ -74.00823442, 40.70924582 ], [ -74.00823981, 40.70925059 ], [ -74.00824358, 40.70925617 ], [ -74.00824565, 40.7092623 ], [ -74.00824574, 40.70926856 ], [ -74.00824403, 40.70927469 ], [ -74.00824044, 40.70928041 ], [ -74.00823523, 40.70928531 ], [ -74.00822867, 40.7092892 ] ] ] } }, { "type": "Feature", "properties": { "height": 116.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00852691, 40.70931916 ], [ -74.00851963, 40.70931616 ], [ -74.00851344, 40.70931201 ], [ -74.00850867, 40.7093069 ], [ -74.00850562, 40.70930098 ], [ -74.00850427, 40.70929478 ], [ -74.0085049, 40.70928851 ], [ -74.00850751, 40.70928252 ], [ -74.00851173, 40.70927707 ], [ -74.00851748, 40.70927258 ], [ -74.00852439, 40.70926918 ], [ -74.0085323, 40.709267 ], [ -74.00854047, 40.70926632 ], [ -74.00854883, 40.709267 ], [ -74.00855664, 40.70926918 ], [ -74.00856365, 40.70927258 ], [ -74.00856931, 40.70927707 ], [ -74.00857299, 40.70928157 ], [ -74.00857587, 40.7092879 ], [ -74.00857677, 40.7092943 ], [ -74.00857551, 40.70930077 ], [ -74.00857228, 40.7093069 ], [ -74.00856698, 40.70931248 ], [ -74.00856069, 40.70931657 ], [ -74.0085526, 40.7093197 ], [ -74.00854425, 40.70932106 ], [ -74.0085358, 40.709321 ], [ -74.00852691, 40.70931916 ] ] ] } }, { "type": "Feature", "properties": { "height": 116.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00864091, 40.70920612 ], [ -74.00863372, 40.70920299 ], [ -74.00862761, 40.70919877 ], [ -74.00862294, 40.70919359 ], [ -74.00861989, 40.7091878 ], [ -74.00861872, 40.70918161 ], [ -74.00861944, 40.70917541 ], [ -74.00862195, 40.70916942 ], [ -74.00862608, 40.7091641 ], [ -74.00863183, 40.70915961 ], [ -74.00863875, 40.70915607 ], [ -74.00864648, 40.70915396 ], [ -74.00865474, 40.70915321 ], [ -74.00866292, 40.70915389 ], [ -74.00867073, 40.70915587 ], [ -74.00867765, 40.70915927 ], [ -74.00868349, 40.7091637 ], [ -74.00868717, 40.70916812 ], [ -74.00869022, 40.70917432 ], [ -74.0086913, 40.70918099 ], [ -74.00869013, 40.7091876 ], [ -74.00868681, 40.70919386 ], [ -74.00868178, 40.70919917 ], [ -74.00867513, 40.7092036 ], [ -74.00866714, 40.7092066 ], [ -74.00865851, 40.70920809 ], [ -74.00864971, 40.70920789 ], [ -74.00864091, 40.70920612 ] ] ] } }, { "type": "Feature", "properties": { "height": 116.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00854631, 40.70886598 ], [ -74.00854155, 40.70887116 ], [ -74.00853508, 40.70887552 ], [ -74.00852763, 40.70887858 ], [ -74.00851927, 40.70888022 ], [ -74.00851083, 40.70888028 ], [ -74.00850248, 40.70887899 ], [ -74.00849484, 40.7088762 ], [ -74.00848819, 40.70887211 ], [ -74.00848307, 40.70886687 ], [ -74.00847957, 40.70886101 ], [ -74.00847813, 40.70885468 ], [ -74.00847858, 40.70884821 ], [ -74.00848101, 40.70884201 ], [ -74.00848532, 40.70883636 ], [ -74.00849107, 40.7088318 ], [ -74.00849798, 40.7088284 ], [ -74.00850328, 40.70882669 ], [ -74.00851379, 40.7088254 ], [ -74.00852224, 40.70882608 ], [ -74.00853014, 40.70882819 ], [ -74.00853419, 40.70882989 ], [ -74.0085385, 40.70883241 ], [ -74.0085429, 40.70883602 ], [ -74.00854703, 40.70884099 ], [ -74.00854955, 40.7088461 ], [ -74.00855063, 40.70885332 ], [ -74.00854937, 40.70885986 ], [ -74.00854631, 40.70886598 ] ] ] } }, { "type": "Feature", "properties": { "height": 116.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00869481, 40.7089526 ], [ -74.00869139, 40.70895607 ], [ -74.00868474, 40.7089605 ], [ -74.00867675, 40.7089635 ], [ -74.00866813, 40.70896499 ], [ -74.00865932, 40.70896479 ], [ -74.00865052, 40.70896288 ], [ -74.00864333, 40.70895989 ], [ -74.00863722, 40.70895567 ], [ -74.00863255, 40.70895049 ], [ -74.0086295, 40.7089447 ], [ -74.00862833, 40.70893851 ], [ -74.00862905, 40.70893231 ], [ -74.00863147, 40.70892632 ], [ -74.0086357, 40.70892087 ], [ -74.00864145, 40.70891637 ], [ -74.00864558, 40.70891386 ], [ -74.00865609, 40.70891086 ], [ -74.00866435, 40.70891011 ], [ -74.00867253, 40.70891079 ], [ -74.00868034, 40.70891277 ], [ -74.00868717, 40.7089161 ], [ -74.0086931, 40.7089206 ], [ -74.00869678, 40.70892489 ], [ -74.00869993, 40.70893122 ], [ -74.00870118, 40.70893762 ], [ -74.00869975, 40.7089445 ], [ -74.00869651, 40.70895069 ], [ -74.00869481, 40.7089526 ] ] ] } }, { "type": "Feature", "properties": { "height": 116.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00876299, 40.70908491 ], [ -74.00875409, 40.709083 ], [ -74.00874682, 40.70908001 ], [ -74.00874044, 40.70907551 ], [ -74.0087355, 40.70907 ], [ -74.00873253, 40.7090638 ], [ -74.00873164, 40.7090572 ], [ -74.0087328, 40.70905066 ], [ -74.00873604, 40.70904446 ], [ -74.00874107, 40.70903908 ], [ -74.00874772, 40.70903479 ], [ -74.00875553, 40.7090318 ], [ -74.00876011, 40.70903091 ], [ -74.00876398, 40.7090303 ], [ -74.00877278, 40.70903037 ], [ -74.00878122, 40.70903207 ], [ -74.00878895, 40.7090352 ], [ -74.00879542, 40.7090397 ], [ -74.00879667, 40.70904072 ], [ -74.00880018, 40.70904521 ], [ -74.00880323, 40.70905141 ], [ -74.00880413, 40.70905801 ], [ -74.00880287, 40.70906462 ], [ -74.00879973, 40.70907081 ], [ -74.00879461, 40.70907606 ], [ -74.00878805, 40.70908048 ], [ -74.00878024, 40.70908348 ], [ -74.0087717, 40.70908498 ], [ -74.00876299, 40.70908491 ] ] ] } }, { "type": "Feature", "properties": { "height": 238.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00763578, 40.70652687 ], [ -74.00761584, 40.70654662 ], [ -74.00754847, 40.70650712 ], [ -74.0075685, 40.70648751 ], [ -74.00758718, 40.70648349 ], [ -74.00763587, 40.70651236 ], [ -74.00763578, 40.70652687 ] ] ] } }, { "type": "Feature", "properties": { "height": 204.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00928311, 40.71221469 ], [ -74.00927754, 40.71222232 ], [ -74.00924305, 40.71226501 ], [ -74.00923209, 40.7122787 ], [ -74.00920487, 40.71231336 ], [ -74.00919867, 40.71232119 ], [ -74.00918061, 40.71232411 ], [ -74.00917801, 40.71231131 ], [ -74.00918457, 40.71230369 ], [ -74.00921295, 40.71226971 ], [ -74.00922409, 40.71225609 ], [ -74.00925931, 40.71221346 ], [ -74.00926577, 40.71220638 ], [ -74.00928069, 40.712204 ], [ -74.00928311, 40.71221469 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01328771, 40.70829752 ], [ -74.01315961, 40.70826327 ], [ -74.01321261, 40.70824529 ], [ -74.01326867, 40.70825912 ], [ -74.01328771, 40.70829752 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01012528, 40.70927932 ], [ -74.01009474, 40.70931316 ], [ -74.01003455, 40.70928198 ], [ -74.01006519, 40.709248 ], [ -74.01007812, 40.70925481 ], [ -74.01011729, 40.7092751 ], [ -74.01012528, 40.70927932 ] ] ] } }, { "type": "Feature", "properties": { "height": 140.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00549348, 40.7111199 ], [ -74.00547973, 40.71112848 ], [ -74.00534175, 40.71100067 ], [ -74.0053555, 40.71099209 ], [ -74.00549348, 40.7111199 ] ] ] } }, { "type": "Feature", "properties": { "height": 238.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00779936, 40.70636636 ], [ -74.0077796, 40.70638577 ], [ -74.00776074, 40.70638999 ], [ -74.00771214, 40.70636098 ], [ -74.00771232, 40.70634641 ], [ -74.00773235, 40.7063268 ], [ -74.00779936, 40.70636636 ] ] ] } }, { "type": "Feature", "properties": { "height": 204.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00920119, 40.71217547 ], [ -74.00919508, 40.7121831 ], [ -74.00912267, 40.71227386 ], [ -74.00911638, 40.71228169 ], [ -74.00909869, 40.71228489 ], [ -74.00909653, 40.71227216 ], [ -74.00910291, 40.71226426 ], [ -74.00917738, 40.71217458 ], [ -74.00918412, 40.71216716 ], [ -74.00919858, 40.71216492 ], [ -74.00920119, 40.71217547 ] ] ] } }, { "type": "Feature", "properties": { "height": 204.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00911962, 40.71213632 ], [ -74.00911342, 40.71214401 ], [ -74.00907803, 40.71218786 ], [ -74.00906707, 40.71220148 ], [ -74.00904102, 40.71223457 ], [ -74.00903491, 40.71224247 ], [ -74.00901667, 40.71224567 ], [ -74.00901479, 40.71223301 ], [ -74.00902134, 40.71222531 ], [ -74.00904793, 40.71219249 ], [ -74.00905898, 40.71217908 ], [ -74.00909563, 40.71213536 ], [ -74.0091021, 40.71212787 ], [ -74.00911612, 40.71212549 ], [ -74.00911962, 40.71213632 ] ] ] } }, { "type": "Feature", "properties": { "height": 111.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01357329, 40.70649166 ], [ -74.01353951, 40.7065364 ], [ -74.01347321, 40.70650726 ], [ -74.01349019, 40.70648499 ], [ -74.01351337, 40.70649507 ], [ -74.0135537, 40.70648267 ], [ -74.01357329, 40.70649166 ] ] ] } }, { "type": "Feature", "properties": { "height": 99.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01300402, 40.7082235 ], [ -74.01287583, 40.70818932 ], [ -74.01293189, 40.7081725 ], [ -74.01298911, 40.70818782 ], [ -74.01300402, 40.7082235 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00976515, 40.70674247 ], [ -74.00965699, 40.7066792 ], [ -74.00967451, 40.70666211 ], [ -74.0097824, 40.70672571 ], [ -74.00976515, 40.70674247 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01004416, 40.7069057 ], [ -74.00993628, 40.70684209 ], [ -74.00995379, 40.706825 ], [ -74.01006159, 40.7068886 ], [ -74.01004416, 40.7069057 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00787105, 40.70634246 ], [ -74.0078556, 40.70635799 ], [ -74.00772912, 40.70628342 ], [ -74.00774232, 40.70627048 ], [ -74.00787105, 40.70634246 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00918502, 40.70895819 ], [ -74.009141, 40.70900252 ], [ -74.00909572, 40.70897746 ], [ -74.00913417, 40.70893946 ], [ -74.00918502, 40.70895819 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01363257, 40.70606939 ], [ -74.0136235, 40.70608451 ], [ -74.01349423, 40.70603997 ], [ -74.01348866, 40.70604617 ], [ -74.01346908, 40.70603868 ], [ -74.01348417, 40.70601831 ], [ -74.01363257, 40.70606939 ] ] ] } }, { "type": "Feature", "properties": { "height": 123.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0117966, 40.7059876 ], [ -74.01179148, 40.70599802 ], [ -74.01178133, 40.70600592 ], [ -74.01176758, 40.70601007 ], [ -74.01175303, 40.7060096 ], [ -74.01173982, 40.70600469 ], [ -74.01173048, 40.70599611 ], [ -74.01172653, 40.70598542 ], [ -74.0117286, 40.70597439 ], [ -74.01173641, 40.70596499 ], [ -74.01174863, 40.70595886 ], [ -74.01176309, 40.70595696 ], [ -74.01177728, 40.70595968 ], [ -74.01178878, 40.70596656 ], [ -74.01179561, 40.7059765 ], [ -74.0117966, 40.7059876 ] ] ] } }, { "type": "Feature", "properties": { "height": 541.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0132207, 40.71299727 ], [ -74.01322061, 40.71300646 ], [ -74.01321585, 40.71301606 ], [ -74.01320911, 40.71302178 ], [ -74.01320237, 40.71302532 ], [ -74.01319078, 40.71302798 ], [ -74.01318297, 40.71302798 ], [ -74.01317434, 40.71302641 ], [ -74.01316707, 40.71302369 ], [ -74.01315719, 40.71301585 ], [ -74.01315323, 40.71300932 ], [ -74.01315189, 40.71300299 ], [ -74.01315359, 40.71299359 ], [ -74.01316078, 40.71298426 ], [ -74.01317255, 40.71297779 ], [ -74.01317902, 40.71297616 ], [ -74.0131906, 40.71297582 ], [ -74.0131995, 40.71297738 ], [ -74.01321028, 40.71298276 ], [ -74.0132154, 40.71298739 ], [ -74.0132207, 40.71299727 ] ] ] } }, { "type": "Feature", "properties": { "height": 117.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0116641, 40.70750808 ], [ -74.01162035, 40.70755718 ], [ -74.01155333, 40.70753192 ], [ -74.01160768, 40.70752102 ], [ -74.01163194, 40.70749269 ], [ -74.01163715, 40.70749521 ], [ -74.0116641, 40.70750808 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01421864, 40.70798898 ], [ -74.01419627, 40.70802786 ], [ -74.01413545, 40.70800777 ], [ -74.01414479, 40.70799157 ], [ -74.01415827, 40.70796848 ], [ -74.01416447, 40.70797059 ], [ -74.01420399, 40.70798408 ], [ -74.01421864, 40.70798898 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00872301, 40.70565079 ], [ -74.0086639, 40.70562579 ], [ -74.00864207, 40.70556866 ], [ -74.00870046, 40.70559406 ], [ -74.00872301, 40.70565079 ] ] ] } }, { "type": "Feature", "properties": { "height": 39.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00980333, 40.70911167 ], [ -74.00977224, 40.70914558 ], [ -74.00971592, 40.70911657 ], [ -74.00974691, 40.70908198 ], [ -74.00980333, 40.70911167 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01421675, 40.70811645 ], [ -74.01404194, 40.7080615 ], [ -74.0140493, 40.70804788 ], [ -74.01415557, 40.70808139 ], [ -74.01422412, 40.70810297 ], [ -74.01421675, 40.70811645 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00995793, 40.70897078 ], [ -74.00994149, 40.7089891 ], [ -74.0099308, 40.70900102 ], [ -74.00986612, 40.70896697 ], [ -74.00989028, 40.70894 ], [ -74.00995793, 40.70897078 ] ] ] } }, { "type": "Feature", "properties": { "height": 45.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0088433, 40.70991226 ], [ -74.00882695, 40.70992888 ], [ -74.00872571, 40.70985622 ], [ -74.00874008, 40.70984042 ], [ -74.0088433, 40.70991226 ] ] ] } }, { "type": "Feature", "properties": { "height": 117.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01149908, 40.70742936 ], [ -74.01147608, 40.70745817 ], [ -74.01148839, 40.70750066 ], [ -74.01142865, 40.70746607 ], [ -74.01146889, 40.70741506 ], [ -74.01149378, 40.70742691 ], [ -74.01149908, 40.70742936 ] ] ] } }, { "type": "Feature", "properties": { "height": 259.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00772031, 40.70644161 ], [ -74.00769309, 40.70646837 ], [ -74.00763021, 40.70643181 ], [ -74.00765743, 40.70640497 ], [ -74.00772031, 40.70644161 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01395875, 40.70762521 ], [ -74.01392902, 40.70769228 ], [ -74.01390333, 40.70768581 ], [ -74.01390827, 40.70767451 ], [ -74.01389273, 40.70767049 ], [ -74.01391168, 40.70762759 ], [ -74.01392731, 40.70763161 ], [ -74.01393423, 40.70761636 ], [ -74.01395875, 40.70762521 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01389174, 40.70777706 ], [ -74.01386138, 40.70784461 ], [ -74.01383568, 40.70783787 ], [ -74.0138408, 40.70782671 ], [ -74.01382517, 40.70782262 ], [ -74.0138444, 40.70777979 ], [ -74.01385967, 40.7077838 ], [ -74.01386569, 40.70777039 ], [ -74.01389174, 40.70777706 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00763228, 40.70657706 ], [ -74.00761907, 40.70659 ], [ -74.00749232, 40.7065157 ], [ -74.00750553, 40.70650269 ], [ -74.00763228, 40.70657706 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0078556, 40.70635799 ], [ -74.00784239, 40.70637086 ], [ -74.00771582, 40.70629636 ], [ -74.00772912, 40.70628342 ], [ -74.0078556, 40.70635799 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00784239, 40.70637086 ], [ -74.00783548, 40.70637767 ], [ -74.0078291, 40.70638386 ], [ -74.00779936, 40.70636636 ], [ -74.00773235, 40.7063268 ], [ -74.00770262, 40.7063093 ], [ -74.00770899, 40.70630296 ], [ -74.00771582, 40.70629636 ], [ -74.00784239, 40.70637086 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00764557, 40.70656412 ], [ -74.00763785, 40.70657168 ], [ -74.00763228, 40.70657706 ], [ -74.00750553, 40.70650269 ], [ -74.00751154, 40.70649691 ], [ -74.00751882, 40.70648969 ], [ -74.00754847, 40.70650712 ], [ -74.00761584, 40.70654662 ], [ -74.00764557, 40.70656412 ] ] ] } }, { "type": "Feature", "properties": { "height": 73.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00691255, 40.70831216 ], [ -74.00689997, 40.70833211 ], [ -74.00680412, 40.70827219 ], [ -74.00681957, 40.7082553 ], [ -74.00691255, 40.70831216 ] ] ] } }, { "type": "Feature", "properties": { "height": 190.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01165583, 40.70747172 ], [ -74.01166868, 40.70747117 ], [ -74.01167524, 40.70745299 ], [ -74.01168359, 40.70745156 ], [ -74.01168754, 40.70744666 ], [ -74.01169985, 40.70744809 ], [ -74.01170488, 40.70744026 ], [ -74.01171719, 40.70743386 ], [ -74.01171925, 40.70741779 ], [ -74.01174423, 40.70740539 ], [ -74.01174809, 40.70738449 ], [ -74.01176695, 40.70737666 ], [ -74.01176974, 40.70736556 ], [ -74.0117771, 40.70735888 ], [ -74.01177037, 40.70735098 ], [ -74.01177477, 40.70734628 ], [ -74.01177333, 40.70733988 ], [ -74.01179265, 40.70732817 ], [ -74.01178797, 40.70731918 ], [ -74.0118019, 40.70732926 ], [ -74.01180037, 40.7073422 ], [ -74.01169464, 40.70747151 ], [ -74.01167452, 40.70747812 ], [ -74.01165583, 40.70747172 ] ] ] } }, { "type": "Feature", "properties": { "height": 220.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0078256, 40.70656957 ], [ -74.00780134, 40.7065554 ], [ -74.00781257, 40.7065443 ], [ -74.00781859, 40.70654778 ], [ -74.00785201, 40.70651502 ], [ -74.00784599, 40.70651141 ], [ -74.00785722, 40.70650038 ], [ -74.00788165, 40.70651448 ], [ -74.00788982, 40.70651931 ], [ -74.00783377, 40.7065744 ], [ -74.0078256, 40.70656957 ] ] ] } }, { "type": "Feature", "properties": { "height": 220.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00754667, 40.70631788 ], [ -74.00753544, 40.70632891 ], [ -74.00752942, 40.70632537 ], [ -74.00749591, 40.70635819 ], [ -74.00750202, 40.7063618 ], [ -74.0074907, 40.70637276 ], [ -74.00746645, 40.7063586 ], [ -74.00745809, 40.7063539 ], [ -74.00751424, 40.70629888 ], [ -74.00752241, 40.70630371 ], [ -74.00754667, 40.70631788 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01413878, 40.70818646 ], [ -74.01412135, 40.70822146 ], [ -74.01410168, 40.70821581 ], [ -74.01405963, 40.70820369 ], [ -74.01407751, 40.7081678 ], [ -74.01413878, 40.70818646 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01304948, 40.70657651 ], [ -74.01300088, 40.7065552 ], [ -74.01303043, 40.70651659 ], [ -74.01307903, 40.7065379 ], [ -74.01304948, 40.70657651 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01339407, 40.7066758 ], [ -74.01336488, 40.70671461 ], [ -74.01331601, 40.70669337 ], [ -74.0133452, 40.70665462 ], [ -74.01339407, 40.7066758 ] ] ] } }, { "type": "Feature", "properties": { "height": 61.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00689997, 40.70833211 ], [ -74.00688704, 40.7083505 ], [ -74.00678777, 40.70828738 ], [ -74.00680412, 40.70827219 ], [ -74.00689997, 40.70833211 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00715617, 40.70674431 ], [ -74.00713228, 40.7067695 ], [ -74.00706742, 40.70673416 ], [ -74.00709122, 40.70670896 ], [ -74.00715617, 40.70674431 ] ] ] } }, { "type": "Feature", "properties": { "height": 190.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01164559, 40.70724891 ], [ -74.01163221, 40.70724938 ], [ -74.01162574, 40.7072675 ], [ -74.01161729, 40.70726899 ], [ -74.01161352, 40.7072739 ], [ -74.01160121, 40.7072724 ], [ -74.011596, 40.70728016 ], [ -74.0115837, 40.70728656 ], [ -74.01158181, 40.70730277 ], [ -74.01155675, 40.7073151 ], [ -74.01155289, 40.70733607 ], [ -74.01153411, 40.70734376 ], [ -74.01153133, 40.70735486 ], [ -74.01152378, 40.70736161 ], [ -74.01153052, 40.70736957 ], [ -74.01152612, 40.7073742 ], [ -74.01152773, 40.70738067 ], [ -74.01150833, 40.70739239 ], [ -74.0115121, 40.70740076 ], [ -74.01149953, 40.70739136 ], [ -74.01150249, 40.70737536 ], [ -74.01160642, 40.70725081 ], [ -74.011627, 40.70724237 ], [ -74.01164559, 40.70724891 ] ] ] } }, { "type": "Feature", "properties": { "height": 130.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00981402, 40.70712851 ], [ -74.00978024, 40.70716276 ], [ -74.0097347, 40.70713777 ], [ -74.00976811, 40.70710236 ], [ -74.00981402, 40.70712851 ] ] ] } }, { "type": "Feature", "properties": { "height": 43.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00647686, 40.70937452 ], [ -74.00644668, 40.70940816 ], [ -74.00639727, 40.70938276 ], [ -74.00642737, 40.70934912 ], [ -74.00647686, 40.70937452 ] ] ] } }, { "type": "Feature", "properties": { "height": 133.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00917828, 40.70643718 ], [ -74.00914819, 40.70646967 ], [ -74.00909914, 40.70644461 ], [ -74.00913067, 40.70640988 ], [ -74.00917828, 40.70643718 ] ] ] } }, { "type": "Feature", "properties": { "height": 260.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00973074, 40.70696106 ], [ -74.00969724, 40.70699497 ], [ -74.00965259, 40.70696957 ], [ -74.00968619, 40.70693566 ], [ -74.00973074, 40.70696106 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00584229, 40.70757345 ], [ -74.00582711, 40.70758299 ], [ -74.0057362, 40.70749317 ], [ -74.00575498, 40.70748336 ], [ -74.00584229, 40.70757345 ] ] ] } }, { "type": "Feature", "properties": { "height": 87.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01376355, 40.70611447 ], [ -74.01375448, 40.70612959 ], [ -74.0136235, 40.70608451 ], [ -74.01363257, 40.70606939 ], [ -74.01376355, 40.70611447 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01247725, 40.71025831 ], [ -74.0124291, 40.71024367 ], [ -74.01246405, 40.7101939 ], [ -74.01249432, 40.71020772 ], [ -74.01247725, 40.71025831 ] ] ] } }, { "type": "Feature", "properties": { "height": 210.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0078256, 40.70656957 ], [ -74.00781733, 40.7065774 ], [ -74.00779927, 40.70659449 ], [ -74.00779505, 40.70659858 ], [ -74.0077752, 40.70659912 ], [ -74.00773001, 40.70656916 ], [ -74.007746, 40.70655431 ], [ -74.00776882, 40.70656766 ], [ -74.00779011, 40.70656637 ], [ -74.00780134, 40.7065554 ], [ -74.0078256, 40.70656957 ] ] ] } }, { "type": "Feature", "properties": { "height": 210.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0079068, 40.70648867 ], [ -74.00788929, 40.70650658 ], [ -74.00788165, 40.70651448 ], [ -74.00785722, 40.70650038 ], [ -74.00786853, 40.70648928 ], [ -74.00786467, 40.70647341 ], [ -74.00784168, 40.70646007 ], [ -74.00785668, 40.70644461 ], [ -74.00790626, 40.70647001 ], [ -74.00791067, 40.70648472 ], [ -74.0079068, 40.70648867 ] ] ] } }, { "type": "Feature", "properties": { "height": 210.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00761799, 40.70630412 ], [ -74.007602, 40.70631897 ], [ -74.00757919, 40.70630562 ], [ -74.00755799, 40.70630678 ], [ -74.00754667, 40.70631788 ], [ -74.00752241, 40.70630371 ], [ -74.00752583, 40.70630072 ], [ -74.00755314, 40.7062747 ], [ -74.0075729, 40.70627416 ], [ -74.00761799, 40.70630412 ] ] ] } }, { "type": "Feature", "properties": { "height": 210.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00750624, 40.70641308 ], [ -74.00749124, 40.7064286 ], [ -74.00744157, 40.70640307 ], [ -74.00743707, 40.70638849 ], [ -74.00746313, 40.70636207 ], [ -74.00746645, 40.7063586 ], [ -74.0074907, 40.70637276 ], [ -74.00747938, 40.70638386 ], [ -74.00748325, 40.7063998 ], [ -74.00750624, 40.70641308 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00674313, 40.70862819 ], [ -74.00673306, 40.70863739 ], [ -74.00658251, 40.70854457 ], [ -74.00659248, 40.70853531 ], [ -74.00674313, 40.70862819 ] ] ] } }, { "type": "Feature", "properties": { "height": 38.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00687895, 40.70956648 ], [ -74.00685497, 40.70959297 ], [ -74.00679577, 40.70956239 ], [ -74.00681975, 40.7095359 ], [ -74.00687895, 40.70956648 ] ] ] } }, { "type": "Feature", "properties": { "height": 80.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00908791, 40.70632632 ], [ -74.00904793, 40.70636868 ], [ -74.00901263, 40.70634988 ], [ -74.00904919, 40.70630671 ], [ -74.00908791, 40.70632632 ] ] ] } }, { "type": "Feature", "properties": { "height": 103.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00544219, 40.70770277 ], [ -74.00539134, 40.70773239 ], [ -74.00536322, 40.70770461 ], [ -74.00541407, 40.70767499 ], [ -74.00544219, 40.70770277 ] ] ] } }, { "type": "Feature", "properties": { "height": 103.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00558699, 40.70784788 ], [ -74.00553615, 40.70787751 ], [ -74.00550803, 40.70784972 ], [ -74.00555897, 40.70782017 ], [ -74.00558699, 40.70784788 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00631104, 40.70670876 ], [ -74.00636053, 40.70667199 ], [ -74.00639063, 40.70669521 ], [ -74.00634113, 40.70673198 ], [ -74.00631104, 40.70670876 ] ] ] } }, { "type": "Feature", "properties": { "height": 43.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00538505, 40.70874477 ], [ -74.00532001, 40.7087746 ], [ -74.00529944, 40.70874879 ], [ -74.00536439, 40.70871897 ], [ -74.00538505, 40.70874477 ] ] ] } }, { "type": "Feature", "properties": { "height": 77.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01300573, 40.70745279 ], [ -74.01296872, 40.70750522 ], [ -74.0129362, 40.70749072 ], [ -74.01297294, 40.70743849 ], [ -74.01300573, 40.70745279 ] ] ] } }, { "type": "Feature", "properties": { "height": 261.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00771672, 40.70644202 ], [ -74.00769264, 40.70646572 ], [ -74.00763389, 40.70643146 ], [ -74.00765788, 40.7064077 ], [ -74.00771672, 40.70644202 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01172204, 40.70709916 ], [ -74.01164532, 40.70719579 ], [ -74.0116164, 40.70720546 ], [ -74.01170704, 40.70709221 ], [ -74.01172204, 40.70709916 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0094016, 40.71140569 ], [ -74.00938839, 40.71142121 ], [ -74.0093645, 40.71142509 ], [ -74.00934402, 40.71141508 ], [ -74.0093389, 40.71139697 ], [ -74.0093521, 40.71138151 ], [ -74.009376, 40.71137756 ], [ -74.00939639, 40.71138757 ], [ -74.0094016, 40.71140569 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00575498, 40.70748336 ], [ -74.0057362, 40.70749317 ], [ -74.00568608, 40.7074438 ], [ -74.00569021, 40.70743529 ], [ -74.00573962, 40.70741636 ], [ -74.00574959, 40.70743168 ], [ -74.00571698, 40.70744516 ], [ -74.00575498, 40.70748336 ] ] ] } }, { "type": "Feature", "properties": { "height": 101.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01120838, 40.70764332 ], [ -74.0111764, 40.70767601 ], [ -74.01113382, 40.70765006 ], [ -74.01116535, 40.70761717 ], [ -74.01120838, 40.70764332 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00587032, 40.7073821 ], [ -74.00574959, 40.70743168 ], [ -74.00573962, 40.70741636 ], [ -74.00586278, 40.70736937 ], [ -74.00587032, 40.7073821 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01426553, 40.70800498 ], [ -74.01424442, 40.70804318 ], [ -74.01422178, 40.70803597 ], [ -74.01419627, 40.70802786 ], [ -74.01421864, 40.70798898 ], [ -74.01423795, 40.70799558 ], [ -74.01426553, 40.70800498 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00604415, 40.71272728 ], [ -74.00604307, 40.71273457 ], [ -74.00604001, 40.71274022 ], [ -74.00603292, 40.71274642 ], [ -74.00602357, 40.71275016 ], [ -74.00600902, 40.71275098 ], [ -74.0059969, 40.71274717 ], [ -74.00598818, 40.71273981 ], [ -74.00598441, 40.71273069 ], [ -74.00598549, 40.71272238 ], [ -74.00599168, 40.7127138 ], [ -74.00599968, 40.7127089 ], [ -74.00601118, 40.71270611 ], [ -74.00602268, 40.71270686 ], [ -74.00603283, 40.71271087 ], [ -74.00604109, 40.7127187 ], [ -74.00604415, 40.71272728 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01169284, 40.70756596 ], [ -74.01165664, 40.70761016 ], [ -74.01160858, 40.7076184 ], [ -74.01166014, 40.70755827 ], [ -74.01169284, 40.70756596 ] ] ] } }, { "type": "Feature", "properties": { "height": 118.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0065251, 40.70868601 ], [ -74.00647094, 40.70864726 ], [ -74.00649555, 40.70862561 ], [ -74.00654972, 40.70866728 ], [ -74.0065251, 40.70868601 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01414479, 40.70799157 ], [ -74.01413545, 40.70800777 ], [ -74.01412431, 40.70802711 ], [ -74.01409161, 40.70801629 ], [ -74.01409664, 40.70800771 ], [ -74.01407401, 40.70800021 ], [ -74.01408964, 40.70797332 ], [ -74.01414479, 40.70799157 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01022338, 40.71053369 ], [ -74.01014208, 40.71063828 ], [ -74.01012699, 40.71063147 ], [ -74.01014037, 40.71061451 ], [ -74.01020847, 40.71052701 ], [ -74.01022338, 40.71053369 ] ] ] } }, { "type": "Feature", "properties": { "height": 133.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00907264, 40.7065569 ], [ -74.00904605, 40.70658557 ], [ -74.00899628, 40.70656119 ], [ -74.00902323, 40.7065317 ], [ -74.00907264, 40.7065569 ] ] ] } }, { "type": "Feature", "properties": { "height": 98.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01126659, 40.7067106 ], [ -74.01121889, 40.70668949 ], [ -74.01124413, 40.70665496 ], [ -74.01127252, 40.70666627 ], [ -74.01126578, 40.70667498 ], [ -74.0112868, 40.70668431 ], [ -74.01126659, 40.7067106 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01344168, 40.70602921 ], [ -74.01341464, 40.70606796 ], [ -74.01337242, 40.70605039 ], [ -74.01339785, 40.70601396 ], [ -74.01344168, 40.70602921 ] ] ] } }, { "type": "Feature", "properties": { "height": 90.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01195883, 40.70720968 ], [ -74.01186182, 40.70732109 ], [ -74.01185113, 40.70731387 ], [ -74.01194545, 40.70720328 ], [ -74.01195883, 40.70720968 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01194545, 40.70720328 ], [ -74.01185113, 40.70731387 ], [ -74.01185391, 40.70728649 ], [ -74.01193233, 40.70719688 ], [ -74.01194545, 40.70720328 ] ] ] } }, { "type": "Feature", "properties": { "height": 71.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01422178, 40.70803597 ], [ -74.01421037, 40.70805551 ], [ -74.01412431, 40.70802711 ], [ -74.01413545, 40.70800777 ], [ -74.01419627, 40.70802786 ], [ -74.01422178, 40.70803597 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00872301, 40.70565079 ], [ -74.00870972, 40.70567769 ], [ -74.00864675, 40.70564902 ], [ -74.0086639, 40.70562579 ], [ -74.00872301, 40.70565079 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01053464, 40.71013711 ], [ -74.01045811, 40.71023462 ], [ -74.0104432, 40.71022788 ], [ -74.01051964, 40.71013016 ], [ -74.01053464, 40.71013711 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01087798, 40.71029277 ], [ -74.01083935, 40.71034221 ], [ -74.01081375, 40.71037475 ], [ -74.01080243, 40.71038987 ], [ -74.01078698, 40.71038286 ], [ -74.01086307, 40.71028596 ], [ -74.01087798, 40.71029277 ] ] ] } }, { "type": "Feature", "properties": { "height": 215.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00818375, 40.71227427 ], [ -74.00817774, 40.71229729 ], [ -74.00814584, 40.71230307 ], [ -74.00812662, 40.71228626 ], [ -74.00813237, 40.71226317 ], [ -74.00816435, 40.71225732 ], [ -74.00818375, 40.71227427 ] ] ] } }, { "type": "Feature", "properties": { "height": 215.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00825382, 40.71248958 ], [ -74.0082478, 40.71251259 ], [ -74.00821591, 40.71251838 ], [ -74.00819669, 40.7125017 ], [ -74.00820253, 40.71247861 ], [ -74.00823442, 40.71247262 ], [ -74.00825382, 40.71248958 ] ] ] } }, { "type": "Feature", "properties": { "height": 215.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00836099, 40.71236551 ], [ -74.00834195, 40.71238397 ], [ -74.00830997, 40.71237811 ], [ -74.00830287, 40.71235659 ], [ -74.008322, 40.712338 ], [ -74.00835389, 40.71234366 ], [ -74.00836099, 40.71236551 ] ] ] } }, { "type": "Feature", "properties": { "height": 215.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00807542, 40.71241856 ], [ -74.00805673, 40.71243728 ], [ -74.00802457, 40.7124319 ], [ -74.00801721, 40.71241039 ], [ -74.0080358, 40.71239159 ], [ -74.00806787, 40.7123969 ], [ -74.00807542, 40.71241856 ] ] ] } }, { "type": "Feature", "properties": { "height": 234.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00761799, 40.7063285 ], [ -74.00760434, 40.70634192 ], [ -74.00758377, 40.70632986 ], [ -74.00756634, 40.70634709 ], [ -74.00753544, 40.70632891 ], [ -74.00754667, 40.70631788 ], [ -74.00755799, 40.70630678 ], [ -74.00757919, 40.70630562 ], [ -74.007602, 40.70631897 ], [ -74.00761799, 40.7063285 ] ] ] } }, { "type": "Feature", "properties": { "height": 234.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00781257, 40.7065443 ], [ -74.00780134, 40.7065554 ], [ -74.00779011, 40.70656637 ], [ -74.00776882, 40.70656766 ], [ -74.007746, 40.70655431 ], [ -74.00773001, 40.70654478 ], [ -74.00774358, 40.70653136 ], [ -74.00776415, 40.70654342 ], [ -74.00778158, 40.70652619 ], [ -74.00781257, 40.7065443 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0059182, 40.70764816 ], [ -74.00590455, 40.70765926 ], [ -74.00582711, 40.70758299 ], [ -74.00584229, 40.70757345 ], [ -74.0059182, 40.70764816 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01416384, 40.70806627 ], [ -74.01415557, 40.70808139 ], [ -74.0140493, 40.70804788 ], [ -74.01405748, 40.7080329 ], [ -74.01416384, 40.70806627 ] ] ] } }, { "type": "Feature", "properties": { "height": 101.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01362027, 40.70646081 ], [ -74.01360239, 40.70645346 ], [ -74.01362629, 40.70642132 ], [ -74.01358218, 40.70640239 ], [ -74.01359224, 40.70638849 ], [ -74.01365458, 40.7064158 ], [ -74.01362027, 40.70646081 ] ] ] } }, { "type": "Feature", "properties": { "height": 77.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01236891, 40.70716372 ], [ -74.01232669, 40.70721608 ], [ -74.01230091, 40.70720376 ], [ -74.01234322, 40.70715139 ], [ -74.01236891, 40.70716372 ] ] ] } }, { "type": "Feature", "properties": { "height": 87.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01385554, 40.70620742 ], [ -74.01384161, 40.70620116 ], [ -74.0138585, 40.70617698 ], [ -74.01374882, 40.70613919 ], [ -74.01375448, 40.70612959 ], [ -74.01387961, 40.70617276 ], [ -74.01385554, 40.70620742 ] ] ] } }, { "type": "Feature", "properties": { "height": 234.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00785722, 40.70650038 ], [ -74.00784599, 40.70651141 ], [ -74.00781517, 40.7064935 ], [ -74.0078326, 40.70647627 ], [ -74.00781194, 40.70646429 ], [ -74.00782569, 40.70645087 ], [ -74.00784168, 40.70646007 ], [ -74.00786467, 40.70647341 ], [ -74.00786853, 40.70648928 ], [ -74.00785722, 40.70650038 ] ] ] } }, { "type": "Feature", "properties": { "height": 234.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00753598, 40.70640899 ], [ -74.00752223, 40.70642241 ], [ -74.00750624, 40.70641308 ], [ -74.00748325, 40.7063998 ], [ -74.00747938, 40.70638386 ], [ -74.0074907, 40.70637276 ], [ -74.00750202, 40.7063618 ], [ -74.00753274, 40.70637978 ], [ -74.00751532, 40.70639687 ], [ -74.00753598, 40.70640899 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00475506, 40.70782439 ], [ -74.00469461, 40.7078472 ], [ -74.0046788, 40.70782221 ], [ -74.00473898, 40.70779967 ], [ -74.00475506, 40.70782439 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00684913, 40.70808411 ], [ -74.00678148, 40.70814642 ], [ -74.00676388, 40.70813552 ], [ -74.00683152, 40.70807308 ], [ -74.00684913, 40.70808411 ] ] ] } }, { "type": "Feature", "properties": { "height": 101.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01329759, 40.70625959 ], [ -74.01328744, 40.70627327 ], [ -74.01324307, 40.70625407 ], [ -74.01321971, 40.70628519 ], [ -74.01320183, 40.70627736 ], [ -74.01323552, 40.70623269 ], [ -74.01329759, 40.70625959 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00707604, 40.70963396 ], [ -74.00705511, 40.7096548 ], [ -74.00699897, 40.70962252 ], [ -74.00701981, 40.70960168 ], [ -74.00707604, 40.70963396 ] ] ] } }, { "type": "Feature", "properties": { "height": 262.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00771277, 40.70644229 ], [ -74.00769211, 40.70646279 ], [ -74.00763767, 40.70643106 ], [ -74.00765842, 40.70641056 ], [ -74.00771277, 40.70644229 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00688883, 40.70811325 ], [ -74.00682478, 40.70817229 ], [ -74.00680664, 40.70816099 ], [ -74.00687051, 40.70810188 ], [ -74.00688883, 40.70811325 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01379993, 40.70637161 ], [ -74.01376597, 40.70641349 ], [ -74.01373507, 40.70639987 ], [ -74.01376705, 40.7063588 ], [ -74.01377747, 40.70636262 ], [ -74.01379993, 40.70637161 ] ] ] } }, { "type": "Feature", "properties": { "height": 108.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01164595, 40.70755432 ], [ -74.01162035, 40.70755718 ], [ -74.0116641, 40.70750808 ], [ -74.01166787, 40.70750992 ], [ -74.01168305, 40.70749167 ], [ -74.01169805, 40.70747356 ], [ -74.01170165, 40.70746961 ], [ -74.01171395, 40.70746511 ], [ -74.01171485, 40.70747356 ], [ -74.01164595, 40.70755432 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00470817, 40.70786831 ], [ -74.00464286, 40.70789242 ], [ -74.00462984, 40.70787131 ], [ -74.00469461, 40.7078472 ], [ -74.00470817, 40.70786831 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00593033, 40.70763842 ], [ -74.0059182, 40.70764816 ], [ -74.00584229, 40.70757345 ], [ -74.00585721, 40.70756358 ], [ -74.00593033, 40.70763842 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00752583, 40.70630072 ], [ -74.00752241, 40.70630371 ], [ -74.00751424, 40.70629888 ], [ -74.00745809, 40.7063539 ], [ -74.00746645, 40.7063586 ], [ -74.00746313, 40.70636207 ], [ -74.00743887, 40.70634832 ], [ -74.00750103, 40.70628642 ], [ -74.00752583, 40.70630072 ] ] ] } }, { "type": "Feature", "properties": { "height": 108.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01150123, 40.70737019 ], [ -74.01149773, 40.70737461 ], [ -74.01146539, 40.7074135 ], [ -74.01146889, 40.70741506 ], [ -74.01142865, 40.70746607 ], [ -74.01142164, 40.70744931 ], [ -74.01148901, 40.70736487 ], [ -74.0114997, 40.70736229 ], [ -74.01150123, 40.70737019 ] ] ] } }, { "type": "Feature", "properties": { "height": 39.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00717818, 40.70967488 ], [ -74.00706427, 40.70979146 ], [ -74.00698091, 40.70974808 ], [ -74.00698522, 40.70974366 ], [ -74.00706194, 40.70978356 ], [ -74.00717162, 40.70967148 ], [ -74.00717818, 40.70967488 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01376355, 40.70611447 ], [ -74.01363257, 40.70606939 ], [ -74.01363877, 40.7060591 ], [ -74.01376975, 40.70610419 ], [ -74.01376355, 40.70611447 ] ] ] } }, { "type": "Feature", "properties": { "height": 224.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.007746, 40.70655431 ], [ -74.00773001, 40.70656916 ], [ -74.00771888, 40.70657958 ], [ -74.00769471, 40.70658026 ], [ -74.00765465, 40.70655499 ], [ -74.00766561, 40.70654437 ], [ -74.00769318, 40.70656058 ], [ -74.00771591, 40.70655867 ], [ -74.00773001, 40.70654478 ], [ -74.007746, 40.70655431 ] ] ] } }, { "type": "Feature", "properties": { "height": 38.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00716174, 40.70561946 ], [ -74.00713973, 40.70564098 ], [ -74.00712221, 40.705629 ], [ -74.00709311, 40.70560911 ], [ -74.00711305, 40.70558997 ], [ -74.00712374, 40.70559651 ], [ -74.00716174, 40.70561946 ] ] ] } }, { "type": "Feature", "properties": { "height": 111.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01360239, 40.70645346 ], [ -74.01358245, 40.70644488 ], [ -74.01357122, 40.70641716 ], [ -74.01358218, 40.70640239 ], [ -74.01362629, 40.70642132 ], [ -74.01360239, 40.70645346 ] ] ] } }, { "type": "Feature", "properties": { "height": 111.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01328744, 40.70627327 ], [ -74.01327612, 40.70628839 ], [ -74.01323938, 40.70629357 ], [ -74.01321971, 40.70628519 ], [ -74.01324307, 40.70625407 ], [ -74.01328744, 40.70627327 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00626154, 40.70854348 ], [ -74.00617054, 40.70862091 ], [ -74.0061594, 40.70861321 ], [ -74.00624977, 40.70853586 ], [ -74.00626154, 40.70854348 ] ] ] } }, { "type": "Feature", "properties": { "height": 43.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00717162, 40.70967148 ], [ -74.00706194, 40.70978356 ], [ -74.00698522, 40.70974366 ], [ -74.00698953, 40.7097393 ], [ -74.0070596, 40.70977566 ], [ -74.00716506, 40.70966807 ], [ -74.00717162, 40.70967148 ] ] ] } }, { "type": "Feature", "properties": { "height": 224.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00769345, 40.70631829 ], [ -74.00768249, 40.70632898 ], [ -74.00765483, 40.7063127 ], [ -74.00763219, 40.70631461 ], [ -74.00761799, 40.7063285 ], [ -74.007602, 40.70631897 ], [ -74.00761799, 40.70630412 ], [ -74.00762922, 40.7062937 ], [ -74.00765249, 40.7062937 ], [ -74.00769345, 40.70631829 ] ] ] } }, { "type": "Feature", "properties": { "height": 224.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00753867, 40.70647008 ], [ -74.00752834, 40.70648015 ], [ -74.00748594, 40.70645721 ], [ -74.00748064, 40.7064393 ], [ -74.00749124, 40.7064286 ], [ -74.00750624, 40.70641308 ], [ -74.00752223, 40.70642241 ], [ -74.00750759, 40.70643678 ], [ -74.00751092, 40.7064538 ], [ -74.00753867, 40.70647008 ] ] ] } }, { "type": "Feature", "properties": { "height": 224.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00785668, 40.70644461 ], [ -74.00784168, 40.70646007 ], [ -74.00782569, 40.70645087 ], [ -74.00784024, 40.70643637 ], [ -74.00783709, 40.70641948 ], [ -74.00780934, 40.70640327 ], [ -74.0078194, 40.70639306 ], [ -74.00786189, 40.70641601 ], [ -74.00786719, 40.70643392 ], [ -74.00785668, 40.70644461 ] ] ] } }, { "type": "Feature", "properties": { "height": 108.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01185391, 40.70728649 ], [ -74.01185113, 40.70731387 ], [ -74.01179714, 40.70737706 ], [ -74.01178663, 40.70737931 ], [ -74.01178591, 40.70736896 ], [ -74.01180378, 40.70734588 ], [ -74.01181968, 40.70732647 ], [ -74.01183567, 40.70730726 ], [ -74.01185391, 40.70728649 ] ] ] } }, { "type": "Feature", "properties": { "height": 63.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00417089, 40.70803705 ], [ -74.00411717, 40.70806245 ], [ -74.00410028, 40.70804182 ], [ -74.00415391, 40.70801649 ], [ -74.00417089, 40.70803705 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00665338, 40.70838251 ], [ -74.00664072, 40.70839381 ], [ -74.00656238, 40.70834321 ], [ -74.00657478, 40.70833218 ], [ -74.00665338, 40.70838251 ] ] ] } }, { "type": "Feature", "properties": { "height": 89.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0138126, 40.70626878 ], [ -74.01375367, 40.70635308 ], [ -74.01373947, 40.70634736 ], [ -74.01379858, 40.70626279 ], [ -74.0138126, 40.70626878 ] ] ] } }, { "type": "Feature", "properties": { "height": 85.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01140987, 40.70744039 ], [ -74.01136424, 40.7075025 ], [ -74.01136172, 40.70747036 ], [ -74.0113929, 40.70742378 ], [ -74.01140987, 40.70744039 ] ] ] } }, { "type": "Feature", "properties": { "height": 108.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01164532, 40.70719579 ], [ -74.01163328, 40.70721091 ], [ -74.01161855, 40.70722888 ], [ -74.01160337, 40.70724686 ], [ -74.01158343, 40.70727111 ], [ -74.01156789, 40.70727696 ], [ -74.01157067, 40.70726266 ], [ -74.0116164, 40.70720546 ], [ -74.01164532, 40.70719579 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01310464, 40.70629282 ], [ -74.01307158, 40.7063317 ], [ -74.01304481, 40.70631992 ], [ -74.01307858, 40.70628022 ], [ -74.01310464, 40.70629282 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01366608, 40.70653688 ], [ -74.01363347, 40.70657719 ], [ -74.01360652, 40.70656548 ], [ -74.01363823, 40.70652469 ], [ -74.01366608, 40.70653688 ] ] ] } }, { "type": "Feature", "properties": { "height": 54.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01324181, 40.7061302 ], [ -74.01320749, 40.70617092 ], [ -74.01318153, 40.70615826 ], [ -74.01321513, 40.70611849 ], [ -74.01324181, 40.7061302 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01473148, 40.70894191 ], [ -74.01471927, 40.70897167 ], [ -74.01467489, 40.70896132 ], [ -74.01468711, 40.70893149 ], [ -74.01473148, 40.70894191 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00716506, 40.70966807 ], [ -74.0070596, 40.70977566 ], [ -74.00698953, 40.7097393 ], [ -74.00699367, 40.70973501 ], [ -74.00705718, 40.7097679 ], [ -74.0071586, 40.70966467 ], [ -74.00716506, 40.70966807 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0084678, 40.70734819 ], [ -74.00846663, 40.70735412 ], [ -74.00846313, 40.70735936 ], [ -74.00845765, 40.70736358 ], [ -74.00845073, 40.70736637 ], [ -74.00844238, 40.70736739 ], [ -74.00843411, 40.7073663 ], [ -74.00842675, 40.70736317 ], [ -74.00842109, 40.70735841 ], [ -74.00841794, 40.70735248 ], [ -74.00841741, 40.70734608 ], [ -74.00841983, 40.70733988 ], [ -74.00842468, 40.70733471 ], [ -74.0084316, 40.70733096 ], [ -74.00843968, 40.70732919 ], [ -74.00844822, 40.7073296 ], [ -74.00845603, 40.70733212 ], [ -74.00846232, 40.70733627 ], [ -74.00846645, 40.70734186 ], [ -74.0084678, 40.70734819 ] ] ] } }, { "type": "Feature", "properties": { "height": 190.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01163508, 40.70747948 ], [ -74.0116075, 40.70747846 ], [ -74.01152378, 40.70743821 ], [ -74.01151165, 40.70741901 ], [ -74.01153384, 40.70742221 ], [ -74.01153743, 40.70743106 ], [ -74.01155585, 40.70743999 ], [ -74.01156914, 40.70745469 ], [ -74.01159169, 40.7074581 ], [ -74.01161002, 40.70746709 ], [ -74.01162232, 40.70746586 ], [ -74.01163508, 40.70747948 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0071586, 40.70966467 ], [ -74.00705718, 40.7097679 ], [ -74.00699367, 40.70973501 ], [ -74.00699798, 40.70973058 ], [ -74.00705484, 40.70976 ], [ -74.00715213, 40.70966126 ], [ -74.0071586, 40.70966467 ] ] ] } }, { "type": "Feature", "properties": { "height": 59.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00706212, 40.70952691 ], [ -74.00702933, 40.7095596 ], [ -74.00700229, 40.70954401 ], [ -74.00703508, 40.70951132 ], [ -74.00706212, 40.70952691 ] ] ] } }, { "type": "Feature", "properties": { "height": 190.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01178941, 40.70730148 ], [ -74.01176767, 40.70729807 ], [ -74.01176417, 40.70728908 ], [ -74.01174584, 40.70728016 ], [ -74.01173255, 40.70726586 ], [ -74.01170928, 40.70726287 ], [ -74.01169087, 40.70725388 ], [ -74.01167892, 40.70725476 ], [ -74.0116658, 40.70724101 ], [ -74.01169329, 40.7072425 ], [ -74.01177728, 40.70728248 ], [ -74.01178941, 40.70730148 ] ] ] } }, { "type": "Feature", "properties": { "height": 38.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00735623, 40.70573462 ], [ -74.00733188, 40.70575811 ], [ -74.00729595, 40.70573516 ], [ -74.00731922, 40.70571262 ], [ -74.00735623, 40.70573462 ] ] ] } }, { "type": "Feature", "properties": { "height": 47.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0078123, 40.70935429 ], [ -74.00778625, 40.70933911 ], [ -74.00781652, 40.70930847 ], [ -74.00784293, 40.70932358 ], [ -74.0078123, 40.70935429 ] ] ] } }, { "type": "Feature", "properties": { "height": 267.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00971439, 40.7069661 ], [ -74.0097126, 40.70697182 ], [ -74.00970846, 40.70697672 ], [ -74.009702, 40.7069806 ], [ -74.00969481, 40.70698231 ], [ -74.00968681, 40.70698196 ], [ -74.00967981, 40.70697979 ], [ -74.00967352, 40.70697556 ], [ -74.0096702, 40.70697059 ], [ -74.00966903, 40.7069644 ], [ -74.00967082, 40.70695868 ], [ -74.00967514, 40.70695357 ], [ -74.00968089, 40.70695016 ], [ -74.00968852, 40.70694819 ], [ -74.00969562, 40.70694839 ], [ -74.00970361, 40.70695057 ], [ -74.00970963, 40.70695479 ], [ -74.00971332, 40.7069599 ], [ -74.00971439, 40.7069661 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00465535, 40.7079106 ], [ -74.0046028, 40.70793117 ], [ -74.0045904, 40.70791298 ], [ -74.00464286, 40.70789242 ], [ -74.00465535, 40.7079106 ] ] ] } }, { "type": "Feature", "properties": { "height": 73.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0070561, 40.70811148 ], [ -74.00704352, 40.70812926 ], [ -74.00699358, 40.70809882 ], [ -74.00700984, 40.70808329 ], [ -74.0070561, 40.70811148 ] ] ] } }, { "type": "Feature", "properties": { "height": 104.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00570413, 40.70844686 ], [ -74.00566515, 40.70841267 ], [ -74.00568473, 40.7083998 ], [ -74.00572381, 40.70843412 ], [ -74.00570413, 40.70844686 ] ] ] } }, { "type": "Feature", "properties": { "height": 31.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0060357, 40.71272851 ], [ -74.00603462, 40.7127345 ], [ -74.0060304, 40.71273906 ], [ -74.0060251, 40.71274247 ], [ -74.00601747, 40.71274431 ], [ -74.00600929, 40.71274431 ], [ -74.00600157, 40.71274247 ], [ -74.00599663, 40.71273927 ], [ -74.00599294, 40.71273368 ], [ -74.0059924, 40.7127279 ], [ -74.00599447, 40.71272088 ], [ -74.00599851, 40.71271666 ], [ -74.00600588, 40.71271292 ], [ -74.00601297, 40.7127119 ], [ -74.00602007, 40.7127123 ], [ -74.00602591, 40.71271469 ], [ -74.00603094, 40.71271809 ], [ -74.00603444, 40.71272252 ], [ -74.0060357, 40.71272851 ] ] ] } }, { "type": "Feature", "properties": { "height": 101.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01319033, 40.7063238 ], [ -74.01315611, 40.70636881 ], [ -74.01313814, 40.70636098 ], [ -74.0131721, 40.70631631 ], [ -74.01319033, 40.7063238 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0067036, 40.70843446 ], [ -74.00669569, 40.70844161 ], [ -74.0066921, 40.70844488 ], [ -74.00663021, 40.70840341 ], [ -74.00664072, 40.70839381 ], [ -74.0067036, 40.70843446 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01487441, 40.70750658 ], [ -74.01486102, 40.70752837 ], [ -74.0148206, 40.70751421 ], [ -74.01483398, 40.70749242 ], [ -74.01487441, 40.70750658 ] ] ] } }, { "type": "Feature", "properties": { "height": 101.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01359125, 40.70649902 ], [ -74.01355703, 40.7065441 ], [ -74.01353951, 40.7065364 ], [ -74.01357329, 40.70649166 ], [ -74.01359125, 40.70649902 ] ] ] } }, { "type": "Feature", "properties": { "height": 74.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00780044, 40.70935382 ], [ -74.00777664, 40.70937738 ], [ -74.00774951, 40.70936172 ], [ -74.0077734, 40.70933809 ], [ -74.00780044, 40.70935382 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00700247, 40.70959208 ], [ -74.00698064, 40.70961387 ], [ -74.00695037, 40.70959651 ], [ -74.00697229, 40.70957472 ], [ -74.00700247, 40.70959208 ] ] ] } }, { "type": "Feature", "properties": { "height": 91.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00614934, 40.70746096 ], [ -74.00613362, 40.70747376 ], [ -74.00609391, 40.70744428 ], [ -74.006109, 40.70743147 ], [ -74.00614934, 40.70746096 ] ] ] } }, { "type": "Feature", "properties": { "height": 100.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00575498, 40.70748336 ], [ -74.00571698, 40.70744516 ], [ -74.00574959, 40.70743168 ], [ -74.00575848, 40.70744196 ], [ -74.00574007, 40.70745061 ], [ -74.00576809, 40.7074771 ], [ -74.00575498, 40.70748336 ] ] ] } }, { "type": "Feature", "properties": { "height": 95.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00691021, 40.70816092 ], [ -74.00690967, 40.70816787 ], [ -74.00690518, 40.708174 ], [ -74.00689782, 40.70817801 ], [ -74.00688874, 40.70817917 ], [ -74.00687994, 40.70817726 ], [ -74.00687311, 40.70817257 ], [ -74.00686952, 40.70816617 ], [ -74.00686997, 40.70815929 ], [ -74.00687455, 40.70815316 ], [ -74.00688192, 40.70814907 ], [ -74.00689099, 40.70814798 ], [ -74.00689979, 40.70814989 ], [ -74.00690671, 40.70815452 ], [ -74.00691021, 40.70816092 ] ] ] } }, { "type": "Feature", "properties": { "height": 145.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01416528, 40.70790822 ], [ -74.01416294, 40.70791496 ], [ -74.01415692, 40.70792027 ], [ -74.01414839, 40.7079232 ], [ -74.01413913, 40.70792286 ], [ -74.01413087, 40.70791959 ], [ -74.01412539, 40.70791387 ], [ -74.01412359, 40.70790699 ], [ -74.01412602, 40.70790018 ], [ -74.01413213, 40.70789487 ], [ -74.01414057, 40.70789208 ], [ -74.01414991, 40.70789228 ], [ -74.01415809, 40.70789562 ], [ -74.01416357, 40.70790127 ], [ -74.01416528, 40.70790822 ] ] ] } }, { "type": "Feature", "properties": { "height": 95.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01011729, 40.7092751 ], [ -74.01010175, 40.70929226 ], [ -74.01006258, 40.70927197 ], [ -74.01007812, 40.70925481 ], [ -74.01011729, 40.7092751 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01410042, 40.70967107 ], [ -74.01408497, 40.70969198 ], [ -74.01404975, 40.70967577 ], [ -74.01406502, 40.7096548 ], [ -74.01410042, 40.70967107 ] ] ] } }, { "type": "Feature", "properties": { "height": 120.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00906788, 40.70643351 ], [ -74.00906105, 40.7064412 ], [ -74.00897517, 40.70639408 ], [ -74.00898191, 40.70638611 ], [ -74.00906788, 40.70643351 ] ] ] } }, { "type": "Feature", "properties": { "height": 234.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0078291, 40.70638386 ], [ -74.0078194, 40.70639306 ], [ -74.00780934, 40.70640327 ], [ -74.0077796, 40.70638577 ], [ -74.00779936, 40.70636636 ], [ -74.0078291, 40.70638386 ] ] ] } }, { "type": "Feature", "properties": { "height": 234.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00766561, 40.70654437 ], [ -74.00765465, 40.70655499 ], [ -74.00764557, 40.70656412 ], [ -74.00761584, 40.70654662 ], [ -74.00763578, 40.70652687 ], [ -74.00766561, 40.70654437 ] ] ] } }, { "type": "Feature", "properties": { "height": 234.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00773235, 40.7063268 ], [ -74.00771232, 40.70634641 ], [ -74.00768249, 40.70632898 ], [ -74.00769345, 40.70631829 ], [ -74.00770262, 40.7063093 ], [ -74.00773235, 40.7063268 ] ] ] } }, { "type": "Feature", "properties": { "height": 234.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0075685, 40.70648751 ], [ -74.00754847, 40.70650712 ], [ -74.00751882, 40.70648969 ], [ -74.00752834, 40.70648015 ], [ -74.00753867, 40.70647008 ], [ -74.0075685, 40.70648751 ] ] ] } }, { "type": "Feature", "properties": { "height": 32.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01413249, 40.70968591 ], [ -74.01411632, 40.70970641 ], [ -74.01408497, 40.70969198 ], [ -74.01410042, 40.70967107 ], [ -74.01413249, 40.70968591 ] ] ] } }, { "type": "Feature", "properties": { "height": 111.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01178663, 40.70737931 ], [ -74.01171395, 40.70746511 ], [ -74.01170165, 40.70746961 ], [ -74.01178591, 40.70736896 ], [ -74.01178663, 40.70737931 ] ] ] } }, { "type": "Feature", "properties": { "height": 111.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01158343, 40.70727111 ], [ -74.01150123, 40.70737019 ], [ -74.0114997, 40.70736229 ], [ -74.01156789, 40.70727696 ], [ -74.01158343, 40.70727111 ] ] ] } }, { "type": "Feature", "properties": { "height": 81.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00616299, 40.70744986 ], [ -74.00614934, 40.70746096 ], [ -74.006109, 40.70743147 ], [ -74.00612275, 40.70741996 ], [ -74.00616299, 40.70744986 ] ] ] } }, { "type": "Feature", "properties": { "height": 81.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00613362, 40.70747376 ], [ -74.00611952, 40.70748486 ], [ -74.00607954, 40.7074564 ], [ -74.00609391, 40.70744428 ], [ -74.00613362, 40.70747376 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00797319, 40.71315006 ], [ -74.00795396, 40.71317451 ], [ -74.00793007, 40.71316382 ], [ -74.00794938, 40.7131393 ], [ -74.00797319, 40.71315006 ] ] ] } }, { "type": "Feature", "properties": { "height": 176.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01169437, 40.70723998 ], [ -74.0116552, 40.70723358 ], [ -74.01163203, 40.70723549 ], [ -74.01160337, 40.70724686 ], [ -74.01161855, 40.70722888 ], [ -74.01163023, 40.70722351 ], [ -74.01163858, 40.70722228 ], [ -74.01164981, 40.70722248 ], [ -74.01166383, 40.70722528 ], [ -74.01168161, 40.70723358 ], [ -74.01169437, 40.70723998 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.05 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00938902, 40.71139881 ], [ -74.00938848, 40.7114063 ], [ -74.00938363, 40.71141202 ], [ -74.00937429, 40.7114157 ], [ -74.00936477, 40.71141529 ], [ -74.00935704, 40.71141147 ], [ -74.00935219, 40.71140446 ], [ -74.00935273, 40.71139752 ], [ -74.00935803, 40.71139132 ], [ -74.00936683, 40.71138778 ], [ -74.00937645, 40.71138819 ], [ -74.00938453, 40.7113922 ], [ -74.00938902, 40.71139881 ] ] ] } }, { "type": "Feature", "properties": { "height": 176.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01152108, 40.70743999 ], [ -74.01149908, 40.70742936 ], [ -74.01149378, 40.70742691 ], [ -74.01148228, 40.70741629 ], [ -74.01147922, 40.70741091 ], [ -74.0114785, 40.70740301 ], [ -74.01148147, 40.70739409 ], [ -74.01149773, 40.70737461 ], [ -74.01149279, 40.70739872 ], [ -74.01149719, 40.70741472 ], [ -74.01152108, 40.70743999 ] ] ] } }, { "type": "Feature", "properties": { "height": 176.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01169805, 40.70747356 ], [ -74.01168305, 40.70749167 ], [ -74.01167371, 40.70749596 ], [ -74.01166517, 40.70749841 ], [ -74.01165314, 40.70749862 ], [ -74.01163715, 40.70749521 ], [ -74.01163194, 40.70749269 ], [ -74.01160669, 40.70748078 ], [ -74.01164631, 40.70748786 ], [ -74.0116658, 40.70748609 ], [ -74.01169805, 40.70747356 ] ] ] } }, { "type": "Feature", "properties": { "height": 263.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00770208, 40.70644338 ], [ -74.00769067, 40.70645469 ], [ -74.00764845, 40.70642997 ], [ -74.00765977, 40.70641866 ], [ -74.00770208, 40.70644338 ] ] ] } }, { "type": "Feature", "properties": { "height": 109.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00611952, 40.70748486 ], [ -74.00610739, 40.70749487 ], [ -74.00606768, 40.70746641 ], [ -74.00607954, 40.7074564 ], [ -74.00611952, 40.70748486 ] ] ] } }, { "type": "Feature", "properties": { "height": 138.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00874727, 40.70573237 ], [ -74.00872265, 40.70573659 ], [ -74.00870972, 40.70567769 ], [ -74.00874727, 40.70573237 ] ] ] } }, { "type": "Feature", "properties": { "height": 123.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01466788, 40.70943825 ], [ -74.01465099, 40.70948218 ], [ -74.01463698, 40.70947911 ], [ -74.01465423, 40.70943587 ], [ -74.01466788, 40.70943825 ] ] ] } }, { "type": "Feature", "properties": { "height": 126.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01465099, 40.70948218 ], [ -74.01463402, 40.70952596 ], [ -74.01461991, 40.70952358 ], [ -74.01463698, 40.70947911 ], [ -74.01465099, 40.70948218 ] ] ] } }, { "type": "Feature", "properties": { "height": 120.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01468495, 40.70939447 ], [ -74.01466788, 40.70943825 ], [ -74.01465423, 40.70943587 ], [ -74.01466941, 40.70939427 ], [ -74.01468495, 40.70939447 ] ] ] } }, { "type": "Feature", "properties": { "height": 129.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01463402, 40.70952596 ], [ -74.01461704, 40.70956988 ], [ -74.01460338, 40.70956668 ], [ -74.01461991, 40.70952358 ], [ -74.01463402, 40.70952596 ] ] ] } }, { "type": "Feature", "properties": { "height": 175.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00815483, 40.71222518 ], [ -74.00815025, 40.71223832 ], [ -74.00813201, 40.71224057 ], [ -74.00812204, 40.71223049 ], [ -74.00812662, 40.71221728 ], [ -74.00814459, 40.71221489 ], [ -74.00815483, 40.71222518 ] ] ] } }, { "type": "Feature", "properties": { "height": 175.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00825858, 40.71254296 ], [ -74.00825472, 40.71255631 ], [ -74.00823657, 40.7125591 ], [ -74.00822597, 40.71254936 ], [ -74.00822993, 40.71253602 ], [ -74.0082478, 40.71253309 ], [ -74.00825858, 40.71254296 ] ] ] } }, { "type": "Feature", "properties": { "height": 175.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00798415, 40.71244198 ], [ -74.00796645, 40.7124379 ], [ -74.0079634, 40.7124255 ], [ -74.00797534, 40.71241522 ], [ -74.00799295, 40.71241917 ], [ -74.00799592, 40.7124319 ], [ -74.00798415, 40.71244198 ] ] ] } }, { "type": "Feature", "properties": { "height": 175.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00840465, 40.71236129 ], [ -74.00838704, 40.71235721 ], [ -74.00838399, 40.71234468 ], [ -74.00839594, 40.71233446 ], [ -74.00841354, 40.71233848 ], [ -74.00841651, 40.71235108 ], [ -74.00840465, 40.71236129 ] ] ] } }, { "type": "Feature", "properties": { "height": 123.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01459997, 40.70961367 ], [ -74.01458308, 40.70965759 ], [ -74.01456979, 40.70965439 ], [ -74.01458695, 40.70961026 ], [ -74.01459997, 40.70961367 ] ] ] } }, { "type": "Feature", "properties": { "height": 126.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01461704, 40.70956988 ], [ -74.01459997, 40.70961367 ], [ -74.01458695, 40.70961026 ], [ -74.01460338, 40.70956668 ], [ -74.01461704, 40.70956988 ] ] ] } }, { "type": "Feature", "properties": { "height": 120.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01458308, 40.70965759 ], [ -74.0145661, 40.70970137 ], [ -74.01455389, 40.70969606 ], [ -74.01456979, 40.70965439 ], [ -74.01458308, 40.70965759 ] ] ] } }, { "type": "Feature", "properties": { "height": 123.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00978024, 40.70716276 ], [ -74.00977162, 40.70717148 ], [ -74.0097267, 40.70714622 ], [ -74.0097347, 40.70713777 ], [ -74.00978024, 40.70716276 ] ] ] } }, { "type": "Feature", "properties": { "height": 38.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00691857, 40.7095899 ], [ -74.00689521, 40.70961591 ], [ -74.00687841, 40.70960706 ], [ -74.00690168, 40.70958119 ], [ -74.00691857, 40.7095899 ] ] ] } }, { "type": "Feature", "properties": { "height": 38.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00678822, 40.70952399 ], [ -74.00676486, 40.70954986 ], [ -74.00674798, 40.70954121 ], [ -74.00677133, 40.70951527 ], [ -74.00678822, 40.70952399 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01191545, 40.70785388 ], [ -74.01190961, 40.70786116 ], [ -74.01189703, 40.70786361 ], [ -74.01188589, 40.70785837 ], [ -74.01188311, 40.7078489 ], [ -74.01188903, 40.70784169 ], [ -74.01190152, 40.7078393 ], [ -74.01191275, 40.70784448 ], [ -74.01191545, 40.70785388 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01194725, 40.70795037 ], [ -74.01194132, 40.70795765 ], [ -74.01192874, 40.70796011 ], [ -74.01191769, 40.70795486 ], [ -74.01191482, 40.7079454 ], [ -74.01192075, 40.70793818 ], [ -74.01193323, 40.7079358 ], [ -74.01194437, 40.70794097 ], [ -74.01194725, 40.70795037 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01186559, 40.70791292 ], [ -74.01185975, 40.70792007 ], [ -74.01184717, 40.70792252 ], [ -74.01183612, 40.70791741 ], [ -74.01183334, 40.70790781 ], [ -74.01183918, 40.70790059 ], [ -74.01185166, 40.70789821 ], [ -74.0118628, 40.70790338 ], [ -74.01186559, 40.70791292 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0119954, 40.70789126 ], [ -74.01198947, 40.70789848 ], [ -74.01197698, 40.70790086 ], [ -74.01196593, 40.70789569 ], [ -74.01196315, 40.70788622 ], [ -74.01196898, 40.707879 ], [ -74.01198147, 40.70787662 ], [ -74.01199261, 40.7078818 ], [ -74.0119954, 40.70789126 ] ] ] } }, { "type": "Feature", "properties": { "height": 63.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01424442, 40.70804318 ], [ -74.01423319, 40.70806259 ], [ -74.01421037, 40.70805551 ], [ -74.01422178, 40.70803597 ], [ -74.01424442, 40.70804318 ] ] ] } }, { "type": "Feature", "properties": { "height": 176.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01181968, 40.70732647 ], [ -74.01180378, 40.70734588 ], [ -74.01180657, 40.70732088 ], [ -74.01179965, 40.70730257 ], [ -74.01178025, 40.70728077 ], [ -74.01179157, 40.70728636 ], [ -74.01180792, 40.70729412 ], [ -74.011801, 40.7072946 ], [ -74.01180522, 40.70730277 ], [ -74.01180648, 40.70730897 ], [ -74.01181968, 40.70732647 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00645108, 40.70937847 ], [ -74.00644974, 40.70938371 ], [ -74.00644533, 40.70938786 ], [ -74.00643887, 40.70939011 ], [ -74.00643177, 40.7093897 ], [ -74.00642584, 40.70938691 ], [ -74.00642225, 40.70938228 ], [ -74.00642189, 40.70937697 ], [ -74.00642485, 40.70937207 ], [ -74.00643042, 40.7093688 ], [ -74.00643743, 40.70936791 ], [ -74.00644408, 40.70936948 ], [ -74.00644902, 40.70937336 ], [ -74.00645108, 40.70937847 ] ] ] } }, { "type": "Feature", "properties": { "height": 156.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00910129, 40.70649861 ], [ -74.00909977, 40.70650719 ], [ -74.00909078, 40.70651236 ], [ -74.00907955, 40.70651121 ], [ -74.00907264, 40.7065044 ], [ -74.00907407, 40.70649582 ], [ -74.00908324, 40.70649057 ], [ -74.00909438, 40.7064918 ], [ -74.00910129, 40.70649861 ] ] ] } }, { "type": "Feature", "properties": { "height": 71.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01470723, 40.7092006 ], [ -74.0147216, 40.70920401 ], [ -74.01472573, 40.70919386 ], [ -74.01473831, 40.70919686 ], [ -74.0147305, 40.7092162 ], [ -74.01470337, 40.70920986 ], [ -74.01470723, 40.7092006 ] ] ] } }, { "type": "Feature", "properties": { "height": 205.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00907803, 40.71218786 ], [ -74.00906707, 40.71220148 ], [ -74.00904793, 40.71219249 ], [ -74.00905898, 40.71217908 ], [ -74.00907803, 40.71218786 ] ] ] } }, { "type": "Feature", "properties": { "height": 205.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00924305, 40.71226501 ], [ -74.00923209, 40.7122787 ], [ -74.00921295, 40.71226971 ], [ -74.00922409, 40.71225609 ], [ -74.00924305, 40.71226501 ] ] ] } }, { "type": "Feature", "properties": { "height": 204.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00920487, 40.71231336 ], [ -74.00919867, 40.71232119 ], [ -74.00918061, 40.71232411 ], [ -74.00917801, 40.71231131 ], [ -74.00918457, 40.71230369 ], [ -74.00920487, 40.71231336 ] ] ] } }, { "type": "Feature", "properties": { "height": 71.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01464399, 40.70905897 ], [ -74.0146271, 40.70905502 ], [ -74.01462225, 40.709067 ], [ -74.0146121, 40.70906462 ], [ -74.01461991, 40.70904542 ], [ -74.01464704, 40.70905168 ], [ -74.01464399, 40.70905897 ] ] ] } }, { "type": "Feature", "properties": { "height": 71.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01476301, 40.7091018 ], [ -74.01476858, 40.70908797 ], [ -74.01475367, 40.70908457 ], [ -74.01475601, 40.70907899 ], [ -74.01478305, 40.70908539 ], [ -74.01477523, 40.70910459 ], [ -74.01476301, 40.7091018 ] ] ] } }, { "type": "Feature", "properties": { "height": 71.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01459764, 40.70917507 ], [ -74.01459395, 40.70918406 ], [ -74.01456691, 40.70917779 ], [ -74.01457473, 40.70915852 ], [ -74.01458425, 40.7091607 ], [ -74.01458012, 40.70917098 ], [ -74.01459764, 40.70917507 ] ] ] } }, { "type": "Feature", "properties": { "height": 282.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0097028, 40.70696562 ], [ -74.00970191, 40.70696841 ], [ -74.00969993, 40.70697086 ], [ -74.00969679, 40.7069727 ], [ -74.00969319, 40.70697359 ], [ -74.00968942, 40.70697338 ], [ -74.00968583, 40.70697229 ], [ -74.00968295, 40.70697032 ], [ -74.00968125, 40.70696766 ], [ -74.00968062, 40.7069648 ], [ -74.00968151, 40.70696201 ], [ -74.00968358, 40.70695949 ], [ -74.00968637, 40.70695779 ], [ -74.00969014, 40.70695691 ], [ -74.00969391, 40.70695697 ], [ -74.0096975, 40.70695799 ], [ -74.00970038, 40.7069599 ], [ -74.00970227, 40.70696249 ], [ -74.0097028, 40.70696562 ] ] ] } }, { "type": "Feature", "properties": { "height": 264.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0076895, 40.70643698 ], [ -74.00767899, 40.7064474 ], [ -74.00766057, 40.70643671 ], [ -74.00767118, 40.70642629 ], [ -74.0076895, 40.70643698 ] ] ] } }, { "type": "Feature", "properties": { "height": 204.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00912267, 40.71227386 ], [ -74.00911638, 40.71228169 ], [ -74.00909869, 40.71228489 ], [ -74.00909653, 40.71227216 ], [ -74.00910291, 40.71226426 ], [ -74.00912267, 40.71227386 ] ] ] } }, { "type": "Feature", "properties": { "height": 204.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00904102, 40.71223457 ], [ -74.00903491, 40.71224247 ], [ -74.00901667, 40.71224567 ], [ -74.00901479, 40.71223301 ], [ -74.00902134, 40.71222531 ], [ -74.00904102, 40.71223457 ] ] ] } }, { "type": "Feature", "properties": { "height": 204.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00930925, 40.71230709 ], [ -74.00929174, 40.71230716 ], [ -74.00928167, 40.71230226 ], [ -74.00929317, 40.71228857 ], [ -74.00930332, 40.7122932 ], [ -74.00930925, 40.71230709 ] ] ] } }, { "type": "Feature", "properties": { "height": 204.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00900904, 40.71215552 ], [ -74.00899727, 40.71216968 ], [ -74.00898828, 40.71216512 ], [ -74.00898164, 40.71215028 ], [ -74.00899978, 40.71215096 ], [ -74.00900904, 40.71215552 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01002054, 40.70748901 ], [ -74.01002009, 40.70749187 ], [ -74.01001829, 40.7074946 ], [ -74.01001533, 40.70749657 ], [ -74.01001165, 40.70749766 ], [ -74.0100076, 40.7074976 ], [ -74.01000392, 40.70749651 ], [ -74.01000105, 40.70749446 ], [ -74.00999934, 40.70749167 ], [ -74.00999898, 40.70748867 ], [ -74.01000015, 40.70748588 ], [ -74.01000257, 40.7074835 ], [ -74.01000599, 40.70748186 ], [ -74.01000994, 40.70748139 ], [ -74.0100138, 40.707482 ], [ -74.01001713, 40.70748357 ], [ -74.01001955, 40.70748602 ], [ -74.01002054, 40.70748901 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01019643, 40.70758857 ], [ -74.01019598, 40.70759157 ], [ -74.01019418, 40.70759429 ], [ -74.01019122, 40.70759627 ], [ -74.01018754, 40.70759736 ], [ -74.01018349, 40.70759736 ], [ -74.01017981, 40.7075962 ], [ -74.01017694, 40.70759416 ], [ -74.01017523, 40.7075915 ], [ -74.01017478, 40.7075885 ], [ -74.01017604, 40.70758558 ], [ -74.01017837, 40.70758319 ], [ -74.01018179, 40.70758156 ], [ -74.01018574, 40.70758108 ], [ -74.0101896, 40.70758169 ], [ -74.01019302, 40.70758326 ], [ -74.01019544, 40.70758571 ], [ -74.01019643, 40.70758857 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01039379, 40.70710536 ], [ -74.01039343, 40.70710842 ], [ -74.01039163, 40.70711108 ], [ -74.01038858, 40.70711312 ], [ -74.0103849, 40.70711421 ], [ -74.01038094, 40.70711407 ], [ -74.01037717, 40.70711298 ], [ -74.0103743, 40.70711087 ], [ -74.0103725, 40.70710822 ], [ -74.01037223, 40.70710522 ], [ -74.0103734, 40.70710229 ], [ -74.01037582, 40.70709991 ], [ -74.01037924, 40.70709841 ], [ -74.01038319, 40.7070978 ], [ -74.01038714, 40.70709841 ], [ -74.01039038, 40.70710011 ], [ -74.0103928, 40.7071025 ], [ -74.01039379, 40.70710536 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01009097, 40.70752878 ], [ -74.01009061, 40.70753178 ], [ -74.01008881, 40.7075345 ], [ -74.01008585, 40.70753648 ], [ -74.01008207, 40.70753757 ], [ -74.01007812, 40.7075375 ], [ -74.01007444, 40.70753641 ], [ -74.01007147, 40.70753437 ], [ -74.01006977, 40.70753158 ], [ -74.0100695, 40.70752858 ], [ -74.01007058, 40.70752572 ], [ -74.010073, 40.70752327 ], [ -74.0100765, 40.70752177 ], [ -74.01008037, 40.70752129 ], [ -74.01008432, 40.70752191 ], [ -74.01008764, 40.70752347 ], [ -74.01008998, 40.70752586 ], [ -74.01009097, 40.70752878 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00998524, 40.7074692 ], [ -74.00998479, 40.70747219 ], [ -74.00998299, 40.70747492 ], [ -74.00998002, 40.70747689 ], [ -74.00997634, 40.70747798 ], [ -74.0099723, 40.70747798 ], [ -74.00996862, 40.70747676 ], [ -74.00996574, 40.70747478 ], [ -74.00996395, 40.70747206 ], [ -74.00996359, 40.70746906 ], [ -74.00996475, 40.7074662 ], [ -74.00996709, 40.70746382 ], [ -74.0099705, 40.70746218 ], [ -74.00997437, 40.70746171 ], [ -74.00997832, 40.70746218 ], [ -74.00998173, 40.70746389 ], [ -74.00998407, 40.70746627 ], [ -74.00998524, 40.7074692 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01053509, 40.70718469 ], [ -74.01053473, 40.70718769 ], [ -74.01053285, 40.70719041 ], [ -74.01052979, 40.70719238 ], [ -74.01052611, 40.70719341 ], [ -74.01052207, 40.70719341 ], [ -74.01051839, 40.70719218 ], [ -74.01051551, 40.70719021 ], [ -74.0105138, 40.70718741 ], [ -74.01051353, 40.70718442 ], [ -74.0105147, 40.70718149 ], [ -74.01051713, 40.70717917 ], [ -74.01052063, 40.70717761 ], [ -74.01052449, 40.70717706 ], [ -74.01052845, 40.70717768 ], [ -74.01053168, 40.70717938 ], [ -74.01053411, 40.70718176 ], [ -74.01053509, 40.70718469 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01042918, 40.70712531 ], [ -74.01042882, 40.70712831 ], [ -74.01042703, 40.70713096 ], [ -74.01042415, 40.707133 ], [ -74.01042038, 40.70713409 ], [ -74.01041643, 40.70713409 ], [ -74.01041274, 40.707133 ], [ -74.01040978, 40.70713089 ], [ -74.01040798, 40.70712817 ], [ -74.01040762, 40.70712517 ], [ -74.0104087, 40.70712231 ], [ -74.01041113, 40.70711986 ], [ -74.01041454, 40.70711836 ], [ -74.0104184, 40.70711782 ], [ -74.01042227, 40.70711836 ], [ -74.01042568, 40.70711986 ], [ -74.0104281, 40.70712238 ], [ -74.01042918, 40.70712531 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01035849, 40.70708568 ], [ -74.01035804, 40.70708867 ], [ -74.01035624, 40.7070914 ], [ -74.01035319, 40.70709337 ], [ -74.0103495, 40.70709446 ], [ -74.01034555, 40.70709439 ], [ -74.01034178, 40.7070933 ], [ -74.0103389, 40.70709119 ], [ -74.01033711, 40.70708847 ], [ -74.01033684, 40.7070854 ], [ -74.010338, 40.70708248 ], [ -74.01034043, 40.70708016 ], [ -74.01034393, 40.70707859 ], [ -74.0103478, 40.70707812 ], [ -74.01035175, 40.70707866 ], [ -74.01035507, 40.7070803 ], [ -74.01035741, 40.70708282 ], [ -74.01035849, 40.70708568 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01016184, 40.70756808 ], [ -74.01016139, 40.70757121 ], [ -74.0101596, 40.7075738 ], [ -74.01015672, 40.70757591 ], [ -74.01015304, 40.707577 ], [ -74.010149, 40.70757686 ], [ -74.01014531, 40.70757591 ], [ -74.01014235, 40.7075738 ], [ -74.01014064, 40.70757107 ], [ -74.01014019, 40.70756808 ], [ -74.01014127, 40.70756522 ], [ -74.0101437, 40.70756276 ], [ -74.01014711, 40.7075612 ], [ -74.01015097, 40.70756072 ], [ -74.01015493, 40.7075612 ], [ -74.01015834, 40.70756276 ], [ -74.01016068, 40.70756522 ], [ -74.01016184, 40.70756808 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01005602, 40.7075089 ], [ -74.01005557, 40.7075119 ], [ -74.01005378, 40.70751462 ], [ -74.01005081, 40.70751659 ], [ -74.01004713, 40.70751768 ], [ -74.01004309, 40.70751762 ], [ -74.0100394, 40.70751646 ], [ -74.01003644, 40.70751448 ], [ -74.01003473, 40.70751176 ], [ -74.01003428, 40.70750869 ], [ -74.01003554, 40.70750577 ], [ -74.01003788, 40.70750338 ], [ -74.01004129, 40.70750189 ], [ -74.01004524, 40.70750127 ], [ -74.01004911, 40.70750189 ], [ -74.01005252, 40.70750352 ], [ -74.01005494, 40.7075059 ], [ -74.01005602, 40.7075089 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01056959, 40.70720498 ], [ -74.01056923, 40.70720798 ], [ -74.01056743, 40.7072107 ], [ -74.01056447, 40.70721268 ], [ -74.0105607, 40.70721377 ], [ -74.01055674, 40.70721377 ], [ -74.01055297, 40.70721268 ], [ -74.0105501, 40.70721057 ], [ -74.01054839, 40.70720791 ], [ -74.01054803, 40.70720491 ], [ -74.01054911, 40.70720199 ], [ -74.01055162, 40.7071996 ], [ -74.01055504, 40.70719811 ], [ -74.0105589, 40.70719749 ], [ -74.01056285, 40.70719811 ], [ -74.01056618, 40.70719967 ], [ -74.01056851, 40.70720205 ], [ -74.01056959, 40.70720498 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0103221, 40.7070662 ], [ -74.01032174, 40.7070692 ], [ -74.01031995, 40.70707192 ], [ -74.01031689, 40.7070739 ], [ -74.01031321, 40.70707499 ], [ -74.01030917, 40.70707492 ], [ -74.01030548, 40.70707376 ], [ -74.01030261, 40.70707172 ], [ -74.01030081, 40.70706899 ], [ -74.01030054, 40.707066 ], [ -74.01030162, 40.70706307 ], [ -74.01030414, 40.70706069 ], [ -74.01030755, 40.70705919 ], [ -74.01031141, 40.70705857 ], [ -74.01031528, 40.70705919 ], [ -74.01031869, 40.70706082 ], [ -74.01032112, 40.70706327 ], [ -74.0103221, 40.7070662 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0104997, 40.70716501 ], [ -74.01049934, 40.70716801 ], [ -74.01049754, 40.70717066 ], [ -74.01049449, 40.7071727 ], [ -74.01049081, 40.70717366 ], [ -74.01048676, 40.70717366 ], [ -74.01048308, 40.70717257 ], [ -74.01048021, 40.70717046 ], [ -74.01047841, 40.7071678 ], [ -74.01047814, 40.70716481 ], [ -74.01047931, 40.70716188 ], [ -74.01048173, 40.70715949 ], [ -74.01048515, 40.70715786 ], [ -74.01048901, 40.70715738 ], [ -74.01049287, 40.707158 ], [ -74.01049629, 40.70715956 ], [ -74.01049871, 40.70716208 ], [ -74.0104997, 40.70716501 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00994885, 40.70744979 ], [ -74.0099484, 40.70745272 ], [ -74.00994661, 40.70745538 ], [ -74.00994364, 40.70745742 ], [ -74.00993987, 40.70745851 ], [ -74.00993592, 40.70745837 ], [ -74.00993223, 40.70745728 ], [ -74.00992927, 40.70745531 ], [ -74.00992765, 40.70745251 ], [ -74.00992729, 40.70744952 ], [ -74.00992837, 40.70744666 ], [ -74.00993089, 40.70744428 ], [ -74.0099343, 40.70744271 ], [ -74.00993825, 40.70744216 ], [ -74.00994212, 40.70744278 ], [ -74.00994544, 40.70744441 ], [ -74.00994778, 40.70744679 ], [ -74.00994885, 40.70744979 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01046431, 40.70714526 ], [ -74.01046395, 40.70714826 ], [ -74.01046215, 40.70715098 ], [ -74.0104591, 40.70715296 ], [ -74.01045532, 40.70715398 ], [ -74.01045137, 40.70715398 ], [ -74.01044769, 40.70715289 ], [ -74.01044472, 40.70715078 ], [ -74.01044302, 40.70714812 ], [ -74.01044275, 40.70714506 ], [ -74.01044383, 40.7071422 ], [ -74.01044625, 40.70713981 ], [ -74.01044966, 40.70713818 ], [ -74.01045362, 40.7071377 ], [ -74.01045748, 40.70713832 ], [ -74.01046089, 40.70713988 ], [ -74.01046323, 40.7071424 ], [ -74.01046431, 40.70714526 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01012645, 40.70754846 ], [ -74.010126, 40.70755146 ], [ -74.0101242, 40.70755418 ], [ -74.01012124, 40.70755616 ], [ -74.01011747, 40.70755732 ], [ -74.01011351, 40.70755732 ], [ -74.01010983, 40.70755609 ], [ -74.01010687, 40.70755412 ], [ -74.01010525, 40.70755139 ], [ -74.0101048, 40.7075484 ], [ -74.01010597, 40.70754547 ], [ -74.01010839, 40.70754308 ], [ -74.01011181, 40.70754152 ], [ -74.01011567, 40.70754097 ], [ -74.01011962, 40.70754159 ], [ -74.01012304, 40.70754322 ], [ -74.01012528, 40.7075456 ], [ -74.01012645, 40.70754846 ] ] ] } }, { "type": "Feature", "properties": { "height": 290.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00768752, 40.70643718 ], [ -74.00767872, 40.70644577 ], [ -74.00766273, 40.7064365 ], [ -74.00767144, 40.70642779 ], [ -74.00768752, 40.70643718 ] ] ] } }, { "type": "Feature", "properties": { "height": 204.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00920119, 40.71217547 ], [ -74.00919508, 40.7121831 ], [ -74.00917738, 40.71217458 ], [ -74.00918412, 40.71216716 ], [ -74.00919858, 40.71216492 ], [ -74.00920119, 40.71217547 ] ] ] } }, { "type": "Feature", "properties": { "height": 204.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00928311, 40.71221469 ], [ -74.00927754, 40.71222232 ], [ -74.00925931, 40.71221346 ], [ -74.00926577, 40.71220638 ], [ -74.00928069, 40.712204 ], [ -74.00928311, 40.71221469 ] ] ] } }, { "type": "Feature", "properties": { "height": 204.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00911962, 40.71213632 ], [ -74.00911342, 40.71214401 ], [ -74.00909563, 40.71213536 ], [ -74.0091021, 40.71212787 ], [ -74.00911612, 40.71212549 ], [ -74.00911962, 40.71213632 ] ] ] } }, { "type": "Feature", "properties": { "height": 63.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01409161, 40.70801629 ], [ -74.01406907, 40.70800886 ], [ -74.01407401, 40.70800021 ], [ -74.01409664, 40.70800771 ], [ -74.01409161, 40.70801629 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00849771, 40.70772851 ], [ -74.00848927, 40.70773586 ], [ -74.00848119, 40.70773069 ], [ -74.00848954, 40.70772327 ], [ -74.00849771, 40.70772851 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00873945, 40.7078852 ], [ -74.00873101, 40.70789255 ], [ -74.00872283, 40.70788731 ], [ -74.00873119, 40.70787989 ], [ -74.00873945, 40.7078852 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00881994, 40.70793736 ], [ -74.00881159, 40.70794478 ], [ -74.0088035, 40.70793947 ], [ -74.00881177, 40.70793212 ], [ -74.00881994, 40.70793736 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0085782, 40.70778067 ], [ -74.00856985, 40.70778809 ], [ -74.00856167, 40.70778278 ], [ -74.00857003, 40.70777536 ], [ -74.0085782, 40.70778067 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00906159, 40.70809398 ], [ -74.00905323, 40.70810147 ], [ -74.00904497, 40.70809616 ], [ -74.00905341, 40.70808867 ], [ -74.00906159, 40.70809398 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00899062, 40.70766239 ], [ -74.00898245, 40.70765721 ], [ -74.0089908, 40.70764965 ], [ -74.00899889, 40.70765497 ], [ -74.00899062, 40.70766239 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00922284, 40.70819851 ], [ -74.00921448, 40.70820587 ], [ -74.00920631, 40.70820062 ], [ -74.00921475, 40.7081932 ], [ -74.00922284, 40.70819851 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00914235, 40.70814628 ], [ -74.00913399, 40.7081537 ], [ -74.00912582, 40.70814839 ], [ -74.00913408, 40.70814111 ], [ -74.00914235, 40.70814628 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00931285, 40.70787131 ], [ -74.00930467, 40.707866 ], [ -74.00931312, 40.70785857 ], [ -74.0093212, 40.70786389 ], [ -74.00931285, 40.70787131 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0089811, 40.70804189 ], [ -74.00897274, 40.70804931 ], [ -74.00896448, 40.70804407 ], [ -74.00897301, 40.70803658 ], [ -74.0089811, 40.70804189 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.009474, 40.70797577 ], [ -74.00946592, 40.70797046 ], [ -74.00947418, 40.7079631 ], [ -74.00948245, 40.70796841 ], [ -74.009474, 40.70797577 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00865869, 40.7078329 ], [ -74.00865043, 40.70784026 ], [ -74.00864216, 40.70783501 ], [ -74.00865061, 40.70782759 ], [ -74.00865869, 40.7078329 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00939351, 40.70792361 ], [ -74.00938543, 40.7079183 ], [ -74.00939369, 40.70791087 ], [ -74.00940187, 40.70791618 ], [ -74.00939351, 40.70792361 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00874879, 40.7075057 ], [ -74.00874071, 40.70750046 ], [ -74.00874897, 40.7074931 ], [ -74.00875724, 40.70749828 ], [ -74.00874879, 40.7075057 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00882937, 40.707558 ], [ -74.00882129, 40.70755269 ], [ -74.00882964, 40.70754526 ], [ -74.00883782, 40.70755057 ], [ -74.00882937, 40.707558 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0090712, 40.70771469 ], [ -74.00906302, 40.70770938 ], [ -74.00907138, 40.70770202 ], [ -74.00907955, 40.70770726 ], [ -74.0090712, 40.70771469 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00890052, 40.70798959 ], [ -74.00889208, 40.70799701 ], [ -74.00888399, 40.7079917 ], [ -74.00889234, 40.70798428 ], [ -74.00890052, 40.70798959 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00891004, 40.70761016 ], [ -74.00890187, 40.70760498 ], [ -74.00891022, 40.70759756 ], [ -74.00891831, 40.70760287 ], [ -74.00891004, 40.70761016 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00915169, 40.70776692 ], [ -74.0091436, 40.70776161 ], [ -74.00915187, 40.70775418 ], [ -74.00916013, 40.70775949 ], [ -74.00915169, 40.70776692 ] ] ] } }, { "type": "Feature", "properties": { "height": 248.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00923227, 40.70781908 ], [ -74.00922409, 40.70781377 ], [ -74.00923254, 40.70780641 ], [ -74.00924071, 40.70781159 ], [ -74.00923227, 40.70781908 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01057615, 40.71067832 ], [ -74.01056734, 40.71068962 ], [ -74.01055234, 40.71068281 ], [ -74.01057615, 40.71067832 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01080243, 40.71038987 ], [ -74.01079354, 40.71040131 ], [ -74.01078698, 40.71038286 ], [ -74.01080243, 40.71038987 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01041697, 40.71076296 ], [ -74.01040187, 40.71075621 ], [ -74.01040708, 40.71074961 ], [ -74.010422, 40.71075649 ], [ -74.01041697, 40.71076296 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01052692, 40.7102656 ], [ -74.01052198, 40.71027186 ], [ -74.01050698, 40.71026506 ], [ -74.01051192, 40.71025886 ], [ -74.01052692, 40.7102656 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01034797, 40.7107317 ], [ -74.01033297, 40.71072489 ], [ -74.01033818, 40.71071829 ], [ -74.01035319, 40.71072516 ], [ -74.01034797, 40.7107317 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01036091, 40.71059599 ], [ -74.01034591, 40.71058918 ], [ -74.01035112, 40.71058258 ], [ -74.01036603, 40.71058952 ], [ -74.01036091, 40.71059599 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01049844, 40.7106583 ], [ -74.01048344, 40.71065149 ], [ -74.01048847, 40.71064502 ], [ -74.01050347, 40.7106519 ], [ -74.01049844, 40.7106583 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01071215, 40.71050481 ], [ -74.01070317, 40.71051612 ], [ -74.01069437, 40.71051217 ], [ -74.01070335, 40.7105008 ], [ -74.01071215, 40.71050481 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01067182, 40.71019928 ], [ -74.0106667, 40.71020581 ], [ -74.0106517, 40.710199 ], [ -74.01065691, 40.7101924 ], [ -74.01067182, 40.71019928 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01066445, 40.71032757 ], [ -74.01065933, 40.71033417 ], [ -74.01064433, 40.71032736 ], [ -74.01064945, 40.71032089 ], [ -74.01066445, 40.71032757 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01029237, 40.71056501 ], [ -74.01027737, 40.7105582 ], [ -74.01028258, 40.71055146 ], [ -74.01029749, 40.7105584 ], [ -74.01029237, 40.71056501 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01060328, 40.71016829 ], [ -74.01059825, 40.71017469 ], [ -74.01058324, 40.71016802 ], [ -74.01058836, 40.71016128 ], [ -74.01060328, 40.71016829 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01027943, 40.71070058 ], [ -74.01026443, 40.71069377 ], [ -74.01026964, 40.7106871 ], [ -74.01028446, 40.71069398 ], [ -74.01027943, 40.71070058 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01074063, 40.71023046 ], [ -74.01073551, 40.710237 ], [ -74.01072051, 40.71023019 ], [ -74.01072572, 40.71022359 ], [ -74.01074063, 40.71023046 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01080917, 40.71026172 ], [ -74.01080423, 40.71026812 ], [ -74.01078914, 40.71026131 ], [ -74.01079435, 40.71025477 ], [ -74.01080917, 40.71026172 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01059555, 40.71029658 ], [ -74.01059052, 40.71030292 ], [ -74.01057552, 40.71029611 ], [ -74.01058055, 40.71028977 ], [ -74.01059555, 40.71029658 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01021062, 40.7106694 ], [ -74.01019562, 40.71066259 ], [ -74.01020083, 40.71065591 ], [ -74.01021574, 40.71066279 ], [ -74.01021062, 40.7106694 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01075779, 40.71044687 ], [ -74.01074889, 40.71045831 ], [ -74.01074018, 40.71045436 ], [ -74.01074907, 40.71044298 ], [ -74.01075779, 40.71044687 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01073317, 40.71035868 ], [ -74.01072805, 40.71036529 ], [ -74.01071287, 40.71035848 ], [ -74.01071808, 40.71035188 ], [ -74.01073317, 40.71035868 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01042972, 40.71062718 ], [ -74.01041472, 40.71062037 ], [ -74.01041993, 40.71061376 ], [ -74.01043484, 40.71062071 ], [ -74.01042972, 40.71062718 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01062178, 40.71062037 ], [ -74.0106128, 40.71063181 ], [ -74.01060408, 40.71062786 ], [ -74.01061298, 40.71061649 ], [ -74.01062178, 40.71062037 ] ] ] } }, { "type": "Feature", "properties": { "height": 141.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01066679, 40.71056256 ], [ -74.01065789, 40.710574 ], [ -74.01064909, 40.71056998 ], [ -74.01065798, 40.71055868 ], [ -74.01066679, 40.71056256 ] ] ] } }, { "type": "Feature", "properties": { "height": 160.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0090933, 40.70650018 ], [ -74.00909258, 40.70650399 ], [ -74.00908863, 40.7065063 ], [ -74.00908369, 40.70650576 ], [ -74.00908063, 40.70650276 ], [ -74.00908135, 40.70649902 ], [ -74.0090853, 40.7064967 ], [ -74.00909033, 40.70649718 ], [ -74.0090933, 40.70650018 ] ] ] } }, { "type": "Feature", "properties": { "height": 33.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00601953, 40.71272858 ], [ -74.00601405, 40.71273219 ], [ -74.00601001, 40.71272899 ], [ -74.00601477, 40.71272517 ], [ -74.00601953, 40.71272858 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01193233, 40.70809848 ], [ -74.01193359, 40.70809691 ], [ -74.01193889, 40.70809596 ], [ -74.01194123, 40.70809712 ], [ -74.01194338, 40.70809807 ], [ -74.01194455, 40.70810202 ], [ -74.01194248, 40.7081044 ], [ -74.01193727, 40.70810536 ], [ -74.01193269, 40.70810318 ], [ -74.01193161, 40.70809929 ], [ -74.01193233, 40.70809848 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01206142, 40.70783842 ], [ -74.01205945, 40.7078374 ], [ -74.01205828, 40.70783352 ], [ -74.01206025, 40.70783106 ], [ -74.01206555, 40.70783018 ], [ -74.01206744, 40.70783106 ], [ -74.01207014, 40.70783229 ], [ -74.01207112, 40.70783617 ], [ -74.01206915, 40.70783869 ], [ -74.01206394, 40.70783958 ], [ -74.01206142, 40.70783842 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01187709, 40.70807246 ], [ -74.01187619, 40.70807349 ], [ -74.01187107, 40.7080741 ], [ -74.01186658, 40.70807199 ], [ -74.01186541, 40.70806831 ], [ -74.0118673, 40.708066 ], [ -74.0118726, 40.70806497 ], [ -74.01187475, 40.708066 ], [ -74.01187709, 40.70806722 ], [ -74.01187817, 40.7080711 ], [ -74.01187709, 40.70807246 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01210391, 40.70779606 ], [ -74.01210301, 40.70779729 ], [ -74.01209771, 40.70779817 ], [ -74.01209529, 40.70779708 ], [ -74.01209322, 40.70779606 ], [ -74.01209214, 40.70779211 ], [ -74.01209412, 40.7077898 ], [ -74.01209942, 40.70778878 ], [ -74.01210391, 40.70779095 ], [ -74.01210499, 40.7077949 ], [ -74.01210391, 40.70779606 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01215817, 40.70808418 ], [ -74.01215619, 40.7080867 ], [ -74.01215098, 40.70808758 ], [ -74.0121464, 40.7080854 ], [ -74.01214532, 40.70808152 ], [ -74.0121473, 40.70807907 ], [ -74.0121526, 40.70807818 ], [ -74.01215709, 40.7080803 ], [ -74.01215817, 40.70808418 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0120908, 40.70790856 ], [ -74.01208882, 40.70791101 ], [ -74.01208361, 40.70791196 ], [ -74.01207912, 40.70790978 ], [ -74.01207804, 40.70790577 ], [ -74.01207993, 40.70790352 ], [ -74.01208523, 40.7079025 ], [ -74.01208972, 40.70790468 ], [ -74.0120908, 40.70790856 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01205774, 40.70803767 ], [ -74.01205567, 40.70804012 ], [ -74.01205055, 40.70804107 ], [ -74.01204597, 40.70803889 ], [ -74.01204489, 40.70803488 ], [ -74.01204678, 40.70803256 ], [ -74.01205208, 40.70803161 ], [ -74.01205657, 40.70803379 ], [ -74.01205774, 40.70803767 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01224117, 40.70797876 ], [ -74.0122392, 40.70798122 ], [ -74.01223399, 40.70798217 ], [ -74.0122295, 40.70797999 ], [ -74.01222833, 40.70797597 ], [ -74.0122303, 40.70797366 ], [ -74.0122356, 40.7079727 ], [ -74.0122401, 40.70797488 ], [ -74.01224117, 40.70797876 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01225833, 40.70813157 ], [ -74.01225627, 40.70813396 ], [ -74.01225115, 40.70813491 ], [ -74.01224656, 40.7081328 ], [ -74.01224549, 40.70812878 ], [ -74.01224737, 40.70812647 ], [ -74.01225267, 40.70812551 ], [ -74.01225716, 40.70812769 ], [ -74.01225833, 40.70813157 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01220821, 40.70810801 ], [ -74.01220623, 40.70811039 ], [ -74.01220102, 40.70811128 ], [ -74.01219644, 40.70810917 ], [ -74.01219527, 40.70810522 ], [ -74.01219734, 40.7081029 ], [ -74.01220264, 40.70810188 ], [ -74.01220713, 40.70810406 ], [ -74.01220821, 40.70810801 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01210751, 40.70806096 ], [ -74.01210553, 40.70806341 ], [ -74.01210032, 40.70806429 ], [ -74.01209583, 40.70806218 ], [ -74.01209475, 40.70805816 ], [ -74.01209664, 40.70805592 ], [ -74.01210194, 40.7080549 ], [ -74.01210643, 40.70805708 ], [ -74.01210751, 40.70806096 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01230891, 40.70815452 ], [ -74.01230693, 40.7081569 ], [ -74.01230172, 40.70815786 ], [ -74.01229723, 40.70815568 ], [ -74.01229597, 40.70815166 ], [ -74.01229804, 40.70814941 ], [ -74.01230334, 40.70814839 ], [ -74.01230783, 40.70815057 ], [ -74.01230891, 40.70815452 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01214074, 40.70793191 ], [ -74.01213868, 40.7079343 ], [ -74.01213347, 40.70793532 ], [ -74.01212897, 40.70793307 ], [ -74.01212781, 40.70792919 ], [ -74.01212978, 40.70792681 ], [ -74.01213508, 40.70792592 ], [ -74.01213957, 40.70792796 ], [ -74.01214074, 40.70793191 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01229238, 40.70800239 ], [ -74.0122904, 40.70800491 ], [ -74.01228519, 40.7080058 ], [ -74.01228061, 40.70800362 ], [ -74.01227953, 40.70799967 ], [ -74.01228151, 40.70799729 ], [ -74.01228681, 40.7079964 ], [ -74.0122913, 40.70799851 ], [ -74.01229238, 40.70800239 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01239344, 40.70804986 ], [ -74.01239137, 40.70805231 ], [ -74.01238625, 40.70805319 ], [ -74.01238167, 40.70805101 ], [ -74.01238059, 40.70804707 ], [ -74.01238248, 40.70804482 ], [ -74.01238778, 40.7080438 ], [ -74.01239245, 40.70804598 ], [ -74.01239344, 40.70804986 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01200644, 40.70801336 ], [ -74.01200438, 40.70801581 ], [ -74.01199917, 40.70801676 ], [ -74.01199468, 40.70801458 ], [ -74.01199351, 40.7080107 ], [ -74.01199549, 40.70800832 ], [ -74.01200079, 40.70800736 ], [ -74.01200528, 40.70800948 ], [ -74.01200644, 40.70801336 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01219159, 40.70795568 ], [ -74.01218961, 40.70795806 ], [ -74.0121844, 40.70795908 ], [ -74.01217991, 40.70795691 ], [ -74.01217883, 40.70795289 ], [ -74.01218072, 40.70795057 ], [ -74.01218602, 40.70794962 ], [ -74.01219051, 40.7079518 ], [ -74.01219159, 40.70795568 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01191212, 40.70803018 ], [ -74.01190997, 40.7080327 ], [ -74.01190485, 40.70803358 ], [ -74.01190035, 40.7080314 ], [ -74.01189919, 40.70802752 ], [ -74.01190107, 40.70802507 ], [ -74.01190637, 40.70802418 ], [ -74.01191104, 40.7080263 ], [ -74.01191212, 40.70803018 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01217138, 40.70782589 ], [ -74.0121694, 40.70782827 ], [ -74.01216419, 40.70782916 ], [ -74.0121597, 40.70782711 ], [ -74.01215862, 40.7078231 ], [ -74.01216051, 40.70782078 ], [ -74.01216581, 40.70781976 ], [ -74.0121703, 40.70782201 ], [ -74.01217138, 40.70782589 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01234268, 40.70802589 ], [ -74.01234071, 40.70802827 ], [ -74.0123355, 40.70802929 ], [ -74.01233101, 40.70802711 ], [ -74.01232993, 40.70802316 ], [ -74.01233181, 40.70802078 ], [ -74.01233711, 40.70801989 ], [ -74.0123417, 40.70802201 ], [ -74.01234268, 40.70802589 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00905997, 40.71114319 ], [ -74.00905763, 40.7111455 ], [ -74.00905377, 40.71114612 ], [ -74.00905045, 40.71114469 ], [ -74.00904901, 40.71114196 ], [ -74.00905018, 40.71113931 ], [ -74.00905341, 40.71113767 ], [ -74.00905719, 40.71113808 ], [ -74.00905979, 40.71114019 ], [ -74.00905997, 40.71114319 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0089669, 40.71125268 ], [ -74.00896457, 40.711255 ], [ -74.0089608, 40.71125561 ], [ -74.00895738, 40.71125432 ], [ -74.00895604, 40.71125159 ], [ -74.00895711, 40.7112488 ], [ -74.00896044, 40.71124717 ], [ -74.00896421, 40.71124757 ], [ -74.00896682, 40.71124982 ], [ -74.0089669, 40.71125268 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00902979, 40.71117989 ], [ -74.00902754, 40.71118221 ], [ -74.00902368, 40.71118282 ], [ -74.00902026, 40.71118139 ], [ -74.00901892, 40.71117866 ], [ -74.00902, 40.71117601 ], [ -74.00902332, 40.71117437 ], [ -74.00902709, 40.71117478 ], [ -74.0090297, 40.71117696 ], [ -74.00902979, 40.71117989 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00946655, 40.71141331 ], [ -74.00946484, 40.71141501 ], [ -74.00946197, 40.71141536 ], [ -74.00945954, 40.7114144 ], [ -74.00945837, 40.71141236 ], [ -74.00945927, 40.71141038 ], [ -74.0094617, 40.71140916 ], [ -74.00946448, 40.7114095 ], [ -74.00946637, 40.71141107 ], [ -74.00946655, 40.71141331 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00942558, 40.71146166 ], [ -74.00942379, 40.71146336 ], [ -74.009421, 40.71146377 ], [ -74.00941849, 40.71146282 ], [ -74.00941741, 40.71146077 ], [ -74.00941831, 40.7114588 ], [ -74.00942073, 40.71145757 ], [ -74.00942352, 40.71145791 ], [ -74.00942549, 40.71145948 ], [ -74.00942558, 40.71146166 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00893492, 40.71128938 ], [ -74.0089325, 40.7112917 ], [ -74.00892882, 40.71129231 ], [ -74.0089254, 40.71129102 ], [ -74.00892388, 40.71128829 ], [ -74.00892513, 40.7112855 ], [ -74.00892828, 40.711284 ], [ -74.00893214, 40.71128441 ], [ -74.00893475, 40.71128646 ], [ -74.00893492, 40.71128938 ] ] ] } }, { "type": "Feature", "properties": { "height": 108.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.01124674, 40.7085919 ], [ -74.01124593, 40.70859292 ], [ -74.01124449, 40.70859319 ], [ -74.01124315, 40.70859258 ], [ -74.0112427, 40.70859149 ], [ -74.01124351, 40.70859047 ], [ -74.01124503, 40.7085902 ], [ -74.01124629, 40.70859067 ], [ -74.01124674, 40.7085919 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00643779, 40.70937901 ], [ -74.0064377, 40.70937949 ], [ -74.00643725, 40.7093799 ], [ -74.00643662, 40.7093801 ], [ -74.0064359, 40.7093801 ], [ -74.00643527, 40.70937976 ], [ -74.006435, 40.70937942 ], [ -74.00643491, 40.70937888 ], [ -74.00643518, 40.7093784 ], [ -74.00643581, 40.70937806 ], [ -74.00643644, 40.70937799 ], [ -74.00643707, 40.70937806 ], [ -74.00643761, 40.70937847 ], [ -74.00643779, 40.70937901 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00193175, 40.71203432 ], [ -74.0021716, 40.71214129 ], [ -74.00202814, 40.71232602 ], [ -74.00215687, 40.71238349 ], [ -74.00209569, 40.71246227 ], [ -74.00198673, 40.71260261 ], [ -74.00185791, 40.71254507 ], [ -74.00182988, 40.71258109 ], [ -74.0015894, 40.71247378 ], [ -74.0014569, 40.71264428 ], [ -74.0013756, 40.71260799 ], [ -74.00126951, 40.7125606 ], [ -74.00122298, 40.71262052 ], [ -74.00102472, 40.712532 ], [ -74.00129439, 40.71218487 ], [ -74.00101987, 40.7120623 ], [ -74.00119028, 40.71184291 ], [ -74.00134488, 40.71191189 ], [ -74.00137758, 40.71192646 ], [ -74.00143184, 40.71185666 ], [ -74.00157161, 40.71191917 ], [ -74.00159793, 40.71188526 ], [ -74.00183509, 40.71199108 ], [ -74.00202661, 40.71174458 ], [ -74.00211941, 40.71178598 ], [ -74.00214708, 40.7117503 ], [ -74.00224409, 40.71179347 ], [ -74.00226817, 40.71176235 ], [ -74.00255644, 40.71189098 ], [ -74.00252787, 40.71192768 ], [ -74.00261923, 40.7119684 ], [ -74.00259102, 40.71200456 ], [ -74.00268508, 40.71204657 ], [ -74.00254503, 40.71222702 ], [ -74.00246265, 40.7123331 ], [ -74.00235863, 40.7122866 ], [ -74.00244541, 40.71217486 ], [ -74.00240408, 40.7121564 ], [ -74.00236339, 40.71220877 ], [ -74.00217043, 40.7121227 ], [ -74.00221939, 40.71205971 ], [ -74.00218121, 40.71204269 ], [ -74.0021407, 40.71209478 ], [ -74.00195061, 40.71201001 ], [ -74.00193175, 40.71203432 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00392475, 40.71026928 ], [ -74.00340597, 40.71066517 ], [ -74.00258743, 40.71004879 ], [ -74.00310621, 40.70965289 ], [ -74.00392475, 40.71026928 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00412283, 40.71285829 ], [ -74.00394038, 40.7130497 ], [ -74.0038422, 40.7131536 ], [ -74.00367538, 40.7133369 ], [ -74.00349311, 40.71353198 ], [ -74.00323143, 40.71339029 ], [ -74.00324095, 40.71338007 ], [ -74.00320439, 40.71304398 ], [ -74.00318795, 40.71303506 ], [ -74.00327284, 40.71294429 ], [ -74.00326152, 40.71293809 ], [ -74.00328264, 40.71291556 ], [ -74.00330428, 40.71289138 ], [ -74.00339933, 40.71278108 ], [ -74.00345853, 40.71272742 ], [ -74.00347155, 40.71273437 ], [ -74.00355572, 40.71264428 ], [ -74.00357171, 40.71265286 ], [ -74.00404225, 40.7125303 ], [ -74.00404917, 40.71252287 ], [ -74.00408052, 40.7125399 ], [ -74.00430627, 40.71266198 ], [ -74.00412283, 40.71285829 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0022052, 40.7142359 ], [ -74.00207207, 40.71459317 ], [ -74.00192178, 40.71456075 ], [ -74.00190669, 40.71460127 ], [ -74.00187201, 40.71459378 ], [ -74.00134704, 40.71469741 ], [ -74.00133428, 40.71469639 ], [ -74.00132646, 40.71469326 ], [ -74.00126951, 40.71464879 ], [ -74.00093785, 40.71438699 ], [ -74.00093345, 40.71437542 ], [ -74.00108599, 40.71396599 ], [ -74.00109838, 40.71395796 ], [ -74.00163881, 40.7138531 ], [ -74.00165471, 40.7138565 ], [ -74.00203488, 40.7141563 ], [ -74.00206964, 40.71416379 ], [ -74.00205482, 40.71420349 ], [ -74.0022052, 40.7142359 ] ], [ [ -74.00159838, 40.7142805 ], [ -74.00159758, 40.71426368 ], [ -74.00159398, 40.71425149 ], [ -74.00158545, 40.71423597 ], [ -74.00157269, 40.71422228 ], [ -74.00155661, 40.71421091 ], [ -74.0015417, 40.71420376 ], [ -74.00152122, 40.71419756 ], [ -74.00149948, 40.71419491 ], [ -74.00148304, 40.71419511 ], [ -74.00146139, 40.71419852 ], [ -74.00144109, 40.71420505 ], [ -74.00142321, 40.71421486 ], [ -74.0014083, 40.71422718 ], [ -74.0013995, 40.71423787 ], [ -74.00139141, 40.71425347 ], [ -74.00138773, 40.71427001 ], [ -74.00138872, 40.71428676 ], [ -74.00139411, 40.71430297 ], [ -74.0014039, 40.71431808 ], [ -74.00141378, 40.71432809 ], [ -74.00142573, 40.71433688 ], [ -74.00144405, 40.7143462 ], [ -74.00146454, 40.7143524 ], [ -74.00148618, 40.71435519 ], [ -74.00150828, 40.71435458 ], [ -74.00152445, 40.71435179 ], [ -74.00154457, 40.71434518 ], [ -74.00156272, 40.71433551 ], [ -74.00157763, 40.71432319 ], [ -74.00158653, 40.71431257 ], [ -74.0015947, 40.71429698 ], [ -74.00159838, 40.7142805 ] ], [ [ -74.00132314, 40.71436677 ], [ -74.00131173, 40.71435342 ], [ -74.00130437, 40.71434287 ], [ -74.00129547, 40.71432646 ], [ -74.00129098, 40.71431516 ], [ -74.00128748, 40.71430372 ], [ -74.00128451, 40.71428608 ], [ -74.00128424, 40.71426838 ], [ -74.0012855, 40.71425449 ], [ -74.00117465, 40.71423038 ], [ -74.00113602, 40.71433129 ], [ -74.00114303, 40.71435267 ], [ -74.00123897, 40.71442859 ], [ -74.00132314, 40.71436677 ] ], [ [ -74.00140992, 40.71412839 ], [ -74.0013836, 40.71404409 ], [ -74.00129403, 40.71405308 ], [ -74.00129673, 40.7140605 ], [ -74.00125047, 40.71406622 ], [ -74.0012281, 40.7140844 ], [ -74.00119163, 40.7141849 ], [ -74.00130239, 40.714209 ], [ -74.00131173, 40.71419511 ], [ -74.00132907, 40.71417557 ], [ -74.00133922, 40.71416658 ], [ -74.00135602, 40.71415426 ], [ -74.00138081, 40.71414016 ], [ -74.00140992, 40.71412839 ] ], [ [ -74.00151403, 40.71443261 ], [ -74.00149122, 40.71443329 ], [ -74.00147558, 40.71443281 ], [ -74.00145268, 40.7144303 ], [ -74.0014375, 40.7144275 ], [ -74.00141549, 40.71442192 ], [ -74.00140129, 40.71441709 ], [ -74.00138099, 40.71440837 ], [ -74.0013668, 40.71440102 ], [ -74.00128254, 40.71446298 ], [ -74.00137875, 40.7145389 ], [ -74.00140722, 40.71454509 ], [ -74.00154053, 40.71451929 ], [ -74.00151403, 40.71443261 ] ], [ [ -74.00147028, 40.7141162 ], [ -74.00149095, 40.71411518 ], [ -74.0015064, 40.71411552 ], [ -74.00152427, 40.71411688 ], [ -74.00154709, 40.71412042 ], [ -74.001562, 40.71412376 ], [ -74.00158347, 40.7141305 ], [ -74.00160404, 40.71413887 ], [ -74.00162282, 40.71414881 ], [ -74.00170582, 40.71408828 ], [ -74.00160683, 40.71401168 ], [ -74.00157745, 40.71400637 ], [ -74.00144378, 40.7140317 ], [ -74.00147028, 40.7141162 ] ], [ [ -74.00166549, 40.71418279 ], [ -74.00168184, 40.71420349 ], [ -74.001691, 40.71421976 ], [ -74.00169585, 40.71423106 ], [ -74.00170205, 40.71425442 ], [ -74.0017034, 40.7142662 ], [ -74.0017034, 40.7142824 ], [ -74.00181964, 40.71430692 ], [ -74.00185081, 40.71421527 ], [ -74.0018421, 40.71419579 ], [ -74.00181075, 40.71417026 ], [ -74.00174301, 40.71412287 ], [ -74.00166549, 40.71418279 ] ], [ [ -74.00167564, 40.71435369 ], [ -74.00166468, 40.71436656 ], [ -74.00165507, 40.71437596 ], [ -74.00163351, 40.71439298 ], [ -74.00161518, 40.71440401 ], [ -74.00160225, 40.71441048 ], [ -74.00157224, 40.71442178 ], [ -74.00159901, 40.71450887 ], [ -74.00173601, 40.71448082 ], [ -74.00175837, 40.7144655 ], [ -74.00179377, 40.71437841 ], [ -74.00167564, 40.71435369 ] ] ] } }, { "type": "Feature", "properties": { "height": 107.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00412283, 40.71285829 ], [ -74.00402321, 40.71280436 ], [ -74.00392017, 40.71284106 ], [ -74.00379081, 40.71297486 ], [ -74.00369173, 40.71308306 ], [ -74.00358932, 40.71319507 ], [ -74.00357567, 40.71328298 ], [ -74.00367538, 40.7133369 ], [ -74.00349311, 40.71353198 ], [ -74.00323143, 40.71339029 ], [ -74.00324095, 40.71338007 ], [ -74.00320439, 40.71304398 ], [ -74.00318795, 40.71303506 ], [ -74.00327284, 40.71294429 ], [ -74.00326152, 40.71293809 ], [ -74.00328264, 40.71291556 ], [ -74.00330428, 40.71289138 ], [ -74.00339933, 40.71278108 ], [ -74.00345853, 40.71272742 ], [ -74.00347155, 40.71273437 ], [ -74.00355572, 40.71264428 ], [ -74.00357171, 40.71265286 ], [ -74.00404225, 40.7125303 ], [ -74.00404917, 40.71252287 ], [ -74.00408052, 40.7125399 ], [ -74.00430627, 40.71266198 ], [ -74.00412283, 40.71285829 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00198583, 40.71334848 ], [ -74.00200397, 40.71333078 ], [ -74.00201628, 40.71331886 ], [ -74.00204763, 40.71333799 ], [ -74.00207207, 40.7133529 ], [ -74.00241702, 40.71356256 ], [ -74.00255177, 40.71348909 ], [ -74.00259039, 40.7135296 ], [ -74.00293068, 40.71344551 ], [ -74.00299877, 40.71365679 ], [ -74.00293427, 40.71369152 ], [ -74.00297514, 40.71373551 ], [ -74.0024154, 40.71403619 ], [ -74.00237929, 40.71399718 ], [ -74.0023023, 40.71403851 ], [ -74.00207207, 40.71390151 ], [ -74.00208114, 40.71389266 ], [ -74.00167699, 40.71365209 ], [ -74.00171193, 40.71361812 ], [ -74.00168633, 40.71360287 ], [ -74.00171552, 40.71357447 ], [ -74.00170385, 40.71355901 ], [ -74.00169495, 40.7135424 ], [ -74.00168884, 40.71352511 ], [ -74.0016857, 40.7135074 ], [ -74.00168552, 40.71348949 ], [ -74.00168831, 40.71347165 ], [ -74.00169414, 40.71345436 ], [ -74.0016981, 40.71344598 ], [ -74.00170825, 40.71342978 ], [ -74.00171804, 40.7134178 ], [ -74.0017281, 40.71340758 ], [ -74.00174427, 40.71339471 ], [ -74.00176251, 40.71338341 ], [ -74.0017723, 40.71337837 ], [ -74.00179305, 40.71337 ], [ -74.00180392, 40.71336645 ], [ -74.00181497, 40.71336359 ], [ -74.00183787, 40.71335951 ], [ -74.00184955, 40.71335822 ], [ -74.001873, 40.7133574 ], [ -74.00189645, 40.7133589 ], [ -74.00190794, 40.71336046 ], [ -74.00193049, 40.71336537 ], [ -74.0019587, 40.71333799 ], [ -74.00198223, 40.71335202 ], [ -74.00198583, 40.71334848 ] ], [ [ -74.00206245, 40.71350216 ], [ -74.00193678, 40.71342522 ], [ -74.00188872, 40.71347057 ], [ -74.00189213, 40.7134739 ], [ -74.00189698, 40.71348119 ], [ -74.00189923, 40.71348929 ], [ -74.00189923, 40.71349338 ], [ -74.00189698, 40.71350148 ], [ -74.00189483, 40.71350516 ], [ -74.00188863, 40.71351196 ], [ -74.00188028, 40.71351721 ], [ -74.00187039, 40.71352061 ], [ -74.0018597, 40.71352177 ], [ -74.00184892, 40.71352082 ], [ -74.00183895, 40.71351768 ], [ -74.00180814, 40.71354669 ], [ -74.00185108, 40.71357311 ], [ -74.00183931, 40.71358421 ], [ -74.00192205, 40.71363487 ], [ -74.00206245, 40.71350216 ] ], [ [ -74.00241423, 40.71384792 ], [ -74.00240067, 40.71383097 ], [ -74.0022405, 40.71366067 ], [ -74.00228362, 40.71363718 ], [ -74.0022069, 40.71359109 ], [ -74.00219352, 40.71358319 ], [ -74.00207611, 40.71369656 ], [ -74.00217852, 40.71375811 ], [ -74.00215938, 40.7137765 ], [ -74.00234309, 40.71388667 ], [ -74.00241423, 40.71384792 ] ], [ [ -74.00278973, 40.71359667 ], [ -74.00276143, 40.71349719 ], [ -74.00259695, 40.71353641 ], [ -74.00260063, 40.71354022 ], [ -74.0026999, 40.71364426 ], [ -74.00278973, 40.71359667 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00345008, 40.70677359 ], [ -74.0034499, 40.70678762 ], [ -74.00344649, 40.7068013 ], [ -74.00344361, 40.70680791 ], [ -74.00343562, 40.70682051 ], [ -74.00342493, 40.70683181 ], [ -74.00341855, 40.70683692 ], [ -74.00341011, 40.70684189 ], [ -74.00276844, 40.70716801 ], [ -74.00241073, 40.70671666 ], [ -74.0030939, 40.70632251 ], [ -74.00344442, 40.70675316 ], [ -74.00344712, 40.7067599 ], [ -74.00345008, 40.70677359 ] ] ] } }, { "type": "Feature", "properties": { "height": 34.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00117698, 40.71124887 ], [ -74.0012564, 40.71114081 ], [ -74.00134084, 40.71117628 ], [ -74.00154493, 40.71089676 ], [ -74.00157943, 40.71090908 ], [ -74.0015779, 40.71085012 ], [ -74.00157871, 40.7108448 ], [ -74.00158248, 40.71083452 ], [ -74.00158904, 40.71082506 ], [ -74.00159811, 40.71081702 ], [ -74.00160341, 40.71081348 ], [ -74.00160925, 40.71081042 ], [ -74.00162192, 40.71080579 ], [ -74.00162857, 40.71080429 ], [ -74.00164258, 40.71080299 ], [ -74.00165659, 40.71080381 ], [ -74.00166342, 40.71080511 ], [ -74.00166998, 40.71080701 ], [ -74.00168229, 40.71081212 ], [ -74.00169289, 40.7108192 ], [ -74.00170124, 40.71082771 ], [ -74.00170699, 40.71083738 ], [ -74.00170986, 40.7108478 ], [ -74.00171193, 40.71090786 ], [ -74.00176547, 40.71088539 ], [ -74.00212794, 40.71134576 ], [ -74.00208159, 40.71137287 ], [ -74.00214474, 40.71139997 ], [ -74.00215543, 40.71140698 ], [ -74.00215992, 40.71141107 ], [ -74.0021672, 40.71142026 ], [ -74.00217169, 40.71143047 ], [ -74.00217295, 40.71143578 ], [ -74.00217322, 40.71144647 ], [ -74.00217043, 40.71145696 ], [ -74.00216801, 40.71146207 ], [ -74.00216118, 40.7114714 ], [ -74.00215678, 40.71147569 ], [ -74.00214654, 40.71148297 ], [ -74.00214061, 40.71148597 ], [ -74.00212785, 40.71149046 ], [ -74.00211402, 40.71149298 ], [ -74.00210701, 40.71149332 ], [ -74.00209291, 40.71149237 ], [ -74.00207943, 40.7114893 ], [ -74.0020126, 40.71146139 ], [ -74.0020135, 40.71150708 ], [ -74.00130553, 40.71151497 ], [ -74.00129933, 40.71147201 ], [ -74.00124139, 40.7114987 ], [ -74.0012352, 40.71150081 ], [ -74.00122217, 40.7115034 ], [ -74.00121543, 40.71150388 ], [ -74.00119513, 40.71150211 ], [ -74.00118228, 40.71149829 ], [ -74.0011707, 40.7114925 ], [ -74.00116081, 40.71148501 ], [ -74.001153, 40.71147616 ], [ -74.0011477, 40.71146629 ], [ -74.001145, 40.71145587 ], [ -74.00114635, 40.71144021 ], [ -74.00115381, 40.71142571 ], [ -74.00115749, 40.71142142 ], [ -74.00116674, 40.71141379 ], [ -74.00117204, 40.71141066 ], [ -74.00123888, 40.71138002 ], [ -74.00111832, 40.71132867 ], [ -74.00117698, 40.71124887 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00375497, 40.71031102 ], [ -74.0034208, 40.71056596 ], [ -74.00270403, 40.71002632 ], [ -74.0030382, 40.70977117 ], [ -74.00375497, 40.71031102 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00202814, 40.71232602 ], [ -74.00185791, 40.71254507 ], [ -74.00182988, 40.71258109 ], [ -74.0015894, 40.71247378 ], [ -74.00125631, 40.71232507 ], [ -74.00157161, 40.71191917 ], [ -74.00159793, 40.71188526 ], [ -74.00183509, 40.71199108 ], [ -74.00193175, 40.71203432 ], [ -74.0021716, 40.71214129 ], [ -74.00202814, 40.71232602 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00467493, 40.70689609 ], [ -74.00436663, 40.7070867 ], [ -74.00419937, 40.7071917 ], [ -74.00414825, 40.70722391 ], [ -74.00392673, 40.70693859 ], [ -74.0039058, 40.70691407 ], [ -74.00412481, 40.70677556 ], [ -74.00431435, 40.70665231 ], [ -74.00455564, 40.70651032 ], [ -74.00457603, 40.70653 ], [ -74.00482037, 40.7067584 ], [ -74.00480447, 40.70676821 ], [ -74.00483609, 40.7067981 ], [ -74.00467493, 40.70689609 ] ] ] } }, { "type": "Feature", "properties": { "height": 47.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0046761, 40.71354077 ], [ -74.00439655, 40.71389722 ], [ -74.00423377, 40.71382327 ], [ -74.00422623, 40.71383287 ], [ -74.00393957, 40.71370269 ], [ -74.00394712, 40.71369302 ], [ -74.00379854, 40.71362547 ], [ -74.00407818, 40.71326908 ], [ -74.00423871, 40.71334208 ], [ -74.00425192, 40.71332519 ], [ -74.00453839, 40.71345538 ], [ -74.00452519, 40.7134722 ], [ -74.0046761, 40.71354077 ] ], [ [ -74.00436313, 40.71359279 ], [ -74.00418607, 40.7135074 ], [ -74.00411501, 40.71360089 ], [ -74.00429468, 40.71368022 ], [ -74.00436313, 40.71359279 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00374706, 40.70963532 ], [ -74.00371122, 40.70961176 ], [ -74.00373907, 40.70958711 ], [ -74.0036487, 40.70952787 ], [ -74.00363019, 40.7095436 ], [ -74.00358348, 40.70951186 ], [ -74.00360127, 40.70949682 ], [ -74.0035913, 40.70949021 ], [ -74.00360064, 40.70948197 ], [ -74.00357917, 40.70946801 ], [ -74.0035701, 40.70947598 ], [ -74.00356192, 40.7094706 ], [ -74.00354387, 40.70948647 ], [ -74.00349616, 40.70945541 ], [ -74.00351431, 40.70943941 ], [ -74.00345215, 40.70939856 ], [ -74.00343391, 40.70941408 ], [ -74.00338765, 40.70938262 ], [ -74.00340508, 40.70936778 ], [ -74.0033077, 40.7093039 ], [ -74.00326835, 40.7093387 ], [ -74.00328955, 40.70935259 ], [ -74.00320098, 40.70943056 ], [ -74.00317987, 40.70941667 ], [ -74.00312741, 40.70946311 ], [ -74.00314879, 40.70947741 ], [ -74.00310791, 40.70951316 ], [ -74.00308662, 40.70949906 ], [ -74.00301107, 40.7095658 ], [ -74.00294577, 40.7095229 ], [ -74.00288549, 40.70957608 ], [ -74.00281497, 40.70952977 ], [ -74.00282692, 40.70951929 ], [ -74.0027573, 40.7094736 ], [ -74.00277733, 40.70945596 ], [ -74.00284695, 40.70950158 ], [ -74.00287714, 40.70947496 ], [ -74.00285791, 40.70946209 ], [ -74.00289888, 40.70942681 ], [ -74.00291747, 40.70943928 ], [ -74.00292475, 40.70943301 ], [ -74.00293598, 40.70944037 ], [ -74.00295322, 40.70942518 ], [ -74.00294235, 40.7094181 ], [ -74.00299814, 40.7093688 ], [ -74.00297999, 40.70935688 ], [ -74.00306857, 40.70927891 ], [ -74.00308653, 40.70929069 ], [ -74.00319226, 40.70919727 ], [ -74.00317403, 40.70918501 ], [ -74.00326638, 40.70910541 ], [ -74.00328353, 40.70911678 ], [ -74.00334067, 40.70906618 ], [ -74.00332288, 40.70905386 ], [ -74.00336438, 40.70901927 ], [ -74.00338091, 40.70903077 ], [ -74.0034428, 40.70897609 ], [ -74.00357827, 40.70906496 ], [ -74.00351665, 40.70911937 ], [ -74.00353803, 40.70913319 ], [ -74.00349769, 40.70916928 ], [ -74.00347604, 40.70915532 ], [ -74.00342277, 40.70920217 ], [ -74.0035197, 40.7092657 ], [ -74.00353767, 40.7092495 ], [ -74.0035851, 40.70928007 ], [ -74.00356668, 40.70929662 ], [ -74.00363397, 40.70934067 ], [ -74.0036522, 40.7093246 ], [ -74.00369802, 40.70935457 ], [ -74.00367978, 40.7093707 ], [ -74.00371571, 40.70939427 ], [ -74.00373467, 40.70937785 ], [ -74.00378084, 40.70940891 ], [ -74.00376234, 40.70942477 ], [ -74.00378758, 40.70944139 ], [ -74.00385594, 40.70938106 ], [ -74.00383654, 40.70936832 ], [ -74.00387723, 40.70933257 ], [ -74.00389636, 40.70934531 ], [ -74.00396967, 40.70928062 ], [ -74.00407881, 40.70935218 ], [ -74.00405438, 40.7093737 ], [ -74.00407971, 40.70939032 ], [ -74.00402653, 40.7094373 ], [ -74.00404845, 40.70945181 ], [ -74.00395943, 40.7095295 ], [ -74.00393814, 40.70951541 ], [ -74.00388208, 40.70956477 ], [ -74.00382692, 40.70952862 ], [ -74.00380294, 40.70954979 ], [ -74.00383932, 40.70957369 ], [ -74.00378794, 40.70961911 ], [ -74.003775, 40.70961067 ], [ -74.00374706, 40.70963532 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00183293, 40.70640879 ], [ -74.00128254, 40.70672851 ], [ -74.00099382, 40.70642431 ], [ -74.00153254, 40.70611801 ], [ -74.00183293, 40.70640879 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00452725, 40.70841901 ], [ -74.00439035, 40.7084837 ], [ -74.00438891, 40.70848199 ], [ -74.00420251, 40.70825558 ], [ -74.00405932, 40.70832326 ], [ -74.00409283, 40.70836398 ], [ -74.00384705, 40.70848029 ], [ -74.00383923, 40.70847076 ], [ -74.00375057, 40.7083631 ], [ -74.00376647, 40.70835561 ], [ -74.00374679, 40.70833171 ], [ -74.00370457, 40.70828036 ], [ -74.0036814, 40.70829139 ], [ -74.003616, 40.70821186 ], [ -74.00418383, 40.70794329 ], [ -74.0042344, 40.70800471 ], [ -74.00427159, 40.70804986 ], [ -74.00425183, 40.70805932 ], [ -74.00427168, 40.70808336 ], [ -74.00420008, 40.7081172 ], [ -74.00416523, 40.70813382 ], [ -74.0042468, 40.70823297 ], [ -74.00433843, 40.70818959 ], [ -74.00452725, 40.70841901 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0019649, 40.71323157 ], [ -74.00186159, 40.71325322 ], [ -74.00176367, 40.71320971 ], [ -74.0017581, 40.713217 ], [ -74.00174328, 40.71323627 ], [ -74.00174193, 40.71323817 ], [ -74.00175065, 40.71324212 ], [ -74.00169504, 40.7133145 ], [ -74.00158581, 40.71326588 ], [ -74.0016424, 40.71319207 ], [ -74.00159883, 40.7131728 ], [ -74.00144055, 40.71320876 ], [ -74.00141692, 40.71323947 ], [ -74.00151457, 40.71328291 ], [ -74.00144944, 40.71336788 ], [ -74.001433, 40.7133606 ], [ -74.00138432, 40.7134227 ], [ -74.00127059, 40.71337108 ], [ -74.00126439, 40.71337912 ], [ -74.00115551, 40.71333078 ], [ -74.00121193, 40.71325717 ], [ -74.00121858, 40.71326017 ], [ -74.00123753, 40.71323552 ], [ -74.00114069, 40.71319248 ], [ -74.00120519, 40.71310839 ], [ -74.00130041, 40.71315067 ], [ -74.00135952, 40.7130736 ], [ -74.00136913, 40.71307789 ], [ -74.00137605, 40.7130689 ], [ -74.00144432, 40.71305446 ], [ -74.0014569, 40.71306182 ], [ -74.001464, 40.7130484 ], [ -74.00147684, 40.71305719 ], [ -74.00148385, 40.71304616 ], [ -74.00155401, 40.71303138 ], [ -74.00156793, 40.71303778 ], [ -74.00157647, 40.71302328 ], [ -74.00184488, 40.71297139 ], [ -74.0019649, 40.71323157 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0021707, 40.70891522 ], [ -74.00204655, 40.70880191 ], [ -74.00204898, 40.70880041 ], [ -74.00196418, 40.70871958 ], [ -74.0018403, 40.70879489 ], [ -74.0018324, 40.70878727 ], [ -74.00155185, 40.70851985 ], [ -74.00185503, 40.70837399 ], [ -74.00231048, 40.70880797 ], [ -74.0021707, 40.70891522 ] ] ] } }, { "type": "Feature", "properties": { "height": 84.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0042335, 40.71418851 ], [ -74.0040471, 40.71410319 ], [ -74.00407693, 40.71406547 ], [ -74.00395709, 40.71401059 ], [ -74.00389708, 40.71408637 ], [ -74.0037724, 40.71424421 ], [ -74.00356821, 40.71409631 ], [ -74.00367727, 40.71383512 ], [ -74.00376961, 40.71380632 ], [ -74.00433681, 40.71406601 ], [ -74.0042335, 40.71418851 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00318768, 40.70864747 ], [ -74.00311357, 40.70871508 ], [ -74.00314169, 40.70873361 ], [ -74.0031354, 40.70873919 ], [ -74.00315921, 40.70875587 ], [ -74.00311564, 40.70879196 ], [ -74.00309327, 40.70877637 ], [ -74.00299257, 40.7088653 ], [ -74.00301557, 40.70888022 ], [ -74.00292825, 40.70895846 ], [ -74.00290453, 40.70894307 ], [ -74.00287776, 40.7089667 ], [ -74.0029004, 40.70898168 ], [ -74.00285854, 40.70901831 ], [ -74.00283617, 40.7090034 ], [ -74.00273341, 40.7090941 ], [ -74.00275649, 40.70910929 ], [ -74.00266765, 40.7091878 ], [ -74.00264447, 40.70917268 ], [ -74.00259174, 40.70921926 ], [ -74.00261321, 40.70923336 ], [ -74.00257207, 40.70926979 ], [ -74.00255051, 40.70925569 ], [ -74.00252122, 40.70928157 ], [ -74.00258994, 40.70932672 ], [ -74.00257054, 40.70934388 ], [ -74.00250173, 40.7092988 ], [ -74.00249077, 40.7093084 ], [ -74.00243157, 40.70926958 ], [ -74.00243885, 40.70926318 ], [ -74.00242501, 40.70925406 ], [ -74.00239564, 40.70928007 ], [ -74.0023924, 40.7092781 ], [ -74.00238953, 40.70928068 ], [ -74.00233078, 40.70924221 ], [ -74.00234003, 40.70923411 ], [ -74.00232144, 40.70922158 ], [ -74.00236294, 40.7091859 ], [ -74.00238091, 40.70919802 ], [ -74.00243328, 40.70915171 ], [ -74.002441, 40.70915682 ], [ -74.00246382, 40.70913666 ], [ -74.0024561, 40.70913156 ], [ -74.00251035, 40.70908382 ], [ -74.00249239, 40.70907197 ], [ -74.00258114, 40.70899407 ], [ -74.00259875, 40.70900572 ], [ -74.00265031, 40.70896009 ], [ -74.00268984, 40.70898597 ], [ -74.00275029, 40.70893258 ], [ -74.00271077, 40.70890671 ], [ -74.00276521, 40.7088587 ], [ -74.00274778, 40.70884719 ], [ -74.00283698, 40.70876908 ], [ -74.00285387, 40.70878032 ], [ -74.00297595, 40.70867259 ], [ -74.00296014, 40.70866217 ], [ -74.00300155, 40.70862561 ], [ -74.00301745, 40.70863596 ], [ -74.00302401, 40.7086301 ], [ -74.0030877, 40.70867191 ], [ -74.00306408, 40.70869282 ], [ -74.00307629, 40.70870078 ], [ -74.00308285, 40.708695 ], [ -74.00309147, 40.70870072 ], [ -74.00316576, 40.70863289 ], [ -74.00318768, 40.70864747 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00225263, 40.71310798 ], [ -74.00221041, 40.71311711 ], [ -74.00211231, 40.71313821 ], [ -74.00211051, 40.71313338 ], [ -74.00209919, 40.71313597 ], [ -74.00200667, 40.71293558 ], [ -74.00243427, 40.7128427 ], [ -74.00246032, 40.71283712 ], [ -74.00255051, 40.71281751 ], [ -74.0026831, 40.71287096 ], [ -74.00268517, 40.7128777 ], [ -74.0027759, 40.71286156 ], [ -74.00278919, 40.712905 ], [ -74.00269855, 40.71292121 ], [ -74.0027246, 40.71300646 ], [ -74.00250442, 40.71305337 ], [ -74.00252239, 40.71310219 ], [ -74.00251835, 40.71311329 ], [ -74.00236734, 40.71314707 ], [ -74.00235279, 40.71314012 ], [ -74.00233455, 40.71309041 ], [ -74.00225263, 40.71310798 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00440158, 40.70906026 ], [ -74.0043775, 40.70908171 ], [ -74.00439188, 40.70909111 ], [ -74.00433564, 40.70914088 ], [ -74.00429719, 40.70911569 ], [ -74.00427617, 40.70913428 ], [ -74.0043333, 40.70917166 ], [ -74.0042777, 40.70922069 ], [ -74.00429647, 40.70923322 ], [ -74.00420655, 40.70931146 ], [ -74.0041885, 40.70929948 ], [ -74.00413271, 40.70934878 ], [ -74.00410388, 40.70932998 ], [ -74.00407881, 40.70935218 ], [ -74.00396967, 40.70928062 ], [ -74.00404692, 40.70921238 ], [ -74.00402851, 40.7092002 ], [ -74.00406902, 40.70916492 ], [ -74.00408708, 40.70917691 ], [ -74.00415427, 40.70911746 ], [ -74.00413154, 40.70910261 ], [ -74.00411403, 40.7091176 ], [ -74.00406615, 40.70908532 ], [ -74.00408303, 40.70907081 ], [ -74.00404917, 40.70904862 ], [ -74.00403228, 40.70906346 ], [ -74.00398512, 40.70903261 ], [ -74.00400201, 40.7090177 ], [ -74.00393472, 40.70897351 ], [ -74.00391774, 40.70898801 ], [ -74.00387139, 40.70895669 ], [ -74.00388783, 40.70894266 ], [ -74.00381228, 40.70889329 ], [ -74.00393068, 40.7087887 ], [ -74.00400533, 40.70883759 ], [ -74.00402123, 40.7088237 ], [ -74.00406758, 40.70885448 ], [ -74.00405204, 40.70886816 ], [ -74.0041487, 40.70893156 ], [ -74.00416361, 40.70891821 ], [ -74.00426557, 40.70898399 ], [ -74.00424994, 40.70899802 ], [ -74.00434094, 40.70905767 ], [ -74.00436511, 40.70903629 ], [ -74.00440158, 40.70906026 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00385127, 40.70990021 ], [ -74.00378012, 40.70985377 ], [ -74.0037414, 40.70988809 ], [ -74.00353695, 40.70975401 ], [ -74.00357387, 40.70972139 ], [ -74.0035595, 40.70971199 ], [ -74.00365337, 40.70962899 ], [ -74.00366918, 40.70963941 ], [ -74.00370511, 40.70960767 ], [ -74.00371122, 40.70961176 ], [ -74.00374706, 40.70963532 ], [ -74.00390813, 40.70974087 ], [ -74.00388639, 40.70976021 ], [ -74.00395763, 40.70980658 ], [ -74.00400874, 40.70976136 ], [ -74.00421293, 40.7098953 ], [ -74.00417772, 40.70992636 ], [ -74.00419065, 40.70993487 ], [ -74.00409678, 40.71001767 ], [ -74.00408393, 40.71000929 ], [ -74.00404818, 40.71004082 ], [ -74.0038439, 40.70990681 ], [ -74.00385127, 40.70990021 ] ] ] } }, { "type": "Feature", "properties": { "height": 70.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00277733, 40.70945596 ], [ -74.0027573, 40.7094736 ], [ -74.00261905, 40.70959576 ], [ -74.00257539, 40.70956716 ], [ -74.00251413, 40.70962129 ], [ -74.00252257, 40.70962688 ], [ -74.00234722, 40.70978186 ], [ -74.00230527, 40.70975442 ], [ -74.00229332, 40.70976497 ], [ -74.00218462, 40.70969368 ], [ -74.00219738, 40.70968237 ], [ -74.0021557, 40.70965507 ], [ -74.00232952, 40.70950158 ], [ -74.00238962, 40.70954101 ], [ -74.00245223, 40.70948578 ], [ -74.0024278, 40.70946978 ], [ -74.00257054, 40.70934388 ], [ -74.00258994, 40.70932672 ], [ -74.00260144, 40.7093165 ], [ -74.00264375, 40.70934428 ], [ -74.00265669, 40.70933278 ], [ -74.0027653, 40.709404 ], [ -74.00275137, 40.70941619 ], [ -74.00279207, 40.70944289 ], [ -74.00277733, 40.70945596 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00452725, 40.70841901 ], [ -74.00438891, 40.70848199 ], [ -74.00420251, 40.70825558 ], [ -74.00405932, 40.70832326 ], [ -74.00409283, 40.70836398 ], [ -74.00384705, 40.70848029 ], [ -74.00383923, 40.70847076 ], [ -74.00375057, 40.7083631 ], [ -74.00376647, 40.70835561 ], [ -74.00374679, 40.70833171 ], [ -74.00416523, 40.70813382 ], [ -74.0042468, 40.70823297 ], [ -74.00433843, 40.70818959 ], [ -74.00452725, 40.70841901 ] ] ] } }, { "type": "Feature", "properties": { "height": 73.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00344334, 40.70878515 ], [ -74.00336753, 40.7087347 ], [ -74.00334624, 40.70875322 ], [ -74.00318768, 40.70864747 ], [ -74.00316576, 40.70863289 ], [ -74.0031487, 40.70862152 ], [ -74.00318229, 40.70859238 ], [ -74.00316783, 40.70858271 ], [ -74.00326305, 40.70849997 ], [ -74.00327473, 40.7085078 ], [ -74.00331273, 40.70847478 ], [ -74.00351153, 40.70860736 ], [ -74.00347272, 40.708641 ], [ -74.00354997, 40.70869248 ], [ -74.00355572, 40.70868751 ], [ -74.0037529, 40.708819 ], [ -74.0037176, 40.70884971 ], [ -74.00373233, 40.70885958 ], [ -74.00364088, 40.70893898 ], [ -74.0036275, 40.70892999 ], [ -74.00359112, 40.70896159 ], [ -74.00339259, 40.70882921 ], [ -74.00344334, 40.70878515 ] ] ] } }, { "type": "Feature", "properties": { "height": 110.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00277149, 40.71372659 ], [ -74.00246975, 40.71389382 ], [ -74.0024163, 40.71383859 ], [ -74.00224903, 40.71366496 ], [ -74.002282, 40.71364672 ], [ -74.00241603, 40.7135725 ], [ -74.00255078, 40.7134978 ], [ -74.0025974, 40.71354601 ], [ -74.00260818, 40.71355731 ], [ -74.00268454, 40.71363637 ], [ -74.00277149, 40.71372659 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00412283, 40.71285829 ], [ -74.00394038, 40.7130497 ], [ -74.0038422, 40.7131536 ], [ -74.00367538, 40.7133369 ], [ -74.00357567, 40.71328298 ], [ -74.00358932, 40.71319507 ], [ -74.00369173, 40.71308306 ], [ -74.00379081, 40.71297486 ], [ -74.00392017, 40.71284106 ], [ -74.00402321, 40.71280436 ], [ -74.00412283, 40.71285829 ] ] ] } }, { "type": "Feature", "properties": { "height": 125.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00275344, 40.71372488 ], [ -74.00247253, 40.71388047 ], [ -74.00226682, 40.71366701 ], [ -74.00254754, 40.71351149 ], [ -74.00275344, 40.71372488 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0025099, 40.71348139 ], [ -74.00243957, 40.71332417 ], [ -74.00250703, 40.71330681 ], [ -74.00247352, 40.7132317 ], [ -74.00257584, 40.71320528 ], [ -74.00258608, 40.7132285 ], [ -74.00275245, 40.71318547 ], [ -74.00275847, 40.71319916 ], [ -74.00281345, 40.71318499 ], [ -74.00289573, 40.71336931 ], [ -74.00283617, 40.7133847 ], [ -74.0028412, 40.7133958 ], [ -74.00274275, 40.71342127 ], [ -74.00276107, 40.71346246 ], [ -74.00269307, 40.7134801 ], [ -74.00267475, 40.71343877 ], [ -74.0025099, 40.71348139 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0042344, 40.70800471 ], [ -74.00419739, 40.70802221 ], [ -74.0042088, 40.7080361 ], [ -74.00415445, 40.70806177 ], [ -74.00420008, 40.7081172 ], [ -74.00416523, 40.70813382 ], [ -74.00374679, 40.70833171 ], [ -74.00370457, 40.70828036 ], [ -74.00372865, 40.70826906 ], [ -74.00371742, 40.70825537 ], [ -74.0037529, 40.70823862 ], [ -74.00369874, 40.7081727 ], [ -74.00418383, 40.70794329 ], [ -74.0042344, 40.70800471 ] ] ] } }, { "type": "Feature", "properties": { "height": 123.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0038457, 40.71291127 ], [ -74.00378767, 40.71297391 ], [ -74.00378416, 40.71297241 ], [ -74.00371383, 40.71304861 ], [ -74.00371724, 40.71304997 ], [ -74.00365472, 40.71311751 ], [ -74.00364798, 40.71311438 ], [ -74.00357261, 40.71307938 ], [ -74.00357558, 40.71307509 ], [ -74.00345457, 40.71302049 ], [ -74.0034499, 40.71302477 ], [ -74.00337049, 40.71298726 ], [ -74.00342619, 40.71292856 ], [ -74.00343158, 40.71293156 ], [ -74.00351647, 40.71284406 ], [ -74.00351027, 40.71283957 ], [ -74.00356399, 40.71278237 ], [ -74.00364313, 40.71281989 ], [ -74.00363972, 40.71282357 ], [ -74.0037609, 40.71287838 ], [ -74.00376413, 40.71287436 ], [ -74.0038457, 40.71291127 ] ] ] } }, { "type": "Feature", "properties": { "height": 142.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00272703, 40.71372168 ], [ -74.00247667, 40.71386052 ], [ -74.00229314, 40.71367007 ], [ -74.00254341, 40.71353151 ], [ -74.00272703, 40.71372168 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00267771, 40.70780669 ], [ -74.00238109, 40.70796031 ], [ -74.00223978, 40.70779497 ], [ -74.00254808, 40.70764237 ], [ -74.00257162, 40.70767111 ], [ -74.00256767, 40.70767288 ], [ -74.00267771, 40.70780669 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00253739, 40.70723399 ], [ -74.00216747, 40.70742337 ], [ -74.0020991, 40.7073469 ], [ -74.00224517, 40.70727206 ], [ -74.00217295, 40.70719027 ], [ -74.00218184, 40.70718578 ], [ -74.00217879, 40.7071821 ], [ -74.002176, 40.7071787 ], [ -74.00225299, 40.7071392 ], [ -74.00231533, 40.70710726 ], [ -74.00233401, 40.70712837 ], [ -74.0023447, 40.70712286 ], [ -74.00241765, 40.70708561 ], [ -74.00246328, 40.70714261 ], [ -74.00247514, 40.70715602 ], [ -74.00247047, 40.7071584 ], [ -74.00253739, 40.70723399 ] ] ] } }, { "type": "Feature", "properties": { "height": 172.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00271517, 40.71372039 ], [ -74.00247864, 40.71385146 ], [ -74.002305, 40.7136715 ], [ -74.00254162, 40.71354036 ], [ -74.00271517, 40.71372039 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00205814, 40.70900149 ], [ -74.0018686, 40.70914667 ], [ -74.00164519, 40.70894082 ], [ -74.00170313, 40.70890562 ], [ -74.00173708, 40.70893796 ], [ -74.0018315, 40.70888069 ], [ -74.00179458, 40.70884556 ], [ -74.00185386, 40.70880947 ], [ -74.00189043, 40.70884426 ], [ -74.00189213, 40.70884331 ], [ -74.00205814, 40.70900149 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0018324, 40.70878727 ], [ -74.00168723, 40.70886918 ], [ -74.00163234, 40.70881696 ], [ -74.00139815, 40.70859381 ], [ -74.00155185, 40.70851985 ], [ -74.0018324, 40.70878727 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00329683, 40.70748908 ], [ -74.00316118, 40.70755759 ], [ -74.00289483, 40.70722528 ], [ -74.003017, 40.70716161 ], [ -74.00314268, 40.70730869 ], [ -74.00315984, 40.70732878 ], [ -74.0031822, 40.70735507 ], [ -74.00328398, 40.7074741 ], [ -74.00329683, 40.70748908 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00335351, 40.7078694 ], [ -74.00320592, 40.70768922 ], [ -74.00337121, 40.70761077 ], [ -74.00344128, 40.70757761 ], [ -74.00354288, 40.70768636 ], [ -74.00356632, 40.70771489 ], [ -74.0034146, 40.7078679 ], [ -74.00341451, 40.70787492 ], [ -74.00341154, 40.70788146 ], [ -74.00340903, 40.70788438 ], [ -74.0034022, 40.70788922 ], [ -74.00339825, 40.70789078 ], [ -74.00339394, 40.70789201 ], [ -74.00338468, 40.70789269 ], [ -74.00337579, 40.70789119 ], [ -74.00337175, 40.70788956 ], [ -74.00336789, 40.70788758 ], [ -74.00336205, 40.70788227 ], [ -74.00335872, 40.7078758 ], [ -74.00335351, 40.7078694 ] ] ] } }, { "type": "Feature", "properties": { "height": 171.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00154493, 40.71089676 ], [ -74.00134084, 40.71117628 ], [ -74.0012564, 40.71114081 ], [ -74.00118561, 40.71111112 ], [ -74.00138971, 40.71083166 ], [ -74.00146157, 40.7108619 ], [ -74.00154493, 40.71089676 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00230428, 40.70774029 ], [ -74.0021707, 40.70758408 ], [ -74.00239474, 40.70746927 ], [ -74.00241199, 40.70749181 ], [ -74.0024163, 40.7074899 ], [ -74.002472, 40.70756256 ], [ -74.0025267, 40.70763386 ], [ -74.00245502, 40.70766566 ], [ -74.00230428, 40.70774029 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00180383, 40.70919638 ], [ -74.00167797, 40.7092928 ], [ -74.00144369, 40.70906741 ], [ -74.00157458, 40.70898522 ], [ -74.00180383, 40.70919638 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0019649, 40.71323157 ], [ -74.00184488, 40.71297139 ], [ -74.00200667, 40.71293558 ], [ -74.00209919, 40.71313597 ], [ -74.00212749, 40.71319739 ], [ -74.00196867, 40.71323981 ], [ -74.0019649, 40.71323157 ] ] ] } }, { "type": "Feature", "properties": { "height": 113.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00360711, 40.71335481 ], [ -74.00346643, 40.71350536 ], [ -74.00326979, 40.71339621 ], [ -74.00341047, 40.7132477 ], [ -74.00360711, 40.71335481 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0016097, 40.7083503 ], [ -74.0014525, 40.7084299 ], [ -74.00132817, 40.70829827 ], [ -74.0012731, 40.70823998 ], [ -74.00130787, 40.70821901 ], [ -74.00134551, 40.7081964 ], [ -74.00136428, 40.70821601 ], [ -74.00139267, 40.70819892 ], [ -74.00142923, 40.70817686 ], [ -74.00152373, 40.7082677 ], [ -74.0016097, 40.7083503 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00277383, 40.70775691 ], [ -74.00266262, 40.7076216 ], [ -74.00271894, 40.70759668 ], [ -74.00267528, 40.70754588 ], [ -74.00275164, 40.7075121 ], [ -74.00276691, 40.70753212 ], [ -74.00279934, 40.70757441 ], [ -74.00287974, 40.70753866 ], [ -74.00296831, 40.70765606 ], [ -74.00277383, 40.70775691 ] ] ] } }, { "type": "Feature", "properties": { "height": 31.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00335351, 40.7078694 ], [ -74.00320592, 40.70768922 ], [ -74.00337121, 40.70761077 ], [ -74.00348152, 40.70773491 ], [ -74.00335351, 40.7078694 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00365885, 40.70710277 ], [ -74.00356893, 40.70714751 ], [ -74.00360827, 40.70719327 ], [ -74.00353434, 40.70723011 ], [ -74.0034747, 40.70716086 ], [ -74.00348009, 40.7071582 ], [ -74.00355321, 40.70712177 ], [ -74.00353084, 40.70709569 ], [ -74.00347658, 40.7070327 ], [ -74.00345673, 40.70700961 ], [ -74.00338828, 40.70704366 ], [ -74.00334543, 40.70699027 ], [ -74.00348655, 40.70691659 ], [ -74.00349284, 40.7069153 ], [ -74.00349913, 40.70691639 ], [ -74.00350389, 40.70691966 ], [ -74.00365885, 40.70710277 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00149508, 40.70813709 ], [ -74.00142923, 40.70817686 ], [ -74.00139267, 40.70819892 ], [ -74.00134389, 40.70814751 ], [ -74.00127571, 40.70818496 ], [ -74.00130787, 40.70821901 ], [ -74.0012731, 40.70823998 ], [ -74.00126502, 40.70824488 ], [ -74.00118085, 40.70815568 ], [ -74.00113225, 40.70810427 ], [ -74.00123546, 40.70805408 ], [ -74.00128532, 40.70810107 ], [ -74.00139752, 40.70804237 ], [ -74.00144693, 40.70809031 ], [ -74.00149508, 40.70813709 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00272307, 40.70747499 ], [ -74.00264528, 40.70750951 ], [ -74.00263073, 40.70749051 ], [ -74.00261285, 40.70749841 ], [ -74.00261384, 40.70749971 ], [ -74.002472, 40.70756256 ], [ -74.0024163, 40.7074899 ], [ -74.00241199, 40.70749181 ], [ -74.00239474, 40.70746927 ], [ -74.00262453, 40.70735241 ], [ -74.00269163, 40.70743992 ], [ -74.00269505, 40.70743842 ], [ -74.00272307, 40.70747499 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0025099, 40.71348139 ], [ -74.00238737, 40.71351312 ], [ -74.00236321, 40.71345879 ], [ -74.00239851, 40.71344966 ], [ -74.00231308, 40.71325846 ], [ -74.00246759, 40.71321856 ], [ -74.00247352, 40.7132317 ], [ -74.00250703, 40.71330681 ], [ -74.00243957, 40.71332417 ], [ -74.0025099, 40.71348139 ] ] ] } }, { "type": "Feature", "properties": { "height": 149.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00373808, 40.71296036 ], [ -74.00370942, 40.71296472 ], [ -74.00370125, 40.71298351 ], [ -74.00368508, 40.71300087 ], [ -74.00366074, 40.71301477 ], [ -74.00366729, 40.7130354 ], [ -74.00359237, 40.71304908 ], [ -74.0035842, 40.71302661 ], [ -74.0035612, 40.71302096 ], [ -74.00353919, 40.71301157 ], [ -74.00351943, 40.71299659 ], [ -74.00348898, 40.71300108 ], [ -74.00347461, 40.71294361 ], [ -74.00350227, 40.71293891 ], [ -74.00351404, 40.71291842 ], [ -74.00353228, 40.71289928 ], [ -74.00355132, 40.71288812 ], [ -74.00354611, 40.71286837 ], [ -74.00362058, 40.71285659 ], [ -74.00362579, 40.71287736 ], [ -74.0036513, 40.71288342 ], [ -74.00367484, 40.71289268 ], [ -74.00369505, 40.71290786 ], [ -74.00372317, 40.71290337 ], [ -74.00373808, 40.71296036 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00163234, 40.70881696 ], [ -74.00155526, 40.70886381 ], [ -74.00153901, 40.70884828 ], [ -74.00131434, 40.70863419 ], [ -74.00139815, 40.70859381 ], [ -74.00163234, 40.70881696 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00187228, 40.70733539 ], [ -74.00187093, 40.70733621 ], [ -74.00176134, 40.70739382 ], [ -74.00175352, 40.70738442 ], [ -74.00171633, 40.70733961 ], [ -74.00161671, 40.70721949 ], [ -74.00172559, 40.70715731 ], [ -74.00187228, 40.70733539 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0021707, 40.70891522 ], [ -74.00205814, 40.70900149 ], [ -74.00189213, 40.70884331 ], [ -74.00196211, 40.70880068 ], [ -74.00199571, 40.70883282 ], [ -74.00204655, 40.70880191 ], [ -74.0021707, 40.70891522 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00341657, 40.70742868 ], [ -74.00329683, 40.70748908 ], [ -74.00328398, 40.7074741 ], [ -74.0031822, 40.70735507 ], [ -74.00315984, 40.70732878 ], [ -74.00327949, 40.7072692 ], [ -74.00328901, 40.7072803 ], [ -74.00341657, 40.70742868 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00141764, 40.70894947 ], [ -74.0013518, 40.70898951 ], [ -74.00125595, 40.70889881 ], [ -74.00109587, 40.70874757 ], [ -74.00109003, 40.70874212 ], [ -74.00116315, 40.70870691 ], [ -74.00141764, 40.70894947 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00141764, 40.70894947 ], [ -74.00116315, 40.70870691 ], [ -74.00123672, 40.7086715 ], [ -74.00146768, 40.70889159 ], [ -74.00148529, 40.70890827 ], [ -74.00141764, 40.70894947 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00171633, 40.70733961 ], [ -74.00156182, 40.70742296 ], [ -74.00146534, 40.70730577 ], [ -74.00161671, 40.70721949 ], [ -74.00171633, 40.70733961 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00201673, 40.70750066 ], [ -74.00190624, 40.70755732 ], [ -74.00183114, 40.7074726 ], [ -74.00179143, 40.70742766 ], [ -74.00176134, 40.70739382 ], [ -74.00187093, 40.70733621 ], [ -74.00201673, 40.70750066 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00199831, 40.70788942 ], [ -74.00186941, 40.70773859 ], [ -74.00198942, 40.70767696 ], [ -74.0021159, 40.707825 ], [ -74.00211959, 40.70782936 ], [ -74.00199831, 40.70788942 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00238109, 40.70796031 ], [ -74.0022723, 40.70801656 ], [ -74.00214321, 40.70786559 ], [ -74.00212947, 40.70784959 ], [ -74.00223978, 40.70779497 ], [ -74.00238109, 40.70796031 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00132817, 40.70829827 ], [ -74.00125792, 40.70833681 ], [ -74.00125092, 40.70832857 ], [ -74.00122567, 40.7083424 ], [ -74.0010496, 40.70814437 ], [ -74.00113225, 40.70810427 ], [ -74.00118085, 40.70815568 ], [ -74.00126502, 40.70824488 ], [ -74.0012731, 40.70823998 ], [ -74.00132817, 40.70829827 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0022723, 40.70801656 ], [ -74.00215381, 40.70807812 ], [ -74.0021159, 40.70803372 ], [ -74.00211995, 40.70803168 ], [ -74.00206991, 40.70797332 ], [ -74.00202697, 40.70792306 ], [ -74.00214321, 40.70786559 ], [ -74.0022723, 40.70801656 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00153901, 40.70884828 ], [ -74.00146768, 40.70889159 ], [ -74.00123672, 40.7086715 ], [ -74.00131434, 40.70863419 ], [ -74.00153901, 40.70884828 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0018686, 40.70914667 ], [ -74.00180383, 40.70919638 ], [ -74.00157458, 40.70898522 ], [ -74.00164519, 40.70894082 ], [ -74.0018686, 40.70914667 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00335351, 40.7078694 ], [ -74.00348152, 40.70773491 ], [ -74.00337121, 40.70761077 ], [ -74.00344128, 40.70757761 ], [ -74.00354288, 40.70768636 ], [ -74.00356632, 40.70771489 ], [ -74.0034146, 40.7078679 ], [ -74.00341451, 40.70787492 ], [ -74.00341154, 40.70788146 ], [ -74.00340903, 40.70788438 ], [ -74.0034022, 40.70788922 ], [ -74.00339825, 40.70789078 ], [ -74.00339394, 40.70789201 ], [ -74.00338468, 40.70789269 ], [ -74.00337579, 40.70789119 ], [ -74.00337175, 40.70788956 ], [ -74.00336789, 40.70788758 ], [ -74.00336205, 40.70788227 ], [ -74.00335872, 40.7078758 ], [ -74.00335351, 40.7078694 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00241765, 40.70708561 ], [ -74.0023447, 40.70712286 ], [ -74.00216603, 40.7069061 ], [ -74.00224023, 40.70686382 ], [ -74.00231749, 40.70696031 ], [ -74.00239025, 40.70705122 ], [ -74.00241765, 40.70708561 ] ] ] } }, { "type": "Feature", "properties": { "height": 9.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00277383, 40.70775691 ], [ -74.00267771, 40.70780669 ], [ -74.00256767, 40.70767288 ], [ -74.00257162, 40.70767111 ], [ -74.00254808, 40.70764237 ], [ -74.00254395, 40.7076374 ], [ -74.00263854, 40.70759232 ], [ -74.00266262, 40.7076216 ], [ -74.00277383, 40.70775691 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00206991, 40.70797332 ], [ -74.0019993, 40.70800818 ], [ -74.00195367, 40.70795132 ], [ -74.00180554, 40.70777141 ], [ -74.00186941, 40.70773859 ], [ -74.00199831, 40.70788942 ], [ -74.00202697, 40.70792306 ], [ -74.00206991, 40.70797332 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00222119, 40.70777291 ], [ -74.0021159, 40.707825 ], [ -74.00198942, 40.70767696 ], [ -74.00209363, 40.70762357 ], [ -74.00222119, 40.70777291 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00392197, 40.70675309 ], [ -74.00381821, 40.70682126 ], [ -74.00369541, 40.70668547 ], [ -74.00380707, 40.70662636 ], [ -74.00392197, 40.70675309 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00384651, 40.70652578 ], [ -74.00379854, 40.70655608 ], [ -74.00380465, 40.70656167 ], [ -74.00376889, 40.70658421 ], [ -74.00378973, 40.70660729 ], [ -74.00380707, 40.70662636 ], [ -74.00369541, 40.70668547 ], [ -74.00361528, 40.70659701 ], [ -74.00379854, 40.70648158 ], [ -74.00384651, 40.70652578 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00166711, 40.70818128 ], [ -74.00152373, 40.7082677 ], [ -74.00142923, 40.70817686 ], [ -74.00149508, 40.70813709 ], [ -74.00157188, 40.70809078 ], [ -74.00166711, 40.70818128 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00225299, 40.7071392 ], [ -74.002176, 40.7071787 ], [ -74.00202005, 40.70698939 ], [ -74.00209461, 40.70694689 ], [ -74.00225299, 40.7071392 ] ] ] } }, { "type": "Feature", "properties": { "height": 11.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0023447, 40.70712286 ], [ -74.00233401, 40.70712837 ], [ -74.00231533, 40.70710726 ], [ -74.00225299, 40.7071392 ], [ -74.00209461, 40.70694689 ], [ -74.00216603, 40.7069061 ], [ -74.0023447, 40.70712286 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0016097, 40.7083503 ], [ -74.00152373, 40.7082677 ], [ -74.00166711, 40.70818128 ], [ -74.0017634, 40.7082726 ], [ -74.0016097, 40.7083503 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00379854, 40.70648158 ], [ -74.00361528, 40.70659701 ], [ -74.00354872, 40.70652326 ], [ -74.00372488, 40.70641771 ], [ -74.00376234, 40.70645019 ], [ -74.00379854, 40.70648158 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00123502, 40.70853531 ], [ -74.00109865, 40.70837726 ], [ -74.00109021, 40.70838148 ], [ -74.00106577, 40.70835316 ], [ -74.0011468, 40.70831271 ], [ -74.00130778, 40.70849922 ], [ -74.00123502, 40.70853531 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0014525, 40.7084299 ], [ -74.00134973, 40.70848186 ], [ -74.00122567, 40.7083424 ], [ -74.00125092, 40.70832857 ], [ -74.00125792, 40.70833681 ], [ -74.00132817, 40.70829827 ], [ -74.0014525, 40.7084299 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00216747, 40.70742337 ], [ -74.00208671, 40.70746477 ], [ -74.00193894, 40.70730039 ], [ -74.00197523, 40.70728132 ], [ -74.0020196, 40.70725789 ], [ -74.0020991, 40.7073469 ], [ -74.00216747, 40.70742337 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00400192, 40.70635199 ], [ -74.00379854, 40.70648158 ], [ -74.00376234, 40.70645019 ], [ -74.00378749, 40.70643351 ], [ -74.00375892, 40.70640858 ], [ -74.00393329, 40.70629241 ], [ -74.00400192, 40.70635199 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00408564, 40.70642479 ], [ -74.00401297, 40.70647307 ], [ -74.0039782, 40.70644277 ], [ -74.00384651, 40.70652578 ], [ -74.00379854, 40.70648158 ], [ -74.00400192, 40.70635199 ], [ -74.00408564, 40.70642479 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00123502, 40.70853531 ], [ -74.00115974, 40.7085727 ], [ -74.00102014, 40.7084013 ], [ -74.0010055, 40.70838325 ], [ -74.00106101, 40.70835561 ], [ -74.00106577, 40.70835316 ], [ -74.00109021, 40.70838148 ], [ -74.00109865, 40.70837726 ], [ -74.00123502, 40.70853531 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00393329, 40.70629241 ], [ -74.00375892, 40.70640858 ], [ -74.0037238, 40.70637808 ], [ -74.00374617, 40.70636316 ], [ -74.00370619, 40.7063285 ], [ -74.00385828, 40.70622717 ], [ -74.00393329, 40.70629241 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00353587, 40.7063648 ], [ -74.00345439, 40.70641907 ], [ -74.0033068, 40.70625591 ], [ -74.0033669, 40.70621777 ], [ -74.00350398, 40.70633708 ], [ -74.00353587, 40.7063648 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00115974, 40.7085727 ], [ -74.00108572, 40.7086094 ], [ -74.00095214, 40.70844461 ], [ -74.00094414, 40.70844829 ], [ -74.00093749, 40.70844011 ], [ -74.00102014, 40.7084013 ], [ -74.00115974, 40.7085727 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00348009, 40.7071582 ], [ -74.0034747, 40.70716086 ], [ -74.00345475, 40.70717087 ], [ -74.00340912, 40.70719361 ], [ -74.00340687, 40.70719095 ], [ -74.00326871, 40.70703031 ], [ -74.00334543, 40.70699027 ], [ -74.00338828, 40.70704366 ], [ -74.00348009, 40.7071582 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00230428, 40.70774029 ], [ -74.00222631, 40.7077789 ], [ -74.00222119, 40.70777291 ], [ -74.00209363, 40.70762357 ], [ -74.0021707, 40.70758408 ], [ -74.00230428, 40.70774029 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00125595, 40.70889881 ], [ -74.00122298, 40.70891889 ], [ -74.00121723, 40.70891331 ], [ -74.00121067, 40.70891719 ], [ -74.00120322, 40.70891011 ], [ -74.00117294, 40.7089285 ], [ -74.00102229, 40.70878536 ], [ -74.00109587, 40.70874757 ], [ -74.00125595, 40.70889881 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00208671, 40.70746477 ], [ -74.00201673, 40.70750066 ], [ -74.00187093, 40.70733621 ], [ -74.00187228, 40.70733539 ], [ -74.00192573, 40.70730726 ], [ -74.00193894, 40.70730039 ], [ -74.00208671, 40.70746477 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00340687, 40.70719095 ], [ -74.00333537, 40.70722657 ], [ -74.0033174, 40.7072056 ], [ -74.00319819, 40.70706702 ], [ -74.00326871, 40.70703031 ], [ -74.00340687, 40.70719095 ] ] ] } }, { "type": "Feature", "properties": { "height": 31.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00108572, 40.7086094 ], [ -74.00101655, 40.70864379 ], [ -74.00088845, 40.70848581 ], [ -74.00088207, 40.70847798 ], [ -74.00094414, 40.70844829 ], [ -74.00095214, 40.70844461 ], [ -74.00108572, 40.7086094 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00372488, 40.70641771 ], [ -74.00354872, 40.70652326 ], [ -74.0034994, 40.70646892 ], [ -74.00366047, 40.7063616 ], [ -74.00372488, 40.70641771 ] ] ] } }, { "type": "Feature", "properties": { "height": 164.79 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00368427, 40.71296131 ], [ -74.00367502, 40.7129812 ], [ -74.00365741, 40.7129974 ], [ -74.00363352, 40.71300816 ], [ -74.00360621, 40.71301197 ], [ -74.00357881, 40.71300857 ], [ -74.00355465, 40.71299829 ], [ -74.0035365, 40.71298229 ], [ -74.00352671, 40.71296261 ], [ -74.00352644, 40.7129415 ], [ -74.0035356, 40.71292168 ], [ -74.00355321, 40.71290541 ], [ -74.00357719, 40.71289472 ], [ -74.0036045, 40.71289077 ], [ -74.0036319, 40.71289418 ], [ -74.00365607, 40.71290446 ], [ -74.00367421, 40.71292046 ], [ -74.003684, 40.71294021 ], [ -74.00368427, 40.71296131 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0036178, 40.70732722 ], [ -74.00354845, 40.70736222 ], [ -74.00342798, 40.70722221 ], [ -74.00347748, 40.70719749 ], [ -74.00345475, 40.70717087 ], [ -74.0034747, 40.70716086 ], [ -74.00353434, 40.70723011 ], [ -74.00357638, 40.70727907 ], [ -74.0036178, 40.70732722 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00217879, 40.7071821 ], [ -74.00212713, 40.70720859 ], [ -74.00197002, 40.70701792 ], [ -74.00202005, 40.70698939 ], [ -74.002176, 40.7071787 ], [ -74.00217879, 40.7071821 ] ] ] } }, { "type": "Feature", "properties": { "height": 8.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00207808, 40.70723372 ], [ -74.00202607, 40.70726028 ], [ -74.00202284, 40.70725626 ], [ -74.00187228, 40.70707369 ], [ -74.00192259, 40.70704495 ], [ -74.00207808, 40.70723372 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00314268, 40.70730869 ], [ -74.003017, 40.70716161 ], [ -74.00308141, 40.70712797 ], [ -74.00316334, 40.70722316 ], [ -74.00320861, 40.70727587 ], [ -74.00314268, 40.70730869 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00348152, 40.70739599 ], [ -74.00341657, 40.70742868 ], [ -74.00328901, 40.7072803 ], [ -74.00335423, 40.70724788 ], [ -74.00336079, 40.70725558 ], [ -74.00348152, 40.70739599 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00192573, 40.70730726 ], [ -74.00187228, 40.70733539 ], [ -74.00172559, 40.70715731 ], [ -74.00177769, 40.70712769 ], [ -74.00192573, 40.70730726 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00354845, 40.70736222 ], [ -74.00348152, 40.70739599 ], [ -74.00336079, 40.70725558 ], [ -74.00342798, 40.70722221 ], [ -74.00354845, 40.70736222 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00212713, 40.70720859 ], [ -74.00207808, 40.70723372 ], [ -74.00192259, 40.70704495 ], [ -74.00197002, 40.70701792 ], [ -74.00212713, 40.70720859 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00402833, 40.70668472 ], [ -74.00397308, 40.70671979 ], [ -74.00384435, 40.70657856 ], [ -74.00383411, 40.70656739 ], [ -74.00389304, 40.70653627 ], [ -74.00389879, 40.70654267 ], [ -74.00402833, 40.70668472 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00408627, 40.70664686 ], [ -74.00402833, 40.70668472 ], [ -74.00389879, 40.70654267 ], [ -74.00395817, 40.70650651 ], [ -74.00408627, 40.70664686 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00197523, 40.70728132 ], [ -74.00193894, 40.70730039 ], [ -74.00192573, 40.70730726 ], [ -74.00177769, 40.70712769 ], [ -74.00182593, 40.70710011 ], [ -74.00197523, 40.70728132 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00366047, 40.7063616 ], [ -74.0034994, 40.70646892 ], [ -74.00345439, 40.70641907 ], [ -74.00353587, 40.7063648 ], [ -74.00358177, 40.70633429 ], [ -74.00360863, 40.70631652 ], [ -74.00366047, 40.7063616 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00354997, 40.70869248 ], [ -74.00344334, 40.70878515 ], [ -74.00336753, 40.7087347 ], [ -74.00347272, 40.708641 ], [ -74.00354997, 40.70869248 ] ] ] } }, { "type": "Feature", "properties": { "height": 18.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00202284, 40.70725626 ], [ -74.0020196, 40.70725789 ], [ -74.00197523, 40.70728132 ], [ -74.00182593, 40.70710011 ], [ -74.00187228, 40.70707369 ], [ -74.00202284, 40.70725626 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00376234, 40.70645019 ], [ -74.00372488, 40.70641771 ], [ -74.00366047, 40.7063616 ], [ -74.00360863, 40.70631652 ], [ -74.00358177, 40.70633429 ], [ -74.00355725, 40.70631291 ], [ -74.00360809, 40.70627899 ], [ -74.00363145, 40.70626347 ], [ -74.00370619, 40.7063285 ], [ -74.00374617, 40.70636316 ], [ -74.0037238, 40.70637808 ], [ -74.00375892, 40.70640858 ], [ -74.00378749, 40.70643351 ], [ -74.00376234, 40.70645019 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00257539, 40.70956716 ], [ -74.00251413, 40.70962129 ], [ -74.00238962, 40.70954101 ], [ -74.00245223, 40.70948578 ], [ -74.00257539, 40.70956716 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00397308, 40.70671979 ], [ -74.00392197, 40.70675309 ], [ -74.00380707, 40.70662636 ], [ -74.00378973, 40.70660729 ], [ -74.00384435, 40.70657856 ], [ -74.00397308, 40.70671979 ] ] ] } }, { "type": "Feature", "properties": { "height": 75.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00395763, 40.70980658 ], [ -74.00385127, 40.70990021 ], [ -74.00378012, 40.70985377 ], [ -74.00388639, 40.70976021 ], [ -74.00395763, 40.70980658 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00373943, 40.70719797 ], [ -74.00357638, 40.70727907 ], [ -74.00353434, 40.70723011 ], [ -74.00360827, 40.70719327 ], [ -74.00369775, 40.7071488 ], [ -74.00373943, 40.70719797 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00190624, 40.70755732 ], [ -74.0018129, 40.70760512 ], [ -74.00176215, 40.70754778 ], [ -74.00176664, 40.70754547 ], [ -74.00174238, 40.70751816 ], [ -74.00183114, 40.7074726 ], [ -74.00190624, 40.70755732 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00360809, 40.70627899 ], [ -74.00355725, 40.70631291 ], [ -74.00354979, 40.7063065 ], [ -74.00341361, 40.70618808 ], [ -74.00346454, 40.70615417 ], [ -74.00360809, 40.70627899 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00106101, 40.70835561 ], [ -74.0010055, 40.70838325 ], [ -74.00088288, 40.7082329 ], [ -74.00093381, 40.70820818 ], [ -74.00103092, 40.70832081 ], [ -74.00106101, 40.70835561 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0036178, 40.70732722 ], [ -74.00357638, 40.70727907 ], [ -74.00373943, 40.70719797 ], [ -74.00377958, 40.70724557 ], [ -74.0036178, 40.70732722 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0033174, 40.7072056 ], [ -74.00326179, 40.70723318 ], [ -74.00322622, 40.70719191 ], [ -74.0031434, 40.70709562 ], [ -74.00319819, 40.70706702 ], [ -74.0033174, 40.7072056 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00328398, 40.7074741 ], [ -74.00322173, 40.70750481 ], [ -74.00311995, 40.70738571 ], [ -74.0031822, 40.70735507 ], [ -74.00328398, 40.7074741 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0027767, 40.70740206 ], [ -74.00269505, 40.70743842 ], [ -74.00269163, 40.70743992 ], [ -74.00262453, 40.70735241 ], [ -74.00270664, 40.70730931 ], [ -74.0027767, 40.70740206 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00215381, 40.70807812 ], [ -74.00208545, 40.70811359 ], [ -74.0019993, 40.70800818 ], [ -74.00206991, 40.70797332 ], [ -74.00211995, 40.70803168 ], [ -74.0021159, 40.70803372 ], [ -74.00215381, 40.70807812 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00179143, 40.70742766 ], [ -74.00177374, 40.70743719 ], [ -74.00177517, 40.70743876 ], [ -74.00163638, 40.7075136 ], [ -74.00159874, 40.70746777 ], [ -74.00175352, 40.70738442 ], [ -74.00176134, 40.70739382 ], [ -74.00179143, 40.70742766 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00239061, 40.70692286 ], [ -74.00231749, 40.70696031 ], [ -74.00224023, 40.70686382 ], [ -74.00231102, 40.70682337 ], [ -74.00239061, 40.70692286 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00175352, 40.70738442 ], [ -74.00159874, 40.70746777 ], [ -74.00156182, 40.70742296 ], [ -74.00171633, 40.70733961 ], [ -74.00175352, 40.70738442 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00103092, 40.70832081 ], [ -74.00093381, 40.70820818 ], [ -74.00092851, 40.70820212 ], [ -74.00098708, 40.70817277 ], [ -74.00108949, 40.70829146 ], [ -74.00103092, 40.70832081 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00183114, 40.7074726 ], [ -74.00174238, 40.70751816 ], [ -74.00167052, 40.707555 ], [ -74.00163638, 40.7075136 ], [ -74.00177517, 40.70743876 ], [ -74.00177374, 40.70743719 ], [ -74.00179143, 40.70742766 ], [ -74.00183114, 40.7074726 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00354979, 40.7063065 ], [ -74.00350398, 40.70633708 ], [ -74.0033669, 40.70621777 ], [ -74.00341361, 40.70618808 ], [ -74.00354979, 40.7063065 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00253739, 40.70723399 ], [ -74.00247047, 40.7071584 ], [ -74.00247514, 40.70715602 ], [ -74.00246328, 40.70714261 ], [ -74.0025364, 40.70710522 ], [ -74.00260971, 40.70719688 ], [ -74.00253739, 40.70723399 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0025364, 40.70710522 ], [ -74.00246328, 40.70714261 ], [ -74.00241765, 40.70708561 ], [ -74.00239025, 40.70705122 ], [ -74.00246319, 40.70701377 ], [ -74.0025364, 40.70710522 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00246319, 40.70701377 ], [ -74.00239025, 40.70705122 ], [ -74.00231749, 40.70696031 ], [ -74.00239061, 40.70692286 ], [ -74.00246319, 40.70701377 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00105904, 40.70759348 ], [ -74.00094207, 40.70765102 ], [ -74.000895, 40.70759559 ], [ -74.00100469, 40.70754159 ], [ -74.00105904, 40.70759348 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0018129, 40.70760512 ], [ -74.00174184, 40.70764148 ], [ -74.00167052, 40.707555 ], [ -74.00174238, 40.70751816 ], [ -74.00176664, 40.70754547 ], [ -74.00176215, 40.70754778 ], [ -74.0018129, 40.70760512 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00322622, 40.70719191 ], [ -74.00316334, 40.70722316 ], [ -74.00308141, 40.70712797 ], [ -74.0031434, 40.70709562 ], [ -74.00322622, 40.70719191 ] ] ] } }, { "type": "Feature", "properties": { "height": 39.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00370457, 40.70828036 ], [ -74.0036814, 40.70829139 ], [ -74.003616, 40.70821186 ], [ -74.00369874, 40.7081727 ], [ -74.0037529, 40.70823862 ], [ -74.00371742, 40.70825537 ], [ -74.00372865, 40.70826906 ], [ -74.00370457, 40.70828036 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00225263, 40.71310798 ], [ -74.00207207, 40.7133529 ], [ -74.00204763, 40.71333799 ], [ -74.00221041, 40.71311711 ], [ -74.00225263, 40.71310798 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00139752, 40.70804237 ], [ -74.00128532, 40.70810107 ], [ -74.00123546, 40.70805408 ], [ -74.00135162, 40.70799776 ], [ -74.00139752, 40.70804237 ] ] ] } }, { "type": "Feature", "properties": { "height": 176.79 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00365894, 40.71295852 ], [ -74.00365283, 40.71297207 ], [ -74.00364097, 40.71298331 ], [ -74.0036248, 40.71299066 ], [ -74.0036063, 40.71299352 ], [ -74.00358761, 40.71299127 ], [ -74.00357108, 40.7129844 ], [ -74.0035586, 40.71297357 ], [ -74.00355177, 40.71296029 ], [ -74.00355141, 40.71294599 ], [ -74.00355752, 40.71293238 ], [ -74.00356929, 40.71292128 ], [ -74.00358537, 40.71291379 ], [ -74.00360405, 40.71291099 ], [ -74.00362265, 40.71291317 ], [ -74.00363918, 40.71292012 ], [ -74.00365157, 40.71293088 ], [ -74.00365849, 40.71294415 ], [ -74.00365894, 40.71295852 ] ] ] } }, { "type": "Feature", "properties": { "height": 3.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00314861, 40.70570458 ], [ -74.0031275, 40.705718 ], [ -74.00314573, 40.70573482 ], [ -74.00314717, 40.7057432 ], [ -74.00314367, 40.7057513 ], [ -74.00313675, 40.70575702 ], [ -74.00312813, 40.70575988 ], [ -74.0031186, 40.70576022 ], [ -74.00310899, 40.70575736 ], [ -74.00309049, 40.70574047 ], [ -74.00306839, 40.70575457 ], [ -74.00302805, 40.70571786 ], [ -74.00310755, 40.70566727 ], [ -74.00314861, 40.70570458 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00200397, 40.71333078 ], [ -74.00198583, 40.71334848 ], [ -74.00174328, 40.71323627 ], [ -74.0017581, 40.713217 ], [ -74.00200397, 40.71333078 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00369775, 40.7071488 ], [ -74.00360827, 40.70719327 ], [ -74.00356893, 40.70714751 ], [ -74.00365885, 40.70710277 ], [ -74.00369775, 40.7071488 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00152472, 40.70804611 ], [ -74.00144693, 40.70809031 ], [ -74.00139752, 40.70804237 ], [ -74.00147702, 40.70800076 ], [ -74.00152472, 40.70804611 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00157188, 40.70809078 ], [ -74.00149508, 40.70813709 ], [ -74.00144693, 40.70809031 ], [ -74.00152472, 40.70804611 ], [ -74.00157188, 40.70809078 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0028156, 40.70745367 ], [ -74.00273448, 40.70748976 ], [ -74.00272307, 40.70747499 ], [ -74.00269505, 40.70743842 ], [ -74.0027767, 40.70740206 ], [ -74.0028156, 40.70745367 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00147702, 40.70800076 ], [ -74.00139752, 40.70804237 ], [ -74.00135162, 40.70799776 ], [ -74.00143247, 40.70795847 ], [ -74.00147702, 40.70800076 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00353084, 40.70709569 ], [ -74.00347793, 40.70712197 ], [ -74.00342367, 40.70705898 ], [ -74.00347658, 40.7070327 ], [ -74.00353084, 40.70709569 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00287974, 40.70753866 ], [ -74.00279934, 40.70757441 ], [ -74.00276691, 40.70753212 ], [ -74.00284767, 40.7074963 ], [ -74.00287974, 40.70753866 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00284767, 40.7074963 ], [ -74.00276691, 40.70753212 ], [ -74.00275164, 40.7075121 ], [ -74.00273448, 40.70748976 ], [ -74.0028156, 40.70745367 ], [ -74.00284767, 40.7074963 ] ] ] } }, { "type": "Feature", "properties": { "height": 6.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00324104, 40.70890548 ], [ -74.0031858, 40.70895138 ], [ -74.00313378, 40.70891522 ], [ -74.00318894, 40.70886932 ], [ -74.00324104, 40.70890548 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00384193, 40.7095009 ], [ -74.00382639, 40.70951452 ], [ -74.00381641, 40.70950792 ], [ -74.00378533, 40.70953509 ], [ -74.00373512, 40.7095022 ], [ -74.00378174, 40.70946147 ], [ -74.00384193, 40.7095009 ] ] ] } }, { "type": "Feature", "properties": { "height": 135.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00368212, 40.71307761 ], [ -74.00366469, 40.71309777 ], [ -74.00363361, 40.71310192 ], [ -74.00360809, 40.71308858 ], [ -74.00360271, 40.71306726 ], [ -74.00361861, 40.7130497 ], [ -74.00364924, 40.71304398 ], [ -74.00367673, 40.71305521 ], [ -74.00368212, 40.71307761 ] ] ] } }, { "type": "Feature", "properties": { "height": 135.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00381893, 40.71292768 ], [ -74.0038015, 40.7129479 ], [ -74.00377042, 40.71295192 ], [ -74.00374482, 40.71293871 ], [ -74.00373952, 40.71291726 ], [ -74.00375533, 40.71289969 ], [ -74.00378605, 40.71289397 ], [ -74.00381354, 40.71290527 ], [ -74.00381893, 40.71292768 ] ] ] } }, { "type": "Feature", "properties": { "height": 135.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00347775, 40.71298338 ], [ -74.00346032, 40.7130036 ], [ -74.00342924, 40.71300768 ], [ -74.00340364, 40.71299441 ], [ -74.00339834, 40.71297309 ], [ -74.00341415, 40.71295546 ], [ -74.00344469, 40.71294981 ], [ -74.00347227, 40.71296097 ], [ -74.00347775, 40.71298338 ] ] ] } }, { "type": "Feature", "properties": { "height": 135.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00361645, 40.71283466 ], [ -74.00359902, 40.71285489 ], [ -74.00356794, 40.7128589 ], [ -74.00354243, 40.7128457 ], [ -74.00353704, 40.71282431 ], [ -74.00355294, 40.71280668 ], [ -74.00358348, 40.71280096 ], [ -74.00361097, 40.71281226 ], [ -74.00361645, 40.71283466 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00278937, 40.7089575 ], [ -74.00272541, 40.70901396 ], [ -74.00269244, 40.70899251 ], [ -74.0027564, 40.70893599 ], [ -74.00278937, 40.7089575 ] ] ] } }, { "type": "Feature", "properties": { "height": 4.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00374194, 40.71253888 ], [ -74.00368499, 40.71255379 ], [ -74.00366334, 40.71250592 ], [ -74.0037202, 40.71249087 ], [ -74.00374194, 40.71253888 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00337013, 40.70923601 ], [ -74.00332638, 40.70927455 ], [ -74.00328749, 40.70924916 ], [ -74.00333114, 40.70921068 ], [ -74.00337013, 40.70923601 ] ] ] } }, { "type": "Feature", "properties": { "height": 144.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00367268, 40.713077 ], [ -74.00366083, 40.71309191 ], [ -74.00363477, 40.71309491 ], [ -74.00361753, 40.71308558 ], [ -74.00361393, 40.71306849 ], [ -74.00362543, 40.71305548 ], [ -74.0036478, 40.71305126 ], [ -74.0036681, 40.71306059 ], [ -74.00367268, 40.713077 ] ] ] } }, { "type": "Feature", "properties": { "height": 144.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00346832, 40.71298276 ], [ -74.00345637, 40.71299767 ], [ -74.00343032, 40.71300067 ], [ -74.00341298, 40.71299141 ], [ -74.00340948, 40.71297432 ], [ -74.00342098, 40.71296131 ], [ -74.00344343, 40.71295709 ], [ -74.00346374, 40.71296642 ], [ -74.00346832, 40.71298276 ] ] ] } }, { "type": "Feature", "properties": { "height": 144.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00360702, 40.71283412 ], [ -74.00359507, 40.7128489 ], [ -74.00356911, 40.71285189 ], [ -74.00355177, 40.7128427 ], [ -74.00354818, 40.71282561 ], [ -74.00355968, 40.71281247 ], [ -74.00358213, 40.71280831 ], [ -74.00360244, 40.71281757 ], [ -74.00360702, 40.71283412 ] ] ] } }, { "type": "Feature", "properties": { "height": 144.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0038095, 40.71292706 ], [ -74.00379764, 40.71294191 ], [ -74.00377159, 40.7129449 ], [ -74.00375434, 40.71293571 ], [ -74.00375075, 40.71291862 ], [ -74.00376225, 40.71290562 ], [ -74.00378461, 40.71290126 ], [ -74.00380492, 40.71291072 ], [ -74.0038095, 40.71292706 ] ] ] } }, { "type": "Feature", "properties": { "height": 176.79 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00363298, 40.71295117 ], [ -74.0036319, 40.71295927 ], [ -74.00362669, 40.71296642 ], [ -74.00361843, 40.71297146 ], [ -74.00360818, 40.71297371 ], [ -74.00359749, 40.71297289 ], [ -74.00358815, 40.71296901 ], [ -74.00358142, 40.71296268 ], [ -74.00357845, 40.71295491 ], [ -74.00357962, 40.71294681 ], [ -74.00358474, 40.71293966 ], [ -74.003593, 40.71293462 ], [ -74.00360333, 40.71293238 ], [ -74.00361393, 40.71293319 ], [ -74.00362328, 40.71293707 ], [ -74.00363001, 40.71294341 ], [ -74.00363298, 40.71295117 ] ] ] } }, { "type": "Feature", "properties": { "height": 3.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0011344, 40.71221837 ], [ -74.00110521, 40.7122535 ], [ -74.00107242, 40.71223771 ], [ -74.00110162, 40.71220257 ], [ -74.0011344, 40.71221837 ] ] ] } }, { "type": "Feature", "properties": { "height": 63.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00384893, 40.70819136 ], [ -74.00379917, 40.70821492 ], [ -74.00378255, 40.70819456 ], [ -74.00383222, 40.70817107 ], [ -74.00384893, 40.70819136 ] ] ] } }, { "type": "Feature", "properties": { "height": 170.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00253551, 40.71369921 ], [ -74.0025064, 40.71371542 ], [ -74.00248457, 40.71369268 ], [ -74.00251368, 40.71367661 ], [ -74.00253551, 40.71369921 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00242043, 40.71238962 ], [ -74.00240211, 40.71241277 ], [ -74.00237129, 40.71239888 ], [ -74.00238962, 40.71237559 ], [ -74.00242043, 40.71238962 ] ] ] } }, { "type": "Feature", "properties": { "height": 180.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00252518, 40.71369581 ], [ -74.00252491, 40.71369799 ], [ -74.00252374, 40.71370078 ], [ -74.00252104, 40.71370391 ], [ -74.00251583, 40.71370657 ], [ -74.00251134, 40.71370738 ], [ -74.00250757, 40.71370718 ], [ -74.00250505, 40.71370677 ], [ -74.00249975, 40.71370432 ], [ -74.00249553, 40.71369908 ], [ -74.00249499, 40.71369567 ], [ -74.00249508, 40.71369438 ], [ -74.00249598, 40.71369159 ], [ -74.00249778, 40.7136892 ], [ -74.00250182, 40.71368628 ], [ -74.00250838, 40.71368451 ], [ -74.00251233, 40.71368457 ], [ -74.00251601, 40.71368539 ], [ -74.00252024, 40.71368737 ], [ -74.00252392, 40.71369131 ], [ -74.00252518, 40.71369581 ] ] ] } }, { "type": "Feature", "properties": { "height": 182.79 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00362121, 40.71294586 ], [ -74.00360235, 40.71296547 ], [ -74.0035904, 40.71295852 ], [ -74.00361088, 40.7129385 ], [ -74.00362121, 40.71294586 ] ] ] } }, { "type": "Feature", "properties": { "height": 2.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00253784, 40.70519166 ], [ -74.00246014, 40.70524301 ], [ -74.0023757, 40.70516899 ], [ -74.00245313, 40.70511791 ], [ -74.00253784, 40.70519166 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00279314, 40.7055325 ], [ -74.00271418, 40.7055833 ], [ -74.00266073, 40.70553516 ], [ -74.0027396, 40.70548442 ], [ -74.00279314, 40.7055325 ] ] ] } }, { "type": "Feature", "properties": { "height": 3.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0029428, 40.70547918 ], [ -74.00294083, 40.70548646 ], [ -74.00293607, 40.70549171 ], [ -74.00292843, 40.70549539 ], [ -74.00291954, 40.70549641 ], [ -74.00291145, 40.70549491 ], [ -74.00290687, 40.70549266 ], [ -74.00287615, 40.7054642 ], [ -74.00290948, 40.70544329 ], [ -74.00294029, 40.70547189 ], [ -74.0029428, 40.70547918 ] ] ] } }, { "type": "Feature", "properties": { "height": 44.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0022052, 40.7142359 ], [ -74.00207207, 40.71459317 ], [ -74.00192178, 40.71456075 ], [ -74.00190669, 40.71460127 ], [ -74.00187201, 40.71459378 ], [ -74.00134704, 40.71469741 ], [ -74.00133428, 40.71469639 ], [ -74.00132646, 40.71469326 ], [ -74.00126951, 40.71464879 ], [ -74.00093785, 40.71438699 ], [ -74.00093345, 40.71437542 ], [ -74.00108599, 40.71396599 ], [ -74.00109838, 40.71395796 ], [ -74.00163881, 40.7138531 ], [ -74.00165471, 40.7138565 ], [ -74.00203488, 40.7141563 ], [ -74.00206964, 40.71416379 ], [ -74.00205482, 40.71420349 ], [ -74.0022052, 40.7142359 ] ], [ [ -74.00159838, 40.7142805 ], [ -74.00159758, 40.71426368 ], [ -74.00159398, 40.71425149 ], [ -74.00158545, 40.71423597 ], [ -74.00157269, 40.71422228 ], [ -74.00155661, 40.71421091 ], [ -74.0015417, 40.71420376 ], [ -74.00152122, 40.71419756 ], [ -74.00149948, 40.71419491 ], [ -74.00148304, 40.71419511 ], [ -74.00146139, 40.71419852 ], [ -74.00144109, 40.71420505 ], [ -74.00142321, 40.71421486 ], [ -74.0014083, 40.71422718 ], [ -74.0013995, 40.71423787 ], [ -74.00139141, 40.71425347 ], [ -74.00138773, 40.71427001 ], [ -74.00138872, 40.71428676 ], [ -74.00139411, 40.71430297 ], [ -74.0014039, 40.71431808 ], [ -74.00141378, 40.71432809 ], [ -74.00142573, 40.71433688 ], [ -74.00144405, 40.7143462 ], [ -74.00146454, 40.7143524 ], [ -74.00148618, 40.71435519 ], [ -74.00150828, 40.71435458 ], [ -74.00152445, 40.71435179 ], [ -74.00154457, 40.71434518 ], [ -74.00156272, 40.71433551 ], [ -74.00157763, 40.71432319 ], [ -74.00158653, 40.71431257 ], [ -74.0015947, 40.71429698 ], [ -74.00159838, 40.7142805 ] ], [ [ -74.00132314, 40.71436677 ], [ -74.00131173, 40.71435342 ], [ -74.00130437, 40.71434287 ], [ -74.00129547, 40.71432646 ], [ -74.00129098, 40.71431516 ], [ -74.00128748, 40.71430372 ], [ -74.00128451, 40.71428608 ], [ -74.00128424, 40.71426838 ], [ -74.0012855, 40.71425449 ], [ -74.00117465, 40.71423038 ], [ -74.00113602, 40.71433129 ], [ -74.00114303, 40.71435267 ], [ -74.00123897, 40.71442859 ], [ -74.00132314, 40.71436677 ] ], [ [ -74.00140992, 40.71412839 ], [ -74.0013836, 40.71404409 ], [ -74.00129403, 40.71405308 ], [ -74.00129673, 40.7140605 ], [ -74.00125047, 40.71406622 ], [ -74.0012281, 40.7140844 ], [ -74.00119163, 40.7141849 ], [ -74.00130239, 40.714209 ], [ -74.00131173, 40.71419511 ], [ -74.00132907, 40.71417557 ], [ -74.00133922, 40.71416658 ], [ -74.00135602, 40.71415426 ], [ -74.00138081, 40.71414016 ], [ -74.00140992, 40.71412839 ] ], [ [ -74.00151403, 40.71443261 ], [ -74.00149122, 40.71443329 ], [ -74.00147558, 40.71443281 ], [ -74.00145268, 40.7144303 ], [ -74.0014375, 40.7144275 ], [ -74.00141549, 40.71442192 ], [ -74.00140129, 40.71441709 ], [ -74.00138099, 40.71440837 ], [ -74.0013668, 40.71440102 ], [ -74.00128254, 40.71446298 ], [ -74.00137875, 40.7145389 ], [ -74.00140722, 40.71454509 ], [ -74.00154053, 40.71451929 ], [ -74.00151403, 40.71443261 ] ], [ [ -74.00147028, 40.7141162 ], [ -74.00149095, 40.71411518 ], [ -74.0015064, 40.71411552 ], [ -74.00152427, 40.71411688 ], [ -74.00154709, 40.71412042 ], [ -74.001562, 40.71412376 ], [ -74.00158347, 40.7141305 ], [ -74.00160404, 40.71413887 ], [ -74.00162282, 40.71414881 ], [ -74.00170582, 40.71408828 ], [ -74.00160683, 40.71401168 ], [ -74.00157745, 40.71400637 ], [ -74.00144378, 40.7140317 ], [ -74.00147028, 40.7141162 ] ], [ [ -74.00166549, 40.71418279 ], [ -74.00168184, 40.71420349 ], [ -74.001691, 40.71421976 ], [ -74.00169585, 40.71423106 ], [ -74.00170205, 40.71425442 ], [ -74.0017034, 40.7142662 ], [ -74.0017034, 40.7142824 ], [ -74.00181964, 40.71430692 ], [ -74.00185081, 40.71421527 ], [ -74.0018421, 40.71419579 ], [ -74.00181075, 40.71417026 ], [ -74.00174301, 40.71412287 ], [ -74.00166549, 40.71418279 ] ], [ [ -74.00167564, 40.71435369 ], [ -74.00166468, 40.71436656 ], [ -74.00165507, 40.71437596 ], [ -74.00163351, 40.71439298 ], [ -74.00161518, 40.71440401 ], [ -74.00160225, 40.71441048 ], [ -74.00157224, 40.71442178 ], [ -74.00159901, 40.71450887 ], [ -74.00173601, 40.71448082 ], [ -74.00175837, 40.7144655 ], [ -74.00179377, 40.71437841 ], [ -74.00167564, 40.71435369 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00399455, 40.71576109 ], [ -74.00393733, 40.71582986 ], [ -74.00383178, 40.71577948 ], [ -74.00362651, 40.7156815 ], [ -74.00406399, 40.71515429 ], [ -74.00409103, 40.71512147 ], [ -74.00421841, 40.71496929 ], [ -74.00442179, 40.71506639 ], [ -74.00453677, 40.71512127 ], [ -74.00447003, 40.71520168 ], [ -74.00458573, 40.71525697 ], [ -74.00472254, 40.71532226 ], [ -74.00448, 40.71561409 ], [ -74.0042547, 40.71588529 ], [ -74.00399455, 40.71576109 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00198583, 40.71334848 ], [ -74.00200397, 40.71333078 ], [ -74.00201628, 40.71331886 ], [ -74.00204763, 40.71333799 ], [ -74.00207207, 40.7133529 ], [ -74.00241702, 40.71356256 ], [ -74.00255177, 40.71348909 ], [ -74.00259039, 40.7135296 ], [ -74.00293068, 40.71344551 ], [ -74.00299877, 40.71365679 ], [ -74.00293427, 40.71369152 ], [ -74.00297514, 40.71373551 ], [ -74.0024154, 40.71403619 ], [ -74.00237929, 40.71399718 ], [ -74.0023023, 40.71403851 ], [ -74.00207207, 40.71390151 ], [ -74.00208114, 40.71389266 ], [ -74.00167699, 40.71365209 ], [ -74.00171193, 40.71361812 ], [ -74.00168633, 40.71360287 ], [ -74.00171552, 40.71357447 ], [ -74.00170385, 40.71355901 ], [ -74.00169495, 40.7135424 ], [ -74.00168884, 40.71352511 ], [ -74.0016857, 40.7135074 ], [ -74.00168552, 40.71348949 ], [ -74.00168831, 40.71347165 ], [ -74.00169414, 40.71345436 ], [ -74.0016981, 40.71344598 ], [ -74.00170825, 40.71342978 ], [ -74.00171804, 40.7134178 ], [ -74.0017281, 40.71340758 ], [ -74.00174427, 40.71339471 ], [ -74.00176251, 40.71338341 ], [ -74.0017723, 40.71337837 ], [ -74.00179305, 40.71337 ], [ -74.00180392, 40.71336645 ], [ -74.00181497, 40.71336359 ], [ -74.00183787, 40.71335951 ], [ -74.00184955, 40.71335822 ], [ -74.001873, 40.7133574 ], [ -74.00189645, 40.7133589 ], [ -74.00190794, 40.71336046 ], [ -74.00193049, 40.71336537 ], [ -74.0019587, 40.71333799 ], [ -74.00198223, 40.71335202 ], [ -74.00198583, 40.71334848 ] ], [ [ -74.00206245, 40.71350216 ], [ -74.00193678, 40.71342522 ], [ -74.00188872, 40.71347057 ], [ -74.00189213, 40.7134739 ], [ -74.00189698, 40.71348119 ], [ -74.00189923, 40.71348929 ], [ -74.00189923, 40.71349338 ], [ -74.00189698, 40.71350148 ], [ -74.00189483, 40.71350516 ], [ -74.00188863, 40.71351196 ], [ -74.00188028, 40.71351721 ], [ -74.00187039, 40.71352061 ], [ -74.0018597, 40.71352177 ], [ -74.00184892, 40.71352082 ], [ -74.00183895, 40.71351768 ], [ -74.00180814, 40.71354669 ], [ -74.00185108, 40.71357311 ], [ -74.00183931, 40.71358421 ], [ -74.00192205, 40.71363487 ], [ -74.00206245, 40.71350216 ] ], [ [ -74.00241423, 40.71384792 ], [ -74.00240067, 40.71383097 ], [ -74.0022405, 40.71366067 ], [ -74.00228362, 40.71363718 ], [ -74.0022069, 40.71359109 ], [ -74.00219352, 40.71358319 ], [ -74.00207611, 40.71369656 ], [ -74.00217852, 40.71375811 ], [ -74.00215938, 40.7137765 ], [ -74.00234309, 40.71388667 ], [ -74.00241423, 40.71384792 ] ], [ [ -74.00278973, 40.71359667 ], [ -74.00276143, 40.71349719 ], [ -74.00259695, 40.71353641 ], [ -74.00260063, 40.71354022 ], [ -74.0026999, 40.71364426 ], [ -74.00278973, 40.71359667 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00226368, 40.71593349 ], [ -74.00205482, 40.71583429 ], [ -74.00184587, 40.71573502 ], [ -74.002184, 40.71532322 ], [ -74.00281075, 40.7156211 ], [ -74.00247262, 40.71603277 ], [ -74.00226368, 40.71593349 ] ] ] } }, { "type": "Feature", "properties": { "height": 179.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00399455, 40.71576109 ], [ -74.00380815, 40.71566979 ], [ -74.0042812, 40.71510928 ], [ -74.00447003, 40.71520168 ], [ -74.00458573, 40.71525697 ], [ -74.00472254, 40.71532226 ], [ -74.00448, 40.71561409 ], [ -74.0042547, 40.71588529 ], [ -74.00399455, 40.71576109 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00249454, 40.71649637 ], [ -74.0026681, 40.71629129 ], [ -74.00293571, 40.71642236 ], [ -74.00319541, 40.71654962 ], [ -74.00280859, 40.71700689 ], [ -74.00228119, 40.71674857 ], [ -74.00249454, 40.71649637 ] ] ] } }, { "type": "Feature", "properties": { "height": 5.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00149813, 40.71717459 ], [ -74.00098331, 40.71692498 ], [ -74.0012705, 40.7165821 ], [ -74.00136347, 40.71647098 ], [ -74.00137372, 40.71647588 ], [ -74.0015011, 40.71653777 ], [ -74.00175038, 40.71665856 ], [ -74.00187821, 40.71672059 ], [ -74.00149813, 40.71717459 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00149813, 40.71717459 ], [ -74.00148511, 40.71714967 ], [ -74.00102032, 40.71692328 ], [ -74.00098331, 40.71692498 ], [ -74.0012705, 40.7165821 ], [ -74.0012802, 40.71658761 ], [ -74.00137372, 40.71647588 ], [ -74.0015011, 40.71653777 ], [ -74.00149409, 40.71654608 ], [ -74.00174328, 40.716667 ], [ -74.00175038, 40.71665856 ], [ -74.00187821, 40.71672059 ], [ -74.00149813, 40.71717459 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00249454, 40.71649637 ], [ -74.00293571, 40.71642236 ], [ -74.00319541, 40.71654962 ], [ -74.00280859, 40.71700689 ], [ -74.00228119, 40.71674857 ], [ -74.00249454, 40.71649637 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00226368, 40.71593349 ], [ -74.00230033, 40.7158893 ], [ -74.00244684, 40.71571221 ], [ -74.00223789, 40.71561287 ], [ -74.00209048, 40.71579112 ], [ -74.00205482, 40.71583429 ], [ -74.00184587, 40.71573502 ], [ -74.002184, 40.71532322 ], [ -74.00281075, 40.7156211 ], [ -74.00247262, 40.71603277 ], [ -74.00226368, 40.71593349 ] ] ] } }, { "type": "Feature", "properties": { "height": 60.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00407145, 40.71662036 ], [ -74.00396041, 40.71675279 ], [ -74.00274535, 40.71615941 ], [ -74.00277652, 40.71612291 ], [ -74.00290705, 40.71597006 ], [ -74.00407145, 40.71662036 ] ] ] } }, { "type": "Feature", "properties": { "height": 57.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00402887, 40.71616281 ], [ -74.00389807, 40.71632268 ], [ -74.0038307, 40.71629068 ], [ -74.00376225, 40.7163745 ], [ -74.00295188, 40.71592287 ], [ -74.00311905, 40.71573188 ], [ -74.00402887, 40.71616281 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00231165, 40.71589489 ], [ -74.00230033, 40.7158893 ], [ -74.00244684, 40.71571221 ], [ -74.00223789, 40.71561287 ], [ -74.00209048, 40.71579112 ], [ -74.00207889, 40.7157852 ], [ -74.00205527, 40.71581468 ], [ -74.00187659, 40.71572957 ], [ -74.00219109, 40.71534657 ], [ -74.00278003, 40.71562648 ], [ -74.00246553, 40.71600941 ], [ -74.00228775, 40.71592491 ], [ -74.00231165, 40.71589489 ] ] ] } }, { "type": "Feature", "properties": { "height": 41.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00231165, 40.71589489 ], [ -74.00230033, 40.7158893 ], [ -74.00244684, 40.71571221 ], [ -74.00223789, 40.71561287 ], [ -74.00209048, 40.71579112 ], [ -74.00207889, 40.7157852 ], [ -74.00206515, 40.71577832 ], [ -74.00204521, 40.71580235 ], [ -74.00188782, 40.71572766 ], [ -74.0021937, 40.71535508 ], [ -74.0027688, 40.71562839 ], [ -74.00246292, 40.7160009 ], [ -74.00230572, 40.71592621 ], [ -74.00232584, 40.7159019 ], [ -74.00231165, 40.71589489 ] ] ] } }, { "type": "Feature", "properties": { "height": 33.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00395619, 40.71505447 ], [ -74.00392861, 40.71508702 ], [ -74.00391298, 40.7151054 ], [ -74.00342053, 40.71486307 ], [ -74.00348745, 40.71478429 ], [ -74.00344263, 40.7147623 ], [ -74.00342825, 40.71475522 ], [ -74.00334588, 40.71471471 ], [ -74.00345457, 40.71458677 ], [ -74.00354387, 40.71463068 ], [ -74.00347739, 40.71470899 ], [ -74.00352958, 40.71473466 ], [ -74.00366163, 40.71457928 ], [ -74.00393939, 40.71471586 ], [ -74.00415409, 40.71482147 ], [ -74.00395619, 40.71505447 ] ] ] } }, { "type": "Feature", "properties": { "height": 56.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00138548, 40.71702126 ], [ -74.00122145, 40.71694167 ], [ -74.00110233, 40.716884 ], [ -74.00139294, 40.71653961 ], [ -74.00179529, 40.71673482 ], [ -74.00150469, 40.71707906 ], [ -74.00138548, 40.71702126 ] ] ] } }, { "type": "Feature", "properties": { "height": 55.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00309022, 40.71657672 ], [ -74.00277985, 40.71694078 ], [ -74.0023854, 40.71674762 ], [ -74.00254323, 40.71656249 ], [ -74.00292897, 40.71649767 ], [ -74.00309022, 40.71657672 ] ] ] } }, { "type": "Feature", "properties": { "height": 78.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00221184, 40.71727277 ], [ -74.00205338, 40.71745817 ], [ -74.0017502, 40.7173094 ], [ -74.00186572, 40.71717411 ], [ -74.00198592, 40.71703351 ], [ -74.00213854, 40.71710841 ], [ -74.00217789, 40.71706232 ], [ -74.00210872, 40.71702827 ], [ -74.00222505, 40.7168923 ], [ -74.00244882, 40.71700219 ], [ -74.00229233, 40.71718528 ], [ -74.00225811, 40.71716846 ], [ -74.00218157, 40.717258 ], [ -74.00221184, 40.71727277 ] ] ] } }, { "type": "Feature", "properties": { "height": 165.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00447003, 40.71520168 ], [ -74.0042812, 40.71510928 ], [ -74.00380815, 40.71566979 ], [ -74.00399455, 40.71576109 ], [ -74.00393733, 40.71582986 ], [ -74.00383178, 40.71577948 ], [ -74.00362651, 40.7156815 ], [ -74.00406399, 40.71515429 ], [ -74.00409103, 40.71512147 ], [ -74.00421841, 40.71496929 ], [ -74.00442179, 40.71506639 ], [ -74.00453677, 40.71512127 ], [ -74.00447003, 40.71520168 ] ] ] } }, { "type": "Feature", "properties": { "height": 84.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0042335, 40.71418851 ], [ -74.0040471, 40.71410319 ], [ -74.00407693, 40.71406547 ], [ -74.00395709, 40.71401059 ], [ -74.00389708, 40.71408637 ], [ -74.0037724, 40.71424421 ], [ -74.00356821, 40.71409631 ], [ -74.00367727, 40.71383512 ], [ -74.00376961, 40.71380632 ], [ -74.00433681, 40.71406601 ], [ -74.0042335, 40.71418851 ] ] ] } }, { "type": "Feature", "properties": { "height": 49.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00376225, 40.7163745 ], [ -74.0038307, 40.71629068 ], [ -74.00389807, 40.71632268 ], [ -74.00402887, 40.71616281 ], [ -74.00432989, 40.71630539 ], [ -74.00433232, 40.7163092 ], [ -74.00428237, 40.71636326 ], [ -74.00410792, 40.71656712 ], [ -74.00376225, 40.7163745 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00214788, 40.7188764 ], [ -74.00204592, 40.71899609 ], [ -74.00150927, 40.71875432 ], [ -74.00166261, 40.71857131 ], [ -74.00187578, 40.71866738 ], [ -74.00182602, 40.71873131 ], [ -74.00187219, 40.71875208 ], [ -74.00214788, 40.7188764 ] ] ] } }, { "type": "Feature", "properties": { "height": 105.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00307557, 40.7189547 ], [ -74.00291082, 40.71916351 ], [ -74.00286555, 40.71914281 ], [ -74.00275658, 40.71909311 ], [ -74.00282737, 40.71900331 ], [ -74.00279422, 40.71898819 ], [ -74.00251251, 40.71885951 ], [ -74.00260638, 40.71874036 ], [ -74.00307557, 40.7189547 ] ] ] } }, { "type": "Feature", "properties": { "height": 48.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00373557, 40.71700608 ], [ -74.00355671, 40.71691858 ], [ -74.00357935, 40.71689189 ], [ -74.0035621, 40.71688352 ], [ -74.00336214, 40.71678561 ], [ -74.0033395, 40.7168123 ], [ -74.00320772, 40.71674782 ], [ -74.00332252, 40.71661199 ], [ -74.00385037, 40.71687031 ], [ -74.00373557, 40.71700608 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0042335, 40.71418851 ], [ -74.00402599, 40.71443472 ], [ -74.0037724, 40.71424421 ], [ -74.00389708, 40.71408637 ], [ -74.00395332, 40.71411218 ], [ -74.0039835, 40.71407398 ], [ -74.0040471, 40.71410319 ], [ -74.0042335, 40.71418851 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00362489, 40.71713707 ], [ -74.0035701, 40.71720176 ], [ -74.00333447, 40.71708662 ], [ -74.00330042, 40.7170698 ], [ -74.00322038, 40.71703065 ], [ -74.00312633, 40.71714198 ], [ -74.00310684, 40.71716506 ], [ -74.00290184, 40.71706477 ], [ -74.00300443, 40.71694337 ], [ -74.00303129, 40.71695658 ], [ -74.00309704, 40.71687882 ], [ -74.00362489, 40.71713707 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00091054, 40.71733126 ], [ -74.00105418, 40.71712816 ], [ -74.00138494, 40.7172934 ], [ -74.00138315, 40.71730436 ], [ -74.00123151, 40.71746682 ], [ -74.00099885, 40.71733997 ], [ -74.00098367, 40.71736128 ], [ -74.00091054, 40.71733126 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00429351, 40.71759448 ], [ -74.00422057, 40.71768531 ], [ -74.00370951, 40.717453 ], [ -74.00381174, 40.71733269 ], [ -74.00419667, 40.71751162 ], [ -74.00417448, 40.71753919 ], [ -74.00429351, 40.71759448 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0017034, 40.7142824 ], [ -74.0017007, 40.71430106 ], [ -74.00169513, 40.71431931 ], [ -74.00168669, 40.71433701 ], [ -74.00167564, 40.71435369 ], [ -74.00166468, 40.71436656 ], [ -74.00165507, 40.71437596 ], [ -74.00163351, 40.71439298 ], [ -74.00161518, 40.71440401 ], [ -74.00160225, 40.71441048 ], [ -74.00157224, 40.71442178 ], [ -74.00154359, 40.7144288 ], [ -74.00151403, 40.71443261 ], [ -74.00149122, 40.71443329 ], [ -74.00147558, 40.71443281 ], [ -74.00145268, 40.7144303 ], [ -74.0014375, 40.7144275 ], [ -74.00141549, 40.71442192 ], [ -74.00140129, 40.71441709 ], [ -74.00138099, 40.71440837 ], [ -74.0013668, 40.71440102 ], [ -74.00135081, 40.71439067 ], [ -74.00133608, 40.7143793 ], [ -74.00132314, 40.71436677 ], [ -74.00131173, 40.71435342 ], [ -74.00130437, 40.71434287 ], [ -74.00129547, 40.71432646 ], [ -74.00129098, 40.71431516 ], [ -74.00128748, 40.71430372 ], [ -74.00128451, 40.71428608 ], [ -74.0012855, 40.71425449 ], [ -74.0012917, 40.71423127 ], [ -74.00130239, 40.714209 ], [ -74.00131173, 40.71419511 ], [ -74.00132907, 40.71417557 ], [ -74.00133922, 40.71416658 ], [ -74.00135602, 40.71415426 ], [ -74.00138081, 40.71414016 ], [ -74.00140992, 40.71412839 ], [ -74.00143947, 40.71412055 ], [ -74.00147028, 40.7141162 ], [ -74.00149095, 40.71411518 ], [ -74.0015064, 40.71411552 ], [ -74.00152427, 40.71411688 ], [ -74.00154709, 40.71412042 ], [ -74.001562, 40.71412376 ], [ -74.00158347, 40.7141305 ], [ -74.00160404, 40.71413887 ], [ -74.00162282, 40.71414881 ], [ -74.00164582, 40.71416461 ], [ -74.00166549, 40.71418279 ], [ -74.00168184, 40.71420349 ], [ -74.001691, 40.71421976 ], [ -74.00169585, 40.71423106 ], [ -74.00170205, 40.71425442 ], [ -74.0017034, 40.7142662 ], [ -74.0017034, 40.7142824 ] ], [ [ -74.00159838, 40.7142805 ], [ -74.00159758, 40.71426368 ], [ -74.00159398, 40.71425149 ], [ -74.00158545, 40.71423597 ], [ -74.00157269, 40.71422228 ], [ -74.00155661, 40.71421091 ], [ -74.0015417, 40.71420376 ], [ -74.00152122, 40.71419756 ], [ -74.00149948, 40.71419491 ], [ -74.00148304, 40.71419511 ], [ -74.00146139, 40.71419852 ], [ -74.00144109, 40.71420505 ], [ -74.00142321, 40.71421486 ], [ -74.0014083, 40.71422718 ], [ -74.0013995, 40.71423787 ], [ -74.00139141, 40.71425347 ], [ -74.00138773, 40.71427001 ], [ -74.00138872, 40.71428676 ], [ -74.00139411, 40.71430297 ], [ -74.0014039, 40.71431808 ], [ -74.00141378, 40.71432809 ], [ -74.00142573, 40.71433688 ], [ -74.00144405, 40.7143462 ], [ -74.00146454, 40.7143524 ], [ -74.00148618, 40.71435519 ], [ -74.00150828, 40.71435458 ], [ -74.00152445, 40.71435179 ], [ -74.00154457, 40.71434518 ], [ -74.00156272, 40.71433551 ], [ -74.00157763, 40.71432319 ], [ -74.00158653, 40.71431257 ], [ -74.0015947, 40.71429698 ], [ -74.00159838, 40.7142805 ] ] ] } }, { "type": "Feature", "properties": { "height": 67.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0039764, 40.7178927 ], [ -74.0038748, 40.71800987 ], [ -74.00340768, 40.71779826 ], [ -74.0035056, 40.71767952 ], [ -74.0039764, 40.7178927 ] ] ] } }, { "type": "Feature", "properties": { "height": 35.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00162237, 40.71778458 ], [ -74.00159263, 40.71781917 ], [ -74.00158051, 40.71781317 ], [ -74.00156039, 40.7178031 ], [ -74.00154242, 40.717824 ], [ -74.0014843, 40.71779499 ], [ -74.001312, 40.7179953 ], [ -74.0011698, 40.71792967 ], [ -74.00146462, 40.71760326 ], [ -74.00159883, 40.71767019 ], [ -74.00164617, 40.71769382 ], [ -74.00160198, 40.71774516 ], [ -74.00163998, 40.71776408 ], [ -74.00162237, 40.71778458 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0038748, 40.71800987 ], [ -74.003775, 40.7181248 ], [ -74.00331174, 40.71791496 ], [ -74.00340768, 40.71779826 ], [ -74.0038748, 40.71800987 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0039764, 40.7178927 ], [ -74.0035056, 40.71767952 ], [ -74.00359938, 40.71756548 ], [ -74.00407387, 40.71778036 ], [ -74.0039764, 40.7178927 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00326188, 40.71755846 ], [ -74.00281345, 40.71734202 ], [ -74.00290903, 40.71722722 ], [ -74.00335764, 40.71744367 ], [ -74.00326188, 40.71755846 ] ] ] } }, { "type": "Feature", "properties": { "height": 62.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00327284, 40.71858751 ], [ -74.00310091, 40.71880491 ], [ -74.00270942, 40.71862571 ], [ -74.00280635, 40.71851078 ], [ -74.00307351, 40.71863306 ], [ -74.0030833, 40.71863756 ], [ -74.00307189, 40.71865192 ], [ -74.00311043, 40.71866949 ], [ -74.00320107, 40.7185547 ], [ -74.00322047, 40.71856361 ], [ -74.00323565, 40.71854441 ], [ -74.00326269, 40.71855687 ], [ -74.0032476, 40.71857601 ], [ -74.00327284, 40.71858751 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00281479, 40.71809798 ], [ -74.00273718, 40.71819098 ], [ -74.00220151, 40.71793198 ], [ -74.00227913, 40.71783911 ], [ -74.00281479, 40.71809798 ] ] ] } }, { "type": "Feature", "properties": { "height": 46.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.003775, 40.7181248 ], [ -74.00368077, 40.71823326 ], [ -74.0032211, 40.71802506 ], [ -74.00331174, 40.71791496 ], [ -74.003775, 40.7181248 ] ] ] } }, { "type": "Feature", "properties": { "height": 82.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00308393, 40.71772112 ], [ -74.00305069, 40.71776082 ], [ -74.00308078, 40.71777532 ], [ -74.00301081, 40.71785927 ], [ -74.00285621, 40.71778471 ], [ -74.0027971, 40.71775598 ], [ -74.00280294, 40.71774897 ], [ -74.00271724, 40.71770771 ], [ -74.00271167, 40.71771431 ], [ -74.00262103, 40.71767019 ], [ -74.00272352, 40.71754716 ], [ -74.00308393, 40.71772112 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00244684, 40.71571221 ], [ -74.00230033, 40.7158893 ], [ -74.00226368, 40.71593349 ], [ -74.00205482, 40.71583429 ], [ -74.00209048, 40.71579112 ], [ -74.00223789, 40.71561287 ], [ -74.00244684, 40.71571221 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0035701, 40.71720176 ], [ -74.00345655, 40.7173363 ], [ -74.00310684, 40.71716506 ], [ -74.00312633, 40.71714198 ], [ -74.00322038, 40.71703065 ], [ -74.00330042, 40.7170698 ], [ -74.00325407, 40.71712461 ], [ -74.0032882, 40.7171413 ], [ -74.00333447, 40.71708662 ], [ -74.0035701, 40.71720176 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00213028, 40.7176595 ], [ -74.00189573, 40.71794002 ], [ -74.0017361, 40.71786138 ], [ -74.00174697, 40.71784667 ], [ -74.00197289, 40.7175842 ], [ -74.00213028, 40.7176595 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00281479, 40.71809798 ], [ -74.00227913, 40.71783911 ], [ -74.0023456, 40.71775939 ], [ -74.00288127, 40.71801838 ], [ -74.00281479, 40.71809798 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00204754, 40.71848607 ], [ -74.00198421, 40.7185675 ], [ -74.00197532, 40.71857887 ], [ -74.00195259, 40.71856872 ], [ -74.00187578, 40.71866738 ], [ -74.00166261, 40.71857131 ], [ -74.00181982, 40.7183836 ], [ -74.00204754, 40.71848607 ] ] ] } }, { "type": "Feature", "properties": { "height": 61.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00268067, 40.71711781 ], [ -74.00253847, 40.7172868 ], [ -74.00231272, 40.71717677 ], [ -74.00246184, 40.71699968 ], [ -74.00261061, 40.71707219 ], [ -74.00260369, 40.71708036 ], [ -74.00268067, 40.71711781 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00341343, 40.71910898 ], [ -74.00323817, 40.719331 ], [ -74.00322981, 40.71934169 ], [ -74.00305617, 40.71926237 ], [ -74.00323979, 40.71902966 ], [ -74.00341343, 40.71910898 ] ] ] } }, { "type": "Feature", "properties": { "height": 30.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00411744, 40.71813508 ], [ -74.00393769, 40.71836161 ], [ -74.00376198, 40.71828086 ], [ -74.00394182, 40.7180544 ], [ -74.00411744, 40.71813508 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00203164, 40.71800572 ], [ -74.00191791, 40.71795071 ], [ -74.00189573, 40.71794002 ], [ -74.00213028, 40.7176595 ], [ -74.00226619, 40.71772527 ], [ -74.00203164, 40.71800572 ] ] ] } }, { "type": "Feature", "properties": { "height": 40.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00251889, 40.71845236 ], [ -74.00246382, 40.71851827 ], [ -74.00192043, 40.7182686 ], [ -74.00198322, 40.7181935 ], [ -74.00251889, 40.71845236 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00246202, 40.71892351 ], [ -74.00274374, 40.71905219 ], [ -74.00275757, 40.71905846 ], [ -74.00273835, 40.7190829 ], [ -74.00264654, 40.71919926 ], [ -74.00236519, 40.71904607 ], [ -74.00246202, 40.71892351 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00417745, 40.7189711 ], [ -74.0041505, 40.71900508 ], [ -74.00412049, 40.719043 ], [ -74.00398781, 40.71921076 ], [ -74.00383393, 40.71914036 ], [ -74.00402348, 40.71890057 ], [ -74.00417745, 40.7189711 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0025638, 40.71738062 ], [ -74.00236923, 40.71761191 ], [ -74.00221382, 40.71753702 ], [ -74.00238621, 40.71733541 ], [ -74.00240992, 40.71730559 ], [ -74.0025638, 40.71738062 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00402348, 40.71890057 ], [ -74.00383393, 40.71914036 ], [ -74.00368122, 40.71907051 ], [ -74.00387067, 40.71883071 ], [ -74.00402348, 40.71890057 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00273718, 40.71819098 ], [ -74.00268184, 40.7182573 ], [ -74.00214618, 40.7179983 ], [ -74.00220151, 40.71793198 ], [ -74.00273718, 40.71819098 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00262839, 40.71832116 ], [ -74.00257297, 40.71838748 ], [ -74.00203739, 40.71812862 ], [ -74.00209273, 40.7180623 ], [ -74.00262839, 40.71832116 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00373557, 40.71700608 ], [ -74.00367924, 40.7170728 ], [ -74.00345457, 40.71696277 ], [ -74.00336932, 40.7169211 ], [ -74.00315139, 40.71681441 ], [ -74.00320772, 40.71674782 ], [ -74.0033395, 40.7168123 ], [ -74.00355671, 40.71691858 ], [ -74.00373557, 40.71700608 ] ] ] } }, { "type": "Feature", "properties": { "height": 11.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.001911, 40.71755336 ], [ -74.00168525, 40.71781576 ], [ -74.00162237, 40.71778458 ], [ -74.00163998, 40.71776408 ], [ -74.00160198, 40.71774516 ], [ -74.00164617, 40.71769382 ], [ -74.00159883, 40.71767019 ], [ -74.00176242, 40.7174801 ], [ -74.001911, 40.71755336 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0038731, 40.7184877 ], [ -74.0037149, 40.7186878 ], [ -74.00368158, 40.71873002 ], [ -74.00361537, 40.71869972 ], [ -74.00360109, 40.71871776 ], [ -74.00352491, 40.71868297 ], [ -74.00353551, 40.71866956 ], [ -74.00373072, 40.71842261 ], [ -74.0038731, 40.7184877 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00257297, 40.71838748 ], [ -74.00251889, 40.71845236 ], [ -74.00198322, 40.7181935 ], [ -74.00203739, 40.71812862 ], [ -74.00257297, 40.71838748 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00268184, 40.7182573 ], [ -74.00262839, 40.71832116 ], [ -74.00209273, 40.7180623 ], [ -74.00214618, 40.7179983 ], [ -74.00268184, 40.7182573 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00351009, 40.71832157 ], [ -74.00331839, 40.71856409 ], [ -74.00317484, 40.71849839 ], [ -74.00319783, 40.71846932 ], [ -74.0033059, 40.7183326 ], [ -74.00336654, 40.71825587 ], [ -74.00351009, 40.71832157 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0026372, 40.7174163 ], [ -74.00258446, 40.7173907 ], [ -74.00259084, 40.71738321 ], [ -74.00249625, 40.71733711 ], [ -74.00253847, 40.7172868 ], [ -74.00268067, 40.71711781 ], [ -74.00268409, 40.71711379 ], [ -74.00283141, 40.71718548 ], [ -74.0026372, 40.7174163 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00356668, 40.7191791 ], [ -74.00338873, 40.7194046 ], [ -74.00329153, 40.71936021 ], [ -74.0032944, 40.7193566 ], [ -74.00323817, 40.719331 ], [ -74.00341343, 40.71910898 ], [ -74.00356668, 40.7191791 ] ] ] } }, { "type": "Feature", "properties": { "height": 64.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00113899, 40.71577437 ], [ -74.00114779, 40.71576211 ], [ -74.00116144, 40.71574366 ], [ -74.00114105, 40.71573508 ], [ -74.00122397, 40.71562267 ], [ -74.00123564, 40.71560701 ], [ -74.00146121, 40.71570267 ], [ -74.0013447, 40.71586166 ], [ -74.00113899, 40.71577437 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00204592, 40.71899609 ], [ -74.0019931, 40.71905812 ], [ -74.00175173, 40.71894932 ], [ -74.00162551, 40.71889247 ], [ -74.00153209, 40.71885039 ], [ -74.00145717, 40.71881662 ], [ -74.00150927, 40.71875432 ], [ -74.00204592, 40.71899609 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00238621, 40.71733541 ], [ -74.00221382, 40.71753702 ], [ -74.00205338, 40.71745817 ], [ -74.00221184, 40.71727277 ], [ -74.00222568, 40.71725657 ], [ -74.00238621, 40.71733541 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00367924, 40.7170728 ], [ -74.00362489, 40.71713707 ], [ -74.00309704, 40.71687882 ], [ -74.00315139, 40.71681441 ], [ -74.00336932, 40.7169211 ], [ -74.00333968, 40.7169561 ], [ -74.00335621, 40.7169642 ], [ -74.00342502, 40.71699777 ], [ -74.00345457, 40.71696277 ], [ -74.00367924, 40.7170728 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0032326, 40.71834949 ], [ -74.00315382, 40.71844916 ], [ -74.00319783, 40.71846932 ], [ -74.00317484, 40.71849839 ], [ -74.00316514, 40.71851071 ], [ -74.00312498, 40.7184924 ], [ -74.00290615, 40.71839218 ], [ -74.00302302, 40.71825362 ], [ -74.0032326, 40.71834949 ] ] ] } }, { "type": "Feature", "properties": { "height": 64.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00092204, 40.71607341 ], [ -74.00093219, 40.71605939 ], [ -74.00102652, 40.71592982 ], [ -74.00103703, 40.71591531 ], [ -74.00124202, 40.71599899 ], [ -74.00112389, 40.71616016 ], [ -74.00092204, 40.71607341 ] ] ] } }, { "type": "Feature", "properties": { "height": 31.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00153649, 40.71857832 ], [ -74.00144405, 40.71852549 ], [ -74.00141549, 40.71850921 ], [ -74.00159524, 40.71828399 ], [ -74.00173484, 40.71834581 ], [ -74.00153649, 40.71857832 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00298143, 40.71924617 ], [ -74.00281578, 40.71945607 ], [ -74.00266927, 40.71938921 ], [ -74.00283492, 40.71917931 ], [ -74.00298143, 40.71924617 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00419667, 40.71751162 ], [ -74.00381174, 40.71733269 ], [ -74.003866, 40.71726875 ], [ -74.00432217, 40.71748078 ], [ -74.00427015, 40.71754566 ], [ -74.00419667, 40.71751162 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00153649, 40.71857832 ], [ -74.00133994, 40.71880899 ], [ -74.0012095, 40.7187164 ], [ -74.00140641, 40.71855606 ], [ -74.00144405, 40.71852549 ], [ -74.00153649, 40.71857832 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00140641, 40.71855606 ], [ -74.0012095, 40.7187164 ], [ -74.00107907, 40.71862401 ], [ -74.00127625, 40.7184636 ], [ -74.00140641, 40.71855606 ] ] ] } }, { "type": "Feature", "properties": { "height": 41.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00293571, 40.71642236 ], [ -74.00249454, 40.71649637 ], [ -74.0026681, 40.71629129 ], [ -74.00293571, 40.71642236 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00387067, 40.71883071 ], [ -74.00368122, 40.71907051 ], [ -74.00356255, 40.71901611 ], [ -74.00375201, 40.71877638 ], [ -74.00387067, 40.71883071 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00316451, 40.71767537 ], [ -74.0031142, 40.71773569 ], [ -74.00308393, 40.71772112 ], [ -74.00272352, 40.71754716 ], [ -74.00266558, 40.71751931 ], [ -74.00271589, 40.71745899 ], [ -74.00316451, 40.71767537 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00321445, 40.71761552 ], [ -74.00316451, 40.71767537 ], [ -74.00271589, 40.71745899 ], [ -74.00276583, 40.71739907 ], [ -74.00321445, 40.71761552 ] ] ] } }, { "type": "Feature", "properties": { "height": 38.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00101637, 40.71827629 ], [ -74.00091027, 40.71821971 ], [ -74.0010655, 40.71804807 ], [ -74.00120843, 40.71811289 ], [ -74.0010629, 40.71830121 ], [ -74.00101637, 40.71827629 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00203164, 40.71800572 ], [ -74.00183752, 40.71823776 ], [ -74.00172235, 40.71818472 ], [ -74.00188674, 40.71798809 ], [ -74.00191791, 40.71795071 ], [ -74.00203164, 40.71800572 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00336654, 40.71825587 ], [ -74.0033059, 40.7183326 ], [ -74.00326683, 40.71831476 ], [ -74.00323754, 40.71835166 ], [ -74.0032326, 40.71834949 ], [ -74.00302302, 40.71825362 ], [ -74.00311717, 40.71814176 ], [ -74.00336654, 40.71825587 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00326188, 40.71755846 ], [ -74.00321445, 40.71761552 ], [ -74.00276583, 40.71739907 ], [ -74.00281345, 40.71734202 ], [ -74.00326188, 40.71755846 ] ] ] } }, { "type": "Feature", "properties": { "height": 16.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00176242, 40.7174801 ], [ -74.00159883, 40.71767019 ], [ -74.00146462, 40.71760326 ], [ -74.00163333, 40.7174165 ], [ -74.00176242, 40.7174801 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00362561, 40.71880797 ], [ -74.00348799, 40.71898207 ], [ -74.00333402, 40.7189116 ], [ -74.00345942, 40.71875289 ], [ -74.00353875, 40.71878932 ], [ -74.00355087, 40.71877386 ], [ -74.00362561, 40.71880797 ] ] ] } }, { "type": "Feature", "properties": { "height": 37.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00193723, 40.71912361 ], [ -74.00187453, 40.71919721 ], [ -74.00156317, 40.71897247 ], [ -74.00162551, 40.71889247 ], [ -74.00175173, 40.71894932 ], [ -74.00169944, 40.71901652 ], [ -74.00193723, 40.71912361 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0040833, 40.7185839 ], [ -74.00392511, 40.71878401 ], [ -74.00381004, 40.71873138 ], [ -74.00396823, 40.71853127 ], [ -74.0040833, 40.7185839 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00114779, 40.71576211 ], [ -74.00116144, 40.71574366 ], [ -74.00114105, 40.71573508 ], [ -74.00122397, 40.71562267 ], [ -74.00139851, 40.71569682 ], [ -74.00130248, 40.71582782 ], [ -74.00114779, 40.71576211 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00230347, 40.71869366 ], [ -74.00202688, 40.7185692 ], [ -74.00201682, 40.7185822 ], [ -74.00200757, 40.71857812 ], [ -74.00198421, 40.7185675 ], [ -74.00204754, 40.71848607 ], [ -74.00236042, 40.71862687 ], [ -74.00230347, 40.71869366 ] ] ] } }, { "type": "Feature", "properties": { "height": 31.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00188674, 40.71798809 ], [ -74.00172235, 40.71818472 ], [ -74.0016168, 40.71813597 ], [ -74.0017785, 40.71794261 ], [ -74.00179592, 40.7179441 ], [ -74.00188674, 40.71798809 ] ] ] } }, { "type": "Feature", "properties": { "height": 53.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00244684, 40.71571221 ], [ -74.00223789, 40.71561287 ], [ -74.00231614, 40.71551829 ], [ -74.002525, 40.71561756 ], [ -74.00244684, 40.71571221 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00373072, 40.71842261 ], [ -74.00353551, 40.71866956 ], [ -74.00345592, 40.71863306 ], [ -74.00345942, 40.7186287 ], [ -74.00365121, 40.71838618 ], [ -74.00373072, 40.71842261 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0031593, 40.71899296 ], [ -74.00297568, 40.71922567 ], [ -74.00289187, 40.71918741 ], [ -74.00291082, 40.71916351 ], [ -74.00307557, 40.7189547 ], [ -74.0031593, 40.71899296 ] ] ] } }, { "type": "Feature", "properties": { "height": 29.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00222505, 40.7168923 ], [ -74.00210872, 40.71702827 ], [ -74.00217789, 40.71706232 ], [ -74.00213854, 40.71710841 ], [ -74.00198592, 40.71703351 ], [ -74.0021416, 40.71685138 ], [ -74.00222505, 40.7168923 ] ] ] } }, { "type": "Feature", "properties": { "height": 68.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00093219, 40.71605939 ], [ -74.00102652, 40.71592982 ], [ -74.00118049, 40.7159943 ], [ -74.00108572, 40.71612366 ], [ -74.00093219, 40.71605939 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00396823, 40.71853127 ], [ -74.00381004, 40.71873138 ], [ -74.0037149, 40.7186878 ], [ -74.0038731, 40.7184877 ], [ -74.00396823, 40.71853127 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00121498, 40.71910237 ], [ -74.00099588, 40.71928137 ], [ -74.00097774, 40.7192685 ], [ -74.00094648, 40.71929396 ], [ -74.00089491, 40.71925747 ], [ -74.00114518, 40.71905287 ], [ -74.00121498, 40.71910237 ] ] ] } }, { "type": "Feature", "properties": { "height": 13.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00225272, 40.7187533 ], [ -74.00219612, 40.71881982 ], [ -74.00191729, 40.7186942 ], [ -74.00197029, 40.71862612 ], [ -74.00225272, 40.7187533 ] ] ] } }, { "type": "Feature", "properties": { "height": 72.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00123564, 40.71560701 ], [ -74.00122397, 40.71562267 ], [ -74.00114105, 40.71573508 ], [ -74.00098897, 40.71567156 ], [ -74.00107008, 40.71556051 ], [ -74.00108374, 40.71554192 ], [ -74.00123564, 40.71560701 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00323979, 40.71902966 ], [ -74.00305617, 40.71926237 ], [ -74.00297568, 40.71922567 ], [ -74.0031593, 40.71899296 ], [ -74.00323979, 40.71902966 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00375201, 40.71877638 ], [ -74.00356255, 40.71901611 ], [ -74.00348799, 40.71898207 ], [ -74.00362561, 40.71880797 ], [ -74.00368571, 40.71873192 ], [ -74.00376018, 40.71876596 ], [ -74.00375201, 40.71877638 ] ] ] } }, { "type": "Feature", "properties": { "height": 12.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00279422, 40.71898819 ], [ -74.00274374, 40.71905219 ], [ -74.00246202, 40.71892351 ], [ -74.00251251, 40.71885951 ], [ -74.00279422, 40.71898819 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00364511, 40.71921492 ], [ -74.00346715, 40.71944041 ], [ -74.00338873, 40.7194046 ], [ -74.00356668, 40.7191791 ], [ -74.00364511, 40.71921492 ] ] ] } }, { "type": "Feature", "properties": { "height": 6.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00159524, 40.71828399 ], [ -74.00141549, 40.71850921 ], [ -74.00134147, 40.718467 ], [ -74.00151511, 40.71824858 ], [ -74.00159524, 40.71828399 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00343391, 40.71865458 ], [ -74.0032582, 40.71887688 ], [ -74.00317924, 40.71884072 ], [ -74.00335495, 40.71861849 ], [ -74.00343391, 40.71865458 ] ] ] } }, { "type": "Feature", "properties": { "height": 26.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0026372, 40.7174163 ], [ -74.00244253, 40.71764766 ], [ -74.00236923, 40.71761191 ], [ -74.0025638, 40.71738062 ], [ -74.00258446, 40.7173907 ], [ -74.0026372, 40.7174163 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00358204, 40.71835446 ], [ -74.00339034, 40.71859698 ], [ -74.00331839, 40.71856409 ], [ -74.00351009, 40.71832157 ], [ -74.00358204, 40.71835446 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00335495, 40.71861849 ], [ -74.00317924, 40.71884072 ], [ -74.00310091, 40.71880491 ], [ -74.00327284, 40.71858751 ], [ -74.00327662, 40.71858268 ], [ -74.00335495, 40.71861849 ] ] ] } }, { "type": "Feature", "properties": { "height": 57.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00138548, 40.71702126 ], [ -74.00122145, 40.71694167 ], [ -74.00130751, 40.71683981 ], [ -74.00147154, 40.71691926 ], [ -74.00138548, 40.71702126 ] ] ] } }, { "type": "Feature", "properties": { "height": 21.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00372119, 40.71924957 ], [ -74.00354324, 40.7194752 ], [ -74.00346715, 40.71944041 ], [ -74.00364511, 40.71921492 ], [ -74.00372119, 40.71924957 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00230347, 40.71869366 ], [ -74.00225272, 40.7187533 ], [ -74.00197029, 40.71862612 ], [ -74.00200757, 40.71857812 ], [ -74.00201682, 40.7185822 ], [ -74.00202688, 40.7185692 ], [ -74.00230347, 40.71869366 ] ] ] } }, { "type": "Feature", "properties": { "height": 19.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00197289, 40.7175842 ], [ -74.00174697, 40.71784667 ], [ -74.00168525, 40.71781576 ], [ -74.001911, 40.71755336 ], [ -74.00197289, 40.7175842 ] ] ] } }, { "type": "Feature", "properties": { "height": 28.7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00345942, 40.71875289 ], [ -74.00333402, 40.7189116 ], [ -74.0032582, 40.71887688 ], [ -74.00343391, 40.71865458 ], [ -74.00350973, 40.7186893 ], [ -74.00345942, 40.71875289 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00365121, 40.71838618 ], [ -74.00345942, 40.7186287 ], [ -74.00339034, 40.71859698 ], [ -74.00358204, 40.71835446 ], [ -74.00365121, 40.71838618 ] ] ] } }, { "type": "Feature", "properties": { "height": 17.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00158051, 40.71781317 ], [ -74.00156263, 40.71783387 ], [ -74.00139204, 40.71803221 ], [ -74.001312, 40.7179953 ], [ -74.0014843, 40.71779499 ], [ -74.00154242, 40.717824 ], [ -74.00156039, 40.7178031 ], [ -74.00158051, 40.71781317 ] ] ] } }, { "type": "Feature", "properties": { "height": 23.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00311977, 40.71857451 ], [ -74.00285468, 40.71845318 ], [ -74.00290615, 40.71839218 ], [ -74.00312498, 40.7184924 ], [ -74.00312139, 40.71849696 ], [ -74.00317259, 40.71852038 ], [ -74.00312723, 40.71857791 ], [ -74.00311977, 40.71857451 ] ] ] } }, { "type": "Feature", "properties": { "height": 10.8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00306048, 40.71928232 ], [ -74.00289492, 40.71949216 ], [ -74.00281578, 40.71945607 ], [ -74.00298143, 40.71924617 ], [ -74.00306048, 40.71928232 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00151511, 40.71824858 ], [ -74.00134147, 40.718467 ], [ -74.0012696, 40.71842588 ], [ -74.001297, 40.71839252 ], [ -74.0014419, 40.71821617 ], [ -74.00151511, 40.71824858 ] ] ] } }, { "type": "Feature", "properties": { "height": 14.4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00219612, 40.71881982 ], [ -74.00214788, 40.7188764 ], [ -74.00187219, 40.71875208 ], [ -74.00191729, 40.7186942 ], [ -74.00219612, 40.71881982 ] ] ] } }, { "type": "Feature", "properties": { "height": 27.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0019931, 40.71905812 ], [ -74.00193723, 40.71912361 ], [ -74.00169944, 40.71901652 ], [ -74.00175173, 40.71894932 ], [ -74.0019931, 40.71905812 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00311977, 40.71857451 ], [ -74.00307351, 40.71863306 ], [ -74.00280635, 40.71851078 ], [ -74.00285468, 40.71845318 ], [ -74.00311977, 40.71857451 ] ] ] } }, { "type": "Feature", "properties": { "height": 25.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00163737, 40.71787118 ], [ -74.00146849, 40.71806747 ], [ -74.00139204, 40.71803221 ], [ -74.00156263, 40.71783387 ], [ -74.00163737, 40.71787118 ] ] ] } }, { "type": "Feature", "properties": { "height": 20.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00134443, 40.71919401 ], [ -74.0013208, 40.71921328 ], [ -74.0011433, 40.71935817 ], [ -74.00107538, 40.7193101 ], [ -74.00127652, 40.71914588 ], [ -74.00134443, 40.71919401 ] ] ] } }, { "type": "Feature", "properties": { "height": 22.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00127625, 40.7184636 ], [ -74.00107907, 40.71862401 ], [ -74.00101142, 40.71857587 ], [ -74.00120852, 40.71841539 ], [ -74.00127625, 40.7184636 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00146849, 40.71806747 ], [ -74.00163737, 40.71787118 ], [ -74.00170888, 40.71790679 ], [ -74.00154161, 40.71810131 ], [ -74.00146849, 40.71806747 ] ] ] } }, { "type": "Feature", "properties": { "height": 24.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0014419, 40.71821617 ], [ -74.001297, 40.71839252 ], [ -74.00122855, 40.7183597 ], [ -74.00136581, 40.71818247 ], [ -74.0014419, 40.71821617 ] ] ] } }, { "type": "Feature", "properties": { "height": 43.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00115039, 40.71516042 ], [ -74.0012166, 40.71519146 ], [ -74.001229, 40.71517649 ], [ -74.00128873, 40.71520461 ], [ -74.00122091, 40.71528727 ], [ -74.00109497, 40.71522789 ], [ -74.00115039, 40.71516042 ] ] ] } }, { "type": "Feature", "properties": { "height": 61.9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00159991, 40.71673781 ], [ -74.00154053, 40.71680821 ], [ -74.00140893, 40.71674442 ], [ -74.00146831, 40.71667401 ], [ -74.00159991, 40.71673781 ] ] ] } }, { "type": "Feature", "properties": { "height": 39.2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.001229, 40.71517649 ], [ -74.0012166, 40.71519146 ], [ -74.00115039, 40.71516042 ], [ -74.00111823, 40.71514516 ], [ -74.00118094, 40.71506877 ], [ -74.00121274, 40.71508382 ], [ -74.00127921, 40.71511507 ], [ -74.001229, 40.71517649 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00149813, 40.71717459 ], [ -74.00098331, 40.71692498 ], [ -74.00102032, 40.71692328 ], [ -74.00148511, 40.71714967 ], [ -74.00149813, 40.71717459 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00162551, 40.71889247 ], [ -74.00156317, 40.71897247 ], [ -74.00148241, 40.71891432 ], [ -74.00153209, 40.71885039 ], [ -74.00162551, 40.71889247 ] ] ] } }, { "type": "Feature", "properties": { "height": 15.3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00153209, 40.71885039 ], [ -74.00148241, 40.71891432 ], [ -74.00141719, 40.71886428 ], [ -74.00145717, 40.71881662 ], [ -74.00153209, 40.71885039 ] ] ] } }, { "type": "Feature", "properties": { "height": 61.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00149068, 40.71681421 ], [ -74.00144289, 40.71687085 ], [ -74.00137363, 40.71683729 ], [ -74.00142142, 40.71678057 ], [ -74.00149068, 40.71681421 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00175038, 40.71665856 ], [ -74.00174328, 40.716667 ], [ -74.00149409, 40.71654608 ], [ -74.0015011, 40.71653777 ], [ -74.00175038, 40.71665856 ] ] ] } }, { "type": "Feature", "properties": { "height": 50.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.00137372, 40.71647588 ], [ -74.0012802, 40.71658761 ], [ -74.0012705, 40.7165821 ], [ -74.00136347, 40.71647098 ], [ -74.00137372, 40.71647588 ] ] ] } } ] } ================================================ FILE: test/asset/street.geojson ================================================ {"type":"FeatureCollection","crs":{"type":"name","properties":{"name":"urn:ogc:def:crs:OGC:1.3:CRS84"}},"features":[{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03470524300107,40.63800139985099],[-74.0347329017371,40.63795096257644],[-74.03483558848865,40.63776302887637],[-74.03484872205968,40.637740332157136],[-74.03484892288793,40.63773999888209],[-74.03487286562138,40.63770451093108]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0176043718909,40.63583349929484],[-74.01727269453217,40.63569567630449],[-74.01711050334977,40.635641455823546]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01663634217223,40.630422018181434],[-74.01634322391006,40.630285595428546]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02423774621609,40.63285893136],[-74.02173709503862,40.631687882624895]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0178857873427,40.64147118903415],[-74.01781466999286,40.64143613369539],[-74.01774227617491,40.64140075417448]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0191392433223,40.63661983929569],[-74.01918487143968,40.63657561589338]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03205002788695,40.62104063232776],[-74.03219532767785,40.62068747034614]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01659362914246,40.642511031200556],[-74.01717481839918,40.64195100363017]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01932871294058,40.63708062104839],[-74.01920592828769,40.637041414824424],[-74.01908816528687,40.63699306795091],[-74.0189771502464,40.636936209395344],[-74.01887440764712,40.63687170404401]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02174534085249,40.61719787818563],[-74.02216115992056,40.616165728681295]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01938702927659,40.622891818697134],[-74.02008667268495,40.622420952159324]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01680939238204,40.630499032721445],[-74.01663634217223,40.630422018181434]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02293270340282,40.6195046246781],[-74.0228759874347,40.619466147406214]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02735286784608,40.637179949465235],[-74.02761160755223,40.636695255305895]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.028797972029,40.6064893069155],[-74.02877704086511,40.60647298779356],[-74.02875571527782,40.60645696780577],[-74.02873400274304,40.60644125214348],[-74.02871191095689,40.60642584733819],[-74.0286894469552,40.60641075774367],[-74.0286666193131,40.60639598922106],[-74.0286434359455,40.60638154595641],[-74.02861990410851,40.60636743364372],[-74.02859603237681,40.60635365730647],[-74.02857182888502,40.606340220963155],[-74.02854730154873,40.60632713064261],[-74.02852246004055,40.6063143888552],[-74.02849731139689,40.60630200179754],[-74.02847186594998,40.60628997264991],[-74.02844613117519,40.60627830610111],[-74.02842011652582,40.60626700616926],[-74.02839383035585,40.60625607620274],[-74.02836728299782,40.60624552021948],[-74.02834048214665,40.60623534257315],[-74.02831343791465,40.60622554644416],[-74.02828615997436,40.60621613467793],[-74.02825865733908,40.60620711062265],[-74.0282309390222,40.60619847779411],[-74.02820301535544,40.6061902387025],[-74.02817468650773,40.606182340122444],[-74.0281461690201,40.606174847336945],[-74.02811747168566,40.60616776285664],[-74.02808860593485,40.60616108852142],[-74.02805958122039,40.60615482751191],[-74.0280304080935,40.60614898166823],[-74.02800109644578,40.60614355249562],[-74.02797165660925,40.606138543342034],[-74.0279420982552,40.606133954540105],[-74.02791243325369,40.606129788097185],[-74.02788267061723,40.60612604585383],[-74.02785282177598,40.60612272914743],[-74.02782289596163,40.60611983847828],[-74.02779290482424,40.60611737535124],[-74.02776285825507,40.606115340601534],[-74.02773276746417,40.60611373489653],[-74.02770264212286,40.606112558736434],[-74.02767249322115,40.60611181228611],[-74.02764233152968,40.606111496715656],[-74.02761216715875,40.60611161101746],[-74.02758200999945,40.60611215569173],[-74.02755187258046,40.606113130735466],[-74.02752176435254,40.60611453497372],[-74.02749169564649,40.606116369074165],[-74.02746167701227,40.60611863202912],[-74.02743171965909,40.60612132249574],[-74.02740183369748,40.606124439969044],[-74.02737202879813,40.60612798344163],[-74.02734231682959,40.606131951235454],[-74.02731270724277,40.606136342343156],[-74.02728321102691,40.60614115491938],[-74.02725383807237,40.60614638745412]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02724262167769,40.61244385275721],[-74.02897939713604,40.61045523894107]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02940262143127,40.63739166000046],[-74.02903480583916,40.63727591973623]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02628975684716,40.616329300249824],[-74.02621789105868,40.61629415486641],[-74.02613488275219,40.61624944121495]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03205002788695,40.62104063232776],[-74.03021113041939,40.62014827316605]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02089209156752,40.631879624970956],[-74.02064812922482,40.632198164343585],[-74.02062091808762,40.63223369500391]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03106070351704,40.63066101398831],[-74.03135989933355,40.62993051264942]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03791790452361,40.62828155836065],[-74.03819614582365,40.62759933171589]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02045920302128,40.64208105643792],[-74.02078690532231,40.641785783295624]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0343355365717,40.62984715685466],[-74.03463999435027,40.62910561340451]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0205066797487,40.634706342881785],[-74.01795101835532,40.63372994095136]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0190540606447,40.63669904500444],[-74.0191392433223,40.63661983929569]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0357344518362,40.60938952460263],[-74.03599609905362,40.609309069918936]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03327338635061,40.615350542745546],[-74.03355614976502,40.615003922173734]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03609024779193,40.63041824205555],[-74.0361061952766,40.630379442779194],[-74.03623337455562,40.6300699480701]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03437841050534,40.60846996524843],[-74.03433014177516,40.60839883831432],[-74.03423082425408,40.608252506215436],[-74.03407241761373,40.60803940896652],[-74.03398797613114,40.607935279837776],[-74.0339506262722,40.60788922006144],[-74.03390353402801,40.60783114143205],[-74.03373889156182,40.60764208898456],[-74.0337370471169,40.607639973299364],[-74.03355234053615,40.60744809037004],[-74.03350166652871,40.60739770622218],[-74.03345063198783,40.6073475342484],[-74.03339923801362,40.60729757578818],[-74.033347485706,40.60724783201338],[-74.03329537770428,40.607198305268206],[-74.0332429140091,40.60714899638979],[-74.03319009747926,40.60709990721965],[-74.0331369298741,40.60705103892952],[-74.0330834114147,40.60700239352917],[-74.0330295453987,40.60695397151976],[-74.03297533160743,40.606905774743694],[-74.03292077311959,40.60685780537748],[-74.03286587125443,40.60681006392286],[-74.03281062733204,40.60676255238926],[-74.03275504289164,40.60671527161344],[-74.03269912013252,40.60666822360464],[-74.03244706167408,40.6064575639461],[-74.03214344715784,40.6062344994004]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03996068960251,40.62327570425802],[-74.03869172982165,40.62296928612613]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03509032550566,40.60960201210761],[-74.0349769249706,40.609418817365814],[-74.03474956826928,40.60905151852509],[-74.03465241370029,40.60890825695219],[-74.03455711509572,40.608755325800786],[-74.03446045665925,40.60860021023006]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03599609905362,40.609309069918936],[-74.03603977777915,40.609295639001864]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0322115265826,40.61098246224904],[-74.03192153893677,40.61083035531361]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01793148581856,40.60467612710664],[-74.0185330188904,40.60439933699211],[-74.01864352157008,40.604337246082196],[-74.01874882288395,40.604269960167684],[-74.01884829868239,40.60419784792905],[-74.01897536777228,40.60406132600701],[-74.0190881377554,40.60391738612051],[-74.01916517337347,40.60379778367388]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01410877859782,40.63456399731041],[-74.01475422595298,40.633961648996596]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02771303825047,40.61974854921492],[-74.0282052488583,40.619172663284246]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02101552967812,40.63826308446196],[-74.0210777615255,40.63820262142591],[-74.02115312268505,40.63813169160991]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03918247321302,40.62263288348368],[-74.04002522398791,40.62283099597444],[-74.04006317946116,40.62284129398173],[-74.04014730501646,40.622863984382946]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04012487349664,40.62970080634359],[-74.04012648085242,40.629681374470195],[-74.04012761037791,40.629661922827616],[-74.04012826163778,40.62964245811714],[-74.04012843441726,40.62962298821269],[-74.04012812872033,40.629603518977795],[-74.04012734455142,40.62958405711356],[-74.0401260821354,40.629564610158745],[-74.04012434191634,40.62954518464673],[-74.0401221245585,40.62952578744598],[-74.04011943050595,40.62950642508991],[-74.04011626152277,40.62948710511668],[-74.04011261849213,40.62946783288684],[-74.04010850207892,40.629448616441486],[-74.04010391382657,40.629429462146156],[-74.04008723103344,40.62937029248916],[-74.04007010612061,40.62931119602596],[-74.04005253755129,40.62925217493478],[-74.04003452774664,40.62919323139241],[-74.04001607670882,40.629134367073966],[-74.03999718465998,40.62907558398949],[-74.03997785226211,40.62901688414889],[-74.03995808061681,40.62895826939435],[-74.03993786950608,40.628899741066],[-74.03991722113176,40.62884130234585],[-74.03989613417592,40.6287829537367],[-74.03987461127993,40.62872469808542]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01894932186951,40.64021823525207],[-74.01952692715224,40.63966502201572]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0357579567263,40.610585886666165],[-74.0357017562614,40.61051585256555]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03477265794976,40.617559536107855],[-74.03478997236586,40.61751740439846],[-74.03488298805706,40.61729114758776]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0357579567263,40.610585886666165],[-74.03591089828743,40.61043737899516],[-74.03598504676425,40.610330427922364],[-74.03604154951981,40.61021581017774],[-74.03607861165034,40.610096164429365],[-74.03609532497013,40.609974390237724],[-74.03609176175947,40.60985346055834],[-74.03606704534175,40.60977178218767],[-74.03602779636168,40.6096922689885],[-74.0359747016877,40.609617137474686],[-74.03590917963828,40.609548411939414],[-74.03583329875791,40.60948773165801]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03168478453624,40.61067684567532],[-74.03139997061318,40.61049113755576],[-74.03130872447673,40.61043915726491]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04145631606293,40.62053354081697],[-74.04150235501645,40.62078912843236],[-74.04141498112595,40.62079569976448]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02134518789724,40.64118218955396],[-74.02152938816474,40.64087026067666],[-74.02165149085279,40.64060369331658],[-74.0216797799364,40.64053053887377],[-74.02172500211859,40.640400324223044],[-74.02177423115326,40.640231098959056],[-74.02179520508874,40.64013034488874],[-74.02180047058044,40.6401050660265],[-74.02185196389816,40.63981609782905]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01861253218762,40.629859539121846],[-74.01780244173645,40.62936684005484]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01544127093105,40.63158075744509],[-74.01540472030474,40.63161907915319],[-74.01540311326855,40.63162079033804],[-74.01531174084796,40.6317091254601],[-74.01530526469786,40.6317157544236],[-74.01527869237488,40.631763890597675],[-74.01526578990223,40.63178453200153],[-74.01526362767312,40.63178838661892],[-74.0152576626588,40.6318060824506],[-74.01525214029859,40.63184690370239]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02462461252911,40.617389023513944],[-74.0252532717485,40.61667845738943]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02940982440265,40.63935795851155],[-74.02853941735353,40.63909112941787]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02623698651284,40.64012649017486],[-74.02626267406124,40.64009438133773],[-74.02628612034283,40.64007452838303]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02012665551166,40.635673785779716],[-74.02015258203039,40.63556675262543]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0206561969202,40.62137425729978],[-74.02086878854648,40.62150447906306],[-74.02090368274169,40.621526166359786]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02454267884777,40.61899006805416],[-74.02552760871232,40.61784137421778]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02676711059985,40.61657486832318],[-74.02664722173601,40.61650772129021]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0286577676278,40.63654600852422],[-74.02878300552388,40.63623927357724],[-74.02894215584342,40.63586681102552]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01875180734196,40.62431751087332],[-74.01919994798754,40.62426799817216]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02913396937063,40.63537274692008],[-74.0293562464355,40.63483669220852]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02062537093991,40.6236556048074],[-74.02113216418589,40.623051786081625]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03327338635061,40.615350542745546],[-74.03307513983295,40.61525192091846],[-74.0320208222862,40.61472745880179]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02227378599942,40.620109058620585],[-74.0228759874347,40.619466147406214]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01483594452924,40.63174861301147],[-74.0149226681643,40.63180085864727],[-74.01497945991586,40.63183524186672],[-74.01498252295062,40.6318416082242],[-74.01498609427847,40.63184946066146],[-74.01498989008698,40.63185520555968],[-74.01500918267959,40.631867170782776],[-74.01506598608867,40.63190209406991],[-74.01513323976214,40.63194324835247],[-74.01516996901509,40.63196084858922],[-74.01522261794682,40.63197103574545]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03039238356551,40.60745774941676],[-74.02997954531816,40.60712552950822]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01795101835532,40.63372994095136],[-74.01824460047568,40.633033568464015]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03574203342504,40.615075989423545],[-74.0348936622186,40.615375700441724]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02453841857515,40.63832493659562],[-74.02475437604834,40.63812141809163]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02915343608798,40.612694494295916],[-74.02899687638677,40.61285631256618],[-74.02895918888436,40.61292880496657],[-74.02894538629052,40.612955346700794],[-74.02891752157605,40.61306150707922],[-74.02891521646507,40.613169759490255],[-74.02893798627298,40.613274862412474],[-74.0289830268647,40.61337217045861],[-74.0290459533386,40.61345829828121]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03489726686202,40.60979182728423],[-74.03499657445272,40.609981250091394],[-74.034999188621,40.609986751449824],[-74.03504902861404,40.61014260757341],[-74.03508114595083,40.610301449591546],[-74.0350951850035,40.61046151287723],[-74.03509119174844,40.61062101474719],[-74.03506016762314,40.61081079986044],[-74.03501301293603,40.61099904995009],[-74.03494996324632,40.61118457664175],[-74.03487149024217,40.611366235710996]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01711102761195,40.61788751993068],[-74.01769159650473,40.6173259484068]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0250473472466,40.62358917746349],[-74.02268668861555,40.622178102265764]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01952692715224,40.63966502201572],[-74.01735110147658,40.63834114939077]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03250380538073,40.63619865497107],[-74.03221758097386,40.63611168234272],[-74.03182554447379,40.635992562975595]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01536728802037,40.619563617220855],[-74.01594933984525,40.61900487290429]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02840552031603,40.64032182910622],[-74.02859610088227,40.64013893144311],[-74.02940982440265,40.63935795851155]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03016550866239,40.63805212775785],[-74.03045889297914,40.63749481849389]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03155802828581,40.64144186402923],[-74.0312199662448,40.64145395167631],[-74.03102593306487,40.64144979855687],[-74.03083293499617,40.641433983514],[-74.03071603419676,40.64141811149266],[-74.03042980949647,40.64137544019866],[-74.03022171457417,40.64133219785722],[-74.03001720902115,40.64127796819063],[-74.02972508618036,40.641182246794884],[-74.02969081578144,40.641173493073936],[-74.02965671610644,40.6411643618572],[-74.02962279287524,40.641154855991324],[-74.02958905466606,40.64114497681448],[-74.02955550719821,40.64113472600065],[-74.02952215795102,40.641124106731155],[-74.0294890144033,40.641113120846995],[-74.02945608359413,40.641101770692],[-74.0294233714626,40.641090057772544],[-74.02939088548827,40.64107798577255],[-74.02935863227026,40.641065556868384],[-74.02932661884755,40.64105277323632],[-74.02929485181974,40.64103963822544],[-74.02926333734601,40.641026153844734],[-74.02923208246571,40.64101232327564],[-74.0292010946581,40.64099814986706],[-74.02917037920261,40.640983635628174],[-74.02913994225919,40.640968784578355],[-74.0291097908666,40.64095359872636],[-74.02907993184469,40.64093808242645],[-74.02905037025332,40.64092223869306],[-74.02902111335133,40.64090607003753],[-74.02899216707873,40.6408895806468],[-74.02896353693498,40.64087277320017],[-74.02893522952007,40.640855652386996],[-74.02890724989375,40.64083822122176],[-74.02887960509517,40.640820483053524],[-74.02885230062411,40.640802441399224]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03389978866599,40.61651131124679],[-74.03151434452992,40.61533019183227]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02980645882604,40.61618076581306],[-74.02957542681239,40.616066234228235]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02897220554718,40.61351613045301],[-74.02903210521346,40.61357088506667],[-74.02909911721886,40.61362087382872],[-74.02917223570252,40.613665332380094]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01915507960413,40.62927594024435],[-74.01941256238602,40.629005453060536],[-74.01970122546571,40.62870221714901]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03048495050112,40.61651863433924],[-74.03122817458835,40.6157229509399]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03505731294625,40.6097408281576],[-74.03511482326047,40.6097196305825],[-74.03515733062534,40.60970591170685]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02349157152236,40.625380505408465],[-74.02345749690014,40.62541290370687],[-74.02319919643975,40.625658464915894]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02071502826158,40.63854872042211],[-74.01852040600959,40.63721694821191]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01604929666969,40.60318110834597],[-74.01596160428284,40.603374780327805]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02147653651916,40.63900597246773],[-74.02143077242376,40.63888334832732],[-74.02141794650286,40.63884896884998],[-74.02134498899188,40.63871096861142],[-74.02126501256681,40.63858300173016],[-74.02119697423818,40.638489009208584],[-74.02116436692359,40.63844692552875],[-74.02108694468097,40.63834699980372]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02920031510213,40.620721364082634],[-74.02929556017932,40.62048690775809]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03192153893677,40.61083035531361],[-74.03250351930691,40.6105896807567]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02000806065679,40.63725981629294],[-74.01971505559173,40.6370286137495],[-74.0191392433223,40.63661983929569]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03187955888912,40.610803136471155],[-74.03184389083816,40.61082035459872],[-74.03180847835189,40.6108378767095],[-74.03177332714475,40.61085570112694],[-74.03173844007297,40.61087382533748],[-74.03170382351043,40.61089224749682],[-74.03166947987378,40.610910965091584],[-74.03163541443736,40.61092997544012],[-74.03160163247544,40.61094927569321],[-74.03156813618581,40.61096886518039],[-74.0315349312817,40.61098873954462],[-74.03150202105948,40.61100889694235],[-74.03146941057409,40.61102933536218],[-74.03143710356093,40.61105005162027],[-74.0314051041951,40.611071042532636],[-74.03137341599322,40.611092306925926],[-74.03134204356986,40.61111384128102]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03836395479941,40.616513393337435],[-74.03797502733808,40.615858807553956]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03240982901937,40.64143059587199],[-74.03297103416493,40.64136128596171]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02115312268505,40.63813169160991],[-74.02126964466525,40.63802197799566],[-74.0213751886626,40.63799853610025]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0191392433223,40.63661983929569],[-74.0181259811785,40.63602502145665],[-74.01768701220087,40.635749459333],[-74.01766395800685,40.63573498254916],[-74.01730795366713,40.635513941253755],[-74.0172200251889,40.6354459919857],[-74.01713798632896,40.63538701158468],[-74.01707896505447,40.63534002191321],[-74.01697745739544,40.635235081662316]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03297103416493,40.64136128596171],[-74.0332445283371,40.64130933723723],[-74.03351611060491,40.64124055750798],[-74.03371122089443,40.64117795072151],[-74.03378315634848,40.64115486731207],[-74.0340429692284,40.64105253703205],[-74.03429291466274,40.640934125204176],[-74.0345304847494,40.64080054332985],[-74.03475332880578,40.64065298013965],[-74.0349594385574,40.640492913594876],[-74.03496761539404,40.640485472845825],[-74.0351470871627,40.640322001169],[-74.03531498888958,40.64014210693315],[-74.03546220996033,40.639955150467266],[-74.03558827806658,40.63976311168031]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01915507960413,40.62927594024435],[-74.01805930548775,40.62861955791651]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04074397526134,40.625688299329624],[-74.0391088652061,40.625371381658674]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02367769684693,40.619085965218645],[-74.02389566228109,40.618747576728026],[-74.02413041963155,40.61841561370974],[-74.02438145145473,40.61809080626198],[-74.0252532717485,40.61667845738943]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03204523327672,40.63323278037718],[-74.03177291967661,40.63316482142147]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02195240648099,40.620900712256],[-74.02165103568196,40.621203965685496],[-74.02104201559015,40.62186201738322]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02475042751018,40.62432075214108],[-74.02238878740263,40.6228960101773]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01794424974013,40.63621022375068],[-74.01761044271151,40.635993574377046],[-74.01736563695651,40.635823125710296],[-74.01719045663212,40.635701149555786],[-74.01711050334977,40.635641455823546]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01784193368066,40.62659069387398],[-74.01875180734196,40.62431751087332]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0320208222862,40.61472745880179],[-74.03263720326892,40.61400991276134]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02185196389816,40.63981609782905],[-74.02183558532252,40.639472985583964],[-74.0217985851795,40.63929518543931],[-74.0217716818721,40.63919193654847]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01574804402502,40.63176426870878],[-74.01604820400777,40.63103288814215]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02929556017932,40.62048690775809],[-74.02956408409668,40.61983253884943]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02024573669517,40.63640957692435],[-74.01970390025541,40.63608035103739]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02557995053986,40.620158140619374],[-74.02557248489695,40.62016743627572],[-74.02542226113637,40.6203411346406]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03752544637754,40.619696001852745],[-74.03728969733213,40.61930655864202]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01500269223251,40.6308615887506],[-74.0153115894613,40.63104929700415],[-74.01542906057333,40.63112021542459]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03209446071162,40.617321397787926],[-74.0320614482939,40.6173583015449],[-74.03202840046119,40.61739524081823],[-74.03197565154869,40.617454176908794],[-74.031788191921,40.61768007035638]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0406625157839,40.62491296436131],[-74.03940662450633,40.62463864368792]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0312528387201,40.638391387119846],[-74.03127407414611,40.638351515096495],[-74.03154600534789,40.63784088301529]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01926195098474,40.603752157200816],[-74.01924239456802,40.60377850073871],[-74.01922137397284,40.60381610950833]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02572377067443,40.64063051860539],[-74.0260978912955,40.64027001982279]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03592460933342,40.61705482737083],[-74.03386577352411,40.61659397130616]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02614890233889,40.617798135764666],[-74.02600596241939,40.61796500765188],[-74.02598672683885,40.6179739453098],[-74.02595947629416,40.61800577558045],[-74.02592963837728,40.618040614408486]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03883161439232,40.62849685557941],[-74.03791790452361,40.62828155836065]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02547192644472,40.63714013731289],[-74.0256661527146,40.63666778118139]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0235493915473,40.639320333692275],[-74.02392610712151,40.63889885818351],[-74.02417094670037,40.63866937087833]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03310842055332,40.625647051398644],[-74.03042727609291,40.625009935881906]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01699572995919,40.630582212938066],[-74.0169180172404,40.6305474462965],[-74.01680939238204,40.630499032721445]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03578883570226,40.62628504978484],[-74.03310842055332,40.625647051398644]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04111334568839,40.62055643802011],[-74.04099120739049,40.619819072906346],[-74.04096053928613,40.61963391791714],[-74.0407722910782,40.61880154379795],[-74.040682694041,40.61841294850277],[-74.04053928054935,40.617790927023755],[-74.04039082379572,40.617080251995745],[-74.04037674928094,40.61700988543431],[-74.04025044601865,40.61637839948534],[-74.0400827857112,40.61577581127405],[-74.04001531305238,40.61561172733382],[-74.03976536420298,40.6150038780072],[-74.03947574317411,40.61449134708673],[-74.03919477748231,40.61408194024671],[-74.03874119557786,40.61353080441318],[-74.03837286220568,40.61315705851136],[-74.03830934371193,40.613102888109296],[-74.03788517257021,40.61274113419476]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0350366952782,40.637414025851776],[-74.03477328919952,40.63732795343989]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0225901676178,40.64043910503215],[-74.02283854823382,40.640326347360315],[-74.02309676772151,40.6402266709784],[-74.02325020671685,40.640177165893],[-74.02336300700999,40.64014077126573]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02635995559174,40.61825384993942],[-74.02748855985243,40.61698424481986]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02002224833126,40.60326237593874],[-74.02029938114364,40.60338211129111],[-74.02048299600852,40.60344410066122],[-74.02078565282602,40.6035301589521],[-74.02110847907653,40.603594684585595],[-74.0215684974646,40.603656108316194],[-74.02203658698294,40.60371752882554],[-74.02256117207907,40.60378816217829],[-74.02296469896386,40.603840365066375],[-74.0242923070649,40.60401231771199],[-74.02467644931201,40.604065792241066],[-74.02508843438547,40.60413576571631],[-74.02563321482491,40.604240739340604],[-74.02614734576656,40.60432366064875],[-74.02673467652716,40.60440137293697],[-74.02723859099166,40.60447002010487],[-74.02761822311311,40.60450625851959],[-74.02807275346017,40.60453079996403],[-74.02843877174634,40.60457612091124],[-74.02890863994567,40.604636984267465],[-74.02917081365044,40.604674544215406],[-74.02935808535408,40.60470952786479],[-74.02955557435412,40.60475359100284],[-74.0298279795965,40.60482617815296],[-74.03004761282108,40.60490007614591],[-74.03008614756094,40.604914632214665],[-74.03012443432526,40.60492956427068],[-74.03016246607923,40.60494486913302],[-74.03020023644825,40.60496054529587],[-74.03023774059534,40.604976589075065],[-74.03027497126672,40.60499299930013],[-74.03031192208655,40.60500977178474],[-74.0303485877789,40.60502690452022],[-74.03038496240798,40.60504439449289],[-74.03042103937862,40.605062238856796],[-74.0304568116559,40.605080434430995],[-74.03049227594191,40.60509897887126],[-74.03050563373486,40.605104953433624],[-74.03070995698062,40.60519831590535],[-74.03099090303603,40.60532668870925],[-74.03129739601717,40.605479705436856],[-74.03149322108906,40.605596423382494],[-74.03169927758533,40.60574816916692],[-74.03177080248027,40.605803940277696],[-74.03185083057043,40.6058402471377],[-74.03195809544476,40.6058752485242],[-74.03207387364156,40.60591154478002],[-74.03213176734332,40.60594007287902],[-74.03222883197108,40.60600232345322],[-74.03260007804825,40.60627208978525],[-74.03292706466078,40.60654057059007],[-74.03317571495438,40.60674938953697],[-74.03348227933895,40.60702176651067],[-74.03363556149169,40.60715535983124],[-74.03381587920185,40.607313559867265],[-74.0339629593284,40.607456308358195],[-74.03419341827762,40.60766966379552],[-74.03435837833771,40.60786582643361],[-74.0344261819125,40.607969075722515],[-74.03446913326677,40.608051678443914],[-74.0344962683316,40.6081187953263],[-74.03452791893336,40.6081841893173],[-74.03456183847861,40.60827023726886],[-74.03460252486555,40.60833907107462],[-74.03466580397128,40.60842511015165],[-74.03478104367004,40.60854555600169],[-74.03483753290773,40.60860405845137],[-74.03495501949446,40.60870212827001],[-74.03508379787691,40.608798474166214],[-74.03521871563228,40.608878320282756],[-74.03538137115055,40.6089442310194],[-74.03561215637589,40.60901636105958],[-74.03573641297334,40.60908625864715],[-74.03599609905362,40.609309069918936]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02029670597527,40.64197377625254],[-74.02022933658131,40.64193209968427]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03750936272698,40.631894171470876],[-74.03744823361973,40.63188111578922]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02281427319133,40.616487579503314],[-74.02216115992056,40.616165728681295]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02015258203039,40.63556675262543],[-74.0203921699701,40.63496479444601]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01906269284504,40.63103852457284],[-74.0192589306462,40.63055955035461]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.017460462067,40.62863643595272],[-74.01753702908766,40.62841296051191],[-74.01758581867473,40.62827575915362],[-74.01774427051309,40.62783017541721],[-74.01775605727933,40.62779701649184],[-74.01779685439413,40.62769621488724],[-74.01790215486449,40.62743602048602],[-74.01792055659239,40.62739054799244],[-74.01816532344843,40.626785705088835]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01362246814824,40.62124382115554],[-74.01420288350761,40.62068474388309]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01604820400777,40.63103288814215],[-74.01566220606678,40.63080357912659],[-74.01490317317815,40.63035265462519]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03457832908494,40.61751300193664],[-74.03459559678849,40.61747087898192],[-74.03468801069191,40.61724546903249]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02646266411575,40.60727846834476],[-74.02708033873293,40.60741244519307]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02686129357187,40.639536290563555],[-74.02695244733698,40.63944606403955]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01612995805846,40.633264021233344],[-74.0161346617863,40.63323971887965],[-74.01615691028282,40.6331247705525],[-74.01621596169294,40.6328196389354]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02942921523434,40.636016506650954],[-74.02944477745974,40.63597591603439],[-74.02945523806518,40.635947439034744],[-74.02962048919323,40.635565955069765],[-74.02984227536264,40.63499623854843],[-74.02985778965343,40.63495626053565]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03203387836415,40.63356231023096],[-74.03224356174422,40.63361389632391],[-74.03260745676292,40.633718704447965],[-74.03260900551311,40.633719117971836],[-74.03265396321524,40.63372877680466],[-74.03266820854272,40.63373210490139],[-74.03274235473312,40.63374942754122]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02987104022792,40.62637344160045],[-74.0271530069287,40.62572685847986]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02963292315899,40.63415292918439],[-74.026950773583,40.6335159315419]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02457855492976,40.61022330197482],[-74.02459593815628,40.610109224595064],[-74.02459441754772,40.60999204091486],[-74.02457307734359,40.60987452825703],[-74.02453195982463,40.60975959540722],[-74.0244720757739,40.60965008258303],[-74.02439534392727,40.60954853444837],[-74.02430437611244,40.60945696914183]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0166954641309,40.635521475108796],[-74.01679830913133,40.635408366648136]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01727561504546,40.62899814917596],[-74.01699505325172,40.62894636550168],[-74.0170772682257,40.62875400228997],[-74.0169264479982,40.62883563868563]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02292884091298,40.617858888091604],[-74.02288292185465,40.61783651890635],[-74.02248182521255,40.61764116710975]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03232784000393,40.61104001817858],[-74.0322115265826,40.61098246224904]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02664251543516,40.63974743200312],[-74.02686129357187,40.639536290563555]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02677000503712,40.620846254697554],[-74.02722013300452,40.6203223521233]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.031547580922,40.63667258539087],[-74.03182554447379,40.635992562975595]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02164447961336,40.639834687997556],[-74.02176040916885,40.63982434619838]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01315606807276,40.605621663449085],[-74.01515631643922,40.60369719971753]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02730164954356,40.61872254016571],[-74.02839765193403,40.61744349936352]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.032637494089,40.609432094762205],[-74.0327758936268,40.60976383464716]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02101552967812,40.63826308446196],[-74.02091701229124,40.63817967475092],[-74.02037998679783,40.63772499451369]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02222073204432,40.621060530577175],[-74.02234457401045,40.62091694529234],[-74.02279904633724,40.62041475283493],[-74.02309809440634,40.62008430155043]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01490900364942,40.61655789281406],[-74.01548877590352,40.615997917265965]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02115312268505,40.63813169160991],[-74.02106300303572,40.63805595478976],[-74.02102338956485,40.63802106753185],[-74.02098343401775,40.63798640715618],[-74.02094313683533,40.63795197667777],[-74.0209025019766,40.63791777743581],[-74.02086153142174,40.63788381211003],[-74.02082022715042,40.63785008187244],[-74.02077859158241,40.637816588732555],[-74.02073662757721,40.63778333436481],[-74.02069581573917,40.63775146758026],[-74.02065470184723,40.63771982766892],[-74.02061328832056,40.637688414965126],[-74.02057157735904,40.63765723181357],[-74.02052957028259,40.63762627972142],[-74.02048727083012,40.637595559860415],[-74.02044467944226,40.637565075078115],[-74.02041707838863,40.63754555420173],[-74.02038935884737,40.6375261315114],[-74.02030818957937,40.6374668650815],[-74.02000806065679,40.63725981629294]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01676837217506,40.63889900814065],[-74.01735110147658,40.63834114939077]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02685720207243,40.62645774644725],[-74.02673334596018,40.626425273742115],[-74.02444889042178,40.6250484458383]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02369674686376,40.62094919252825],[-74.0231411522841,40.62061070104255]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02026153192729,40.63918045222296],[-74.02082094366662,40.63861280019888]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01497963664175,40.64062546817968],[-74.0127753791902,40.63929563223955]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01640622335879,40.622014176886864],[-74.01420288350761,40.62068474388309]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02262514142657,40.62121078448925],[-74.02255480065712,40.62126440634898],[-74.02245052470514,40.62120173246406]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02984260202672,40.61915381635932],[-74.0287007460467,40.61859355146942]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03483935692643,40.609682730039026],[-74.0348710978547,40.60974097141558],[-74.03489726686202,40.60979182728423]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03137808967088,40.61250877934178],[-74.03185652853652,40.611951954590694]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01908019765466,40.6402972882069],[-74.01902453184582,40.64026372590337],[-74.01894932186951,40.64021823525207]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01823145051426,40.60410847200049],[-74.01823066388766,40.60403943775004],[-74.01823066383116,40.60403923085163],[-74.0182306160869,40.60403905947699],[-74.01821048792463,40.60397037088927],[-74.01821041729647,40.60397011005771],[-74.01821026314774,40.60396986699743],[-74.01817151634259,40.603905998984615],[-74.01817142112358,40.603905836999054],[-74.0181712562267,40.603905674521926],[-74.01811685569322,40.60385046334875],[-74.01762387638252,40.60360675051379]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0277909861234,40.6314633669818],[-74.02808018363976,40.63075415598411]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03438213484671,40.639355147613934],[-74.03485670659863,40.63847431543151]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02134518789724,40.64118218955396],[-74.02152938816474,40.64087026067666],[-74.02165149085279,40.64060369331658],[-74.0216797799364,40.64053053887377],[-74.02172500211859,40.640400324223044],[-74.02177423115326,40.640231098959056],[-74.02179520508874,40.64013034488874],[-74.02180047058044,40.6401050660265],[-74.02185196389816,40.63981609782905]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03708657313658,40.63209122525476],[-74.03710325074238,40.632047724759005],[-74.03719039134116,40.631819063957124]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04017982041616,40.62163217648139],[-74.04047541710517,40.62078994423459]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0196604336372,40.62957688094767],[-74.01915507960413,40.62927594024435]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02202374839493,40.63098801670602],[-74.02229638917754,40.63032309233872]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03607664215738,40.60940692063411],[-74.0365845091119,40.61089265321882]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03134839341736,40.608127472013564],[-74.03087175807111,40.60903422762096]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03084507393038,40.616699488714296],[-74.03106093000177,40.61596182358245]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03049069960784,40.612173353320536],[-74.03065092930589,40.61194040727508],[-74.03067616192742,40.61190568821078],[-74.0307018562561,40.61187116670168],[-74.03072800833544,40.61183684475882],[-74.03075461684838,40.61180272757569],[-74.03078167871833,40.611768818335825],[-74.03080919020897,40.61173511972036],[-74.03083714978288,40.611701635582556],[-74.0308655530446,40.611668369273865],[-74.03089439867658,40.611635324647466],[-74.03092368250314,40.61160250488721],[-74.03095340210749,40.61156991351151],[-74.03098355463288,40.61153755353634],[-74.03101413678345,40.61150542898293],[-74.03104514460303,40.61147354202989],[-74.03107657589506,40.61144189703323],[-74.03110842670368,40.611410496841664],[-74.03114069461198,40.61137934447101],[-74.03117337544438,40.61134844293759],[-74.03120646612517,40.61131779659764],[-74.03123996401696,40.6112874071268]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03618712835667,40.630449765789244],[-74.03620279260744,40.63041102974703],[-74.03623931380882,40.630320669046796],[-74.03624869161456,40.63030755429485],[-74.03633305471051,40.63009895820512],[-74.03623337455562,40.6300699480701]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02956408409668,40.61983253884943],[-74.0282052488583,40.619172663284246]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02071502826158,40.63854872042211],[-74.0208632992042,40.63840746007775],[-74.0209540417791,40.638321007931715]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02097461532125,40.62227607051391],[-74.0210405524029,40.62219819210059],[-74.02123110821154,40.621973124721016],[-74.02161867150039,40.621515372764044],[-74.02206144884833,40.620992398315195],[-74.02207654556122,40.620974567338685]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01863896276912,40.627070526373515],[-74.01830796925623,40.6268715915053]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03295222200916,40.61028113349408],[-74.0331456392176,40.61022748804165],[-74.03354242808052,40.610100922898674],[-74.03444464220135,40.609813133280305],[-74.03483935692643,40.609682730039026]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02078690532231,40.641785783295624],[-74.02104408150896,40.6415721336051],[-74.0211145678175,40.641513578214685]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01711102761195,40.61788751993068],[-74.01490900364942,40.61655789281406]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01348255916146,40.61103739791961],[-74.01522379499055,40.60935638411836]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03598944354782,40.61859585874571],[-74.03616248381722,40.61816830032512]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01756994176787,40.62089820597792],[-74.01716386615648,40.62065217306243],[-74.01536728802037,40.619563617220855]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03572584040815,40.613103033908445],[-74.03411074911207,40.61229599133894]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0326468876647,40.61957917176456],[-74.03275211855042,40.61932301589863]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02656062871394,40.62718718062923],[-74.02415343468138,40.62578041492029]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03039238356551,40.60745774941676],[-74.03000540325685,40.60774150653983]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02750722453025,40.63215460208875],[-74.0277909861234,40.6314633669818]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03612991330351,40.632663269752406],[-74.03642637951485,40.63193208913182]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02456733672958,40.64177087260064],[-74.0226517567625,40.640610488913644],[-74.02250538867234,40.640560907792185]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02663802521565,40.61594423821987],[-74.02684173888453,40.61575708972284],[-74.02725567184149,40.61537682857637],[-74.02740528288432,40.61521834652826],[-74.0276174370169,40.61499267001983],[-74.02799399640573,40.61461672818743],[-74.02838485437434,40.614249499277726]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01970491557115,40.62218496450551],[-74.01999892578114,40.62145136823829]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02930182080097,40.61789600944142],[-74.02839765193403,40.61744349936352]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02542226113637,40.6203411346406],[-74.02538545248089,40.620383692576674]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0268776058058,40.6373906299475],[-74.02686340883068,40.63742068318629],[-74.02685218701885,40.63744134374604],[-74.02676768201421,40.63759767574153],[-74.02675822050722,40.63761601259681],[-74.02673708899094,40.63765681974629]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02582777972842,40.63730700527587],[-74.02554978528251,40.63755700598885],[-74.0254628297917,40.63758865180812],[-74.0253681850416,40.63760619654226],[-74.02527185543377,40.637608532159696]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0324744222498,40.62000389694172],[-74.0326468876647,40.61957917176456]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03583329875791,40.60948773165801],[-74.03579014761328,40.60944326514974],[-74.0357344518362,40.60938952460263]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02457354910433,40.639923934992396],[-74.02484592386213,40.639912178790475],[-74.02511929670592,40.63991374057201],[-74.02521246381761,40.63991883968448],[-74.02539197793416,40.63992866493059],[-74.02566227601639,40.63995681805829],[-74.02587310025794,40.63998663242736],[-74.02608141138477,40.64002593796896],[-74.02628612034283,40.64007452838303]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02117699460089,40.62125785685994],[-74.02030304230694,40.620705247605486]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0211145678175,40.641513578214685],[-74.02114391886154,40.641468366786185],[-74.02115900852569,40.641446908981315],[-74.02115975330344,40.64144585056726],[-74.0212011818474,40.6413869402799],[-74.02134518789724,40.64118218955396]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02695244733698,40.63944606403955],[-74.02762394706329,40.63880495150758]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03134839341736,40.608127472013564],[-74.03079671779996,40.60796647248415]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0282796052702,40.6374676390882],[-74.02774843865195,40.63730274856897],[-74.02735286784608,40.637179949465235]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03396809430834,40.6362764328704],[-74.03353301927748,40.6361427346014],[-74.03366947750509,40.63590486771356],[-74.03369256690526,40.6358649139405]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02475042751018,40.62432075214108],[-74.0250473472466,40.62358917746349]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02621402560658,40.621491677902604],[-74.02677000503712,40.620846254697554]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01780244173645,40.62936684005484],[-74.01773930455538,40.62929061155157],[-74.01778842271797,40.62909753273425],[-74.01752337759615,40.62904448813247]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03430435417751,40.6181861598184],[-74.03431913169013,40.618150738302454],[-74.03442486409209,40.617897399052914]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03676602434834,40.63434742165918],[-74.03676104126944,40.63432735601163],[-74.03675659779698,40.6343072173164],[-74.03675269635356,40.63428701311157],[-74.03674933936244,40.63426675210791],[-74.03674652748784,40.63424644335176],[-74.0367442613933,40.634226094716844],[-74.03674254328195,40.634205714578904],[-74.03674137337875,40.63418531298958],[-74.03674075102701,40.63416489631519],[-74.03674067777133,40.634144475109565],[-74.03674115361518,40.634124056576425],[-74.03674217790335,40.634103649762515],[-74.03674375042038,40.63408326371443],[-74.03674587073023,40.634062906138595],[-74.03674853729778,40.63404258557943],[-74.03675174924793,40.63402231108373],[-74.03675550592514,40.63400209119562],[-74.03675980469437,40.633981933622174],[-74.03676464380118,40.63396184791305],[-74.03677002258925,40.633941841104566],[-74.03677593776504,40.6339219230819],[-74.03678238603372,40.63390210138483],[-74.03678936695972,40.63388238455732],[-74.03679687526933,40.63386278047482],[-74.03680490898732,40.63384329701172],[-74.0368134646003,40.633823944053184],[-74.03682253837285,40.63380472763137],[-74.03683212723142,40.633785657631286],[-74.03684222568168,40.633766740588186],[-74.03685283086946,40.63374798538187],[-74.03686393774055,40.63372939905004],[-74.0368755416813,40.63371098997044],[-74.0368876380779,40.63369276618576],[-74.03690022231575,40.633674734230944],[-74.03691328714253,40.63365690265214],[-74.03692682926332,40.633639278486434]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02319919643975,40.625658464915894],[-74.02293834215115,40.625906448679935],[-74.02290426743478,40.62593885602657]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0263186200422,40.619160287538435],[-74.02684386428139,40.61854342663949],[-74.02687300482306,40.61850920005682]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02227378599942,40.620109058620585],[-74.0217769278977,40.619805253716834],[-74.02125420001359,40.61948204691554],[-74.02089938190545,40.61926265491913]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02371677165152,40.61693704497811],[-74.0231679360648,40.61666371395202],[-74.02281427319133,40.616487579503314]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0349464362437,40.61428853040123],[-74.03316279012168,40.6134020726199]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01336275759327,40.60279636924117],[-74.01340057064833,40.60282374964641],[-74.01342735878266,40.6028423869793],[-74.01350188489346,40.60288827786854],[-74.01360512567038,40.60295175285257],[-74.0136263711351,40.60296466347784],[-74.01369310085788,40.60301428369408]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02147653651916,40.63900597246773],[-74.02143077242376,40.63888334832732],[-74.02141794650286,40.63884896884998],[-74.02134498899188,40.63871096861142],[-74.02126501256681,40.63858300173016],[-74.02119697423818,40.638489009208584],[-74.02116436692359,40.63844692552875],[-74.02108694468097,40.63834699980372]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03275116698742,40.634894075109415],[-74.03276302628404,40.63485243167334],[-74.0327719354545,40.63482137017971],[-74.03287769902701,40.63456621427858],[-74.03288122947899,40.63455794640518],[-74.03299839216854,40.63429018847519],[-74.03300084797425,40.6342846943415],[-74.03301384840601,40.63425614424616],[-74.03303298819965,40.634213598390225]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02161286131559,40.62218380192602],[-74.02233761319047,40.62113026188576]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0177243336457,40.63091050440686],[-74.01733664052384,40.63072928935317]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02838485437434,40.614249499277726],[-74.02885501912635,40.61390068251714],[-74.02917223570252,40.613665332380094]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01922137397284,40.60381610950833],[-74.01916517337347,40.60379778367388]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03126827705228,40.63735730812885],[-74.03140036672403,40.63703348175744],[-74.03142517458046,40.63697266263546],[-74.031547580922,40.63667258539087]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02725974486593,40.60949388465354],[-74.02724257527268,40.60969437183326]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01884666051637,40.604372398075654],[-74.01886869310432,40.60442834598617],[-74.01883304223699,40.60443538838947],[-74.0187975306108,40.60444282813786],[-74.01876216591806,40.60445066439259],[-74.01872695563107,40.60445889514224],[-74.01869190810112,40.604467517872614],[-74.01865702992166,40.604476531912724],[-74.01862232900436,40.60448593458092],[-74.0185878126019,40.60449572436848],[-74.01855348796659,40.60450589876146],[-74.01851936366967,40.60451645524568],[-74.01848544542527,40.6045273926477],[-74.01845174114503,40.604538707783384],[-74.01841825808144,40.60455039830637],[-74.0183850041463,40.6045624615351],[-74.01835198571295,40.60457489529088],[-74.01831920959418,40.60458769672481],[-74.01828668414146,40.60460086315535],[-74.01825441506863,40.60461439190129],[-74.01822240984781,40.60462827961111],[-74.01819067463249,40.60464252360358],[-74.01815921777417,40.60465712102961],[-74.01812804454684,40.60467206803542],[-74.01809716242289,40.6046873619396],[-74.01806657799536,40.604702999558306],[-74.01803629741761,40.60471897737269],[-74.01800632750235,40.60473529152873],[-74.01797667528233,40.60475193901011],[-74.0179511559836,40.60476418870306],[-74.01792591723775,40.604776770891746],[-74.01790096563792,40.60478968239232],[-74.01787630975537,40.60480291951794],[-74.01785195684226,40.60481647757689],[-74.01782791327204,40.604830353552785],[-74.01780418651677,40.60484454292146],[-74.01778078404857,40.604859041326165],[-74.01775771224051,40.60487384424282],[-74.01773497812536,40.604888947984875],[-74.01771258851572,40.60490434752566],[-74.01769054978475,40.6049200385086],[-74.01766886918476,40.604936016074475],[-74.01764755220985,40.60495227620191],[-74.01762660545263,40.60496881285904],[-74.01746711446835,40.6049651038237]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03987461127993,40.62872469808542],[-74.03883161439232,40.62849685557941]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03316279012168,40.6134020726199],[-74.03364741814288,40.6128332434378]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02365406373,40.61996084407536],[-74.02334639906894,40.61976973549253]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0197189447665,40.64254997093113],[-74.01993770878927,40.64233180068142],[-74.01994280019363,40.642326723017916],[-74.02029670597527,40.64197377625254]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01376688929142,40.608478685787745],[-74.0130231768454,40.6080304206257]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03404156746652,40.6305650302342],[-74.0343355365717,40.62984715685466]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0260898717898,40.60591312207867],[-74.02591140454368,40.6064996600137]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03864767576961,40.62645186007846],[-74.03871694221942,40.626215895713685]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03864767576961,40.62645186007846],[-74.03910304027825,40.62642404259122],[-74.0406351932659,40.62678434798753]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03841532458546,40.627111346473754],[-74.03842734424721,40.62711312094155],[-74.03843945887053,40.627114466335364],[-74.03845164316715,40.62711537948057],[-74.0384638703104,40.62711585854332],[-74.03847611303448,40.62711590269508],[-74.03848834561296,40.6271155116094],[-74.03850054100099,40.6271146863005],[-74.03851267215404,40.627113428452766],[-74.03852471290801,40.627111741258],[-74.03853663753837,40.62710962757285],[-74.03854841988206,40.627107092431984],[-74.03856003487601,40.62710414170738],[-74.03857145569793,40.62710078110402],[-74.0385826581651,40.627097018001365],[-74.03859361875546,40.62709286145393],[-74.03860431284707,40.62708831967893],[-74.03861471691854,40.627083402903615],[-74.03862480876813,40.627078121857366],[-74.03863456619418,40.62707248743704],[-74.03864396809571,40.627066512717086],[-74.03865299447091,40.62706021026897],[-74.03866162531882,40.627053594171905],[-74.03866984063849,40.6270466783376],[-74.0386776243874,40.62703947784911],[-74.03868495920456,40.627032008962665],[-74.03869182816828,40.627024287264184],[-74.03869821743639,40.62701633018141],[-74.03870411206694,40.62700815463987],[-74.03870950019697,40.62699977856916],[-74.03871436952369,40.62699121973157],[-74.03871870972418,40.62698249756395],[-74.03872251179423,40.62697363049757],[-74.03872576607036,40.62696463746646],[-74.03872846618829,40.62695553924636],[-74.03873060732207,40.62694635510476],[-74.03873218266705,40.626937104644824],[-74.0387331911358,40.626927808137935],[-74.03873362878244,40.626918485688854],[-74.03873349517957,40.62690915823883],[-74.03873279077868,40.62689984555608],[-74.03873151735077,40.62689056791098],[-74.0387296768871,40.62688134607643],[-74.03872727445615,40.62687219914889],[-74.03872431446771,40.62686314773297],[-74.03872080330986,40.62685421142724],[-74.0387167489097,40.626845409662366],[-74.0387121600735,40.626836761198504],[-74.03870704758674,40.62682828546532],[-74.03870142069512,40.626820000720265],[-74.03869529326151,40.62681192488412],[-74.03868867892896,40.626804075877814],[-74.03868158980052,40.62679647028255],[-74.03867404391583,40.62678912450996],[-74.03866605601667,40.62678205547539],[-74.0386576439216,40.62677527758025],[-74.03864882632925,40.62676880623078],[-74.03863962259672,40.6267626548227],[-74.03863005186199,40.626756838091985],[-74.03862013523984,40.6267513672559],[-74.03860989472534,40.6267462548716],[-74.03859935253239,40.62674151165339],[-74.03858853109494,40.62673714881808],[-74.03857745460442,40.62673317473389],[-74.03856614725272,40.62672959877428],[-74.03864767576961,40.62645186007846]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03555598232235,40.634062017580575],[-74.03287451463889,40.633429345431814]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03996649261121,40.619150841936026],[-74.03813109362966,40.61980248725406]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0274372501343,40.625027608911445],[-74.02773394483708,40.62430140322686]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01878323392015,40.63696028509285],[-74.01887440764712,40.63687170404401]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02748855985243,40.61698424481986],[-74.02676711059985,40.61657486832318]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02900836845947,40.62119206102639],[-74.02920031510213,40.620721364082634]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0359946910694,40.630387141170566],[-74.03601043773016,40.63034813456979],[-74.03613434436348,40.63004112661664]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03583329875791,40.60948773165801],[-74.03607664215738,40.60940692063411]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02566164211383,40.62214065420595],[-74.02369674686376,40.62094919252825]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02628975684716,40.616329300249824],[-74.02647910609785,40.616120552169356],[-74.02663802521565,40.61594423821987]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02188450761754,40.62085685192503],[-74.02293270340282,40.6195046246781]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01542906057333,40.63112021542459],[-74.01552402378347,40.631177547348],[-74.01547668955338,40.63124873110388]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02808018363976,40.63075415598411],[-74.02838003879215,40.63002274319229]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01611824015598,40.615384035751894],[-74.01445107455964,40.61438019833109],[-74.01390656440218,40.61405236151451]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01524185216765,40.62313302617248],[-74.01582540206918,40.622573607188805]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03667838248343,40.63905846791726],[-74.03665118170449,40.63911402501051],[-74.0366234923615,40.63916944169618],[-74.03659531555182,40.639224715795734],[-74.03656665149262,40.63927984412567],[-74.03653750172128,40.63933482484234],[-74.03650786821436,40.63938965476171],[-74.03647775250938,40.63944433220762],[-74.03644715460365,40.639498853996656],[-74.03641607735412,40.63955321828474],[-74.03638452119826,40.63960742239088],[-74.03635248811295,40.63966146363358],[-74.03631997919595,40.639715340336856],[-74.03628699598409,40.63976904931675],[-74.03625353979463,40.63982258805953],[-74.03621961304482,40.6398759547212],[-74.03618521529232,40.639929146285986],[-74.03615035071373,40.639982160741795],[-74.03611501886705,40.640034995742965],[-74.03609316594085,40.6400693705636],[-74.0360708011281,40.6401035535529],[-74.03604792750494,40.64013754068893],[-74.03602454726732,40.64017132694486],[-74.03600066459123,40.64020490863342],[-74.03597628079297,40.64023828072807],[-74.03595140114844,40.64027144004376],[-74.03592602697371,40.64030438105135],[-74.03590016244505,40.64033710039864],[-74.03587381151802,40.64036959322572],[-74.03584697682906,40.640401855510795],[-74.0358196614545,40.640433883064325],[-74.03579186957026,40.64046567186398],[-74.03576360469255,40.64049721772016],[-74.03573487121741,40.64052851677798],[-74.03570567134125,40.64055956434555],[-74.03567600924066,40.64059035740579],[-74.03564589019096,40.64062089109836],[-74.03561531638915,40.64065116173658],[-74.03558429245125,40.64068116529799],[-74.0355528225537,40.64071089826286],[-74.03552090977301,40.640740356441626],[-74.03548855938509,40.64076953581162],[-74.03545577578653,40.640798433188124],[-74.03542256249388,40.64082704454895]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03389978866599,40.61651131124679],[-74.03414586365614,40.615913472934395]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02348815078076,40.60852521073215],[-74.02287535458247,40.608330268246725],[-74.02268180743687,40.60850903894092]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04047541710517,40.62078994423459],[-74.04050274497442,40.62060268046163],[-74.04050275700634,40.62060258111281],[-74.04050275694637,40.620602482270826],[-74.04050929435708,40.620411794323104],[-74.0405092942972,40.62041169564865],[-74.0405092828099,40.62041160552221],[-74.0404942519077,40.62021937653344],[-74.04049425186409,40.620219304663586],[-74.04049423950849,40.620219232798085],[-74.04049177065124,40.62020641654085],[-74.04048123952572,40.620169500082426],[-74.04047021400446,40.62013266772889],[-74.04045869387082,40.62009592350084],[-74.04044668066636,40.62005927041315],[-74.0404341765933,40.62002271315567],[-74.04042118099531,40.61998625591671],[-74.04040769717264,40.61994990137537],[-74.04039372556825,40.619913653719586],[-74.04037926794447,40.619877517471814],[-74.04036432540312,40.61984149564704],[-74.04034890014577,40.619805592097414],[-74.04033299393423,40.6197698105078],[-74.04031660743146,40.61973415540102],[-74.04029974239862,40.61969862945674],[-74.0402824021368,40.61966323702932],[-74.0402645870887,40.619627981971576],[-74.04024629879599,40.61959286763329],[-74.04022754033927,40.619557897363784],[-74.04020831370049,40.61952307551786],[-74.04018861954162,40.61948840511055],[-74.04016846160373,40.619453890998685],[-74.04014784054804,40.61941953502459],[-74.04012675923597,40.619385341710306],[-74.04010521986893,40.61935131490798],[-74.0400832246479,40.61931745779961],[-74.04006077555422,40.61928377390236],[-74.04003787566856,40.61925026690056],[-74.04001452719226,40.619216940646304],[-74.03999073144655,40.619183797819346],[-74.03996649261121,40.619150841936026]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03315548281145,40.63273497322292],[-74.0304730729105,40.632098967408616]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01514575030541,40.63701460961411],[-74.01294381978245,40.63568596469938]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03273636314306,40.62156040841758],[-74.03275112972804,40.621522798355635],[-74.03276642705602,40.621483873374494],[-74.03283249095776,40.62131568226214],[-74.03285202575337,40.62126596787461]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03242972118488,40.63694608860652],[-74.03244743502746,40.636910153267785],[-74.03245240654265,40.63690011958763],[-74.03275623829246,40.636363216294086],[-74.03276010044421,40.63635666834685],[-74.03277800582904,40.636327234682014],[-74.03280047149336,40.63629067589831]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03876752814024,40.617181129201875],[-74.03836395479941,40.616513393337435]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03840315446585,40.631715294441875],[-74.03879672709583,40.63132927188658]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02567519686234,40.60645386551876],[-74.02588379293921,40.60587453848587]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03534760179224,40.614428276285686],[-74.03470051608272,40.61465860187504]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02949037963523,40.64132096933019],[-74.02928610398733,40.6411422234715],[-74.02907326123623,40.64096926986565],[-74.02885230062411,40.640802441399224]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01919994798754,40.62426799817216],[-74.01945099408243,40.623835066755824],[-74.01987797485228,40.62326695485937],[-74.02067901763246,40.622325950302134]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02322142391829,40.605413769589454],[-74.02270656286572,40.605105974327884],[-74.0212250835914,40.60473806226647],[-74.0207854097326,40.60567368551223],[-74.02247769491427,40.60667421564758],[-74.02313801279013,40.60606717683646]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03543728497804,40.61995580764228],[-74.03275211855042,40.61932301589863]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02547192644472,40.63714013731289],[-74.0229098970756,40.63610746601653]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03649125984288,40.61798915516788],[-74.03631596928282,40.617707852005886]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0322115265826,40.61098246224904],[-74.03250351930691,40.6105896807567]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02355676027709,40.627242523740215],[-74.02119408413276,40.625815947890985]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01340877238549,40.6248958784662],[-74.01403349690504,40.62429394156755]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02997954531816,40.60712552950822],[-74.0291039543851,40.60655740829638]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02512022214226,40.64121007239311],[-74.02572377067443,40.64063051860539]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02056295535992,40.64214110540959],[-74.02075868686609,40.64193812013328],[-74.02085372446696,40.641830373962],[-74.02094273457377,40.64172875247475],[-74.0210589565097,40.641583207190735],[-74.0211145678175,40.641513578214685]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03087175807111,40.60903422762096],[-74.03039492080207,40.608721072630324]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02718246490011,40.61601711616431],[-74.02773274491355,40.61541077191828],[-74.0290129242641,40.614000105355316],[-74.02927435380454,40.61371201632833]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02650036803593,40.639673316086004],[-74.02634751299246,40.63957524872549],[-74.02620276541117,40.639470092189875],[-74.0260669286775,40.639358431671816]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01398026751737,40.60342796688883],[-74.01423087504398,40.603142740648565],[-74.01452089665703,40.60281266301773]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01899546812677,40.63675410355976],[-74.0190540606447,40.63669904500444]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0304730729105,40.632098967408616],[-74.03063851169657,40.63169649948075],[-74.03076395882779,40.63139134328966]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03228520129832,40.63292279040538],[-74.03252829042374,40.63298163381959],[-74.0329335487138,40.633077216644764],[-74.03300972797861,40.633095187369044]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02355676027709,40.627242523740215],[-74.02385329376379,40.626514473407404]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0350366952782,40.637414025851776],[-74.0353644639051,40.63751382041346]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02456733672958,40.64177087260064],[-74.02512022214226,40.64121007239311]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0365845091119,40.61089265321882],[-74.03647085469291,40.610724627289166],[-74.03630120437012,40.61054466239991],[-74.03624030914132,40.61048946088244],[-74.03623222335878,40.610483881031016],[-74.03622378998124,40.61047860920681],[-74.03621502726146,40.61047365880633],[-74.03620595740752,40.61046904054434],[-74.03619660174894,40.610464766476184],[-74.03618698337246,40.610460846143624],[-74.0361771244855,40.61045728925631],[-74.03616704905367,40.61045410451813],[-74.03615678148111,40.61045129879008],[-74.03614634551312,40.610448880106],[-74.03613576731108,40.610446852813375],[-74.03612507105885,40.6104452229356],[-74.03611428357651,40.610443993479755],[-74.03610342926639,40.61044316795626],[-74.03609253560765,40.61044274870186],[-74.03608162766008,40.61044273554114],[-74.03607073224259,40.61044312930335],[-74.03596350027992,40.61045420691732],[-74.03578781851749,40.61062489520545]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02195278042983,40.637452235497214],[-74.02219951245164,40.637211965502566]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0268776058058,40.6373906299475],[-74.02680572243769,40.63736238818808]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02195278042983,40.637452235497214],[-74.02191237052556,40.637318175177874],[-74.02150723576601,40.63708611530419],[-74.02117829523179,40.636889426700016],[-74.02103519666349,40.63680169383088],[-74.02096829182192,40.63675358063999],[-74.02094226269145,40.63670262840587],[-74.02094636322941,40.63665099654631]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02714409130141,40.61531284587685],[-74.02719165242974,40.615255742968905],[-74.02728458766258,40.61514416329232],[-74.02768270876913,40.614664864433266],[-74.02790699359782,40.614403623262184],[-74.0279971829814,40.61429649356853],[-74.02807080377022,40.614214888198724],[-74.02815109021289,40.61413572187747],[-74.02822727777382,40.614060594622885],[-74.02825328792369,40.614034946425356],[-74.02845161016938,40.61386501448037],[-74.02860728343553,40.613748835418114],[-74.02897220554718,40.61351613045301]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03468801069191,40.61724546903249],[-74.03466771409552,40.61723435375202],[-74.03465707764904,40.61723179946371],[-74.03463658336906,40.617226942947966],[-74.03462671432295,40.6172246402215]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03053725893822,40.60988983056623],[-74.02979312008893,40.61086565998481]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04095391769229,40.63012729424754],[-74.04087635200995,40.630111937360105]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01640622335879,40.622014176886864],[-74.0169877795685,40.62145382444481]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01932871294058,40.63708062104839],[-74.01892465780084,40.63682599451224]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02895446719153,40.606947408075264],[-74.02878765258042,40.60738258183073]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02325796263634,40.62797141135196],[-74.02355676027709,40.627242523740215]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0262631546062,40.627919956893415],[-74.02385329376379,40.626514473407404]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03528321938438,40.634745343530874],[-74.0353058971767,40.63468854087334],[-74.03540730129517,40.63443449117356],[-74.03555598232235,40.634062017580575]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02245052470514,40.62120173246406],[-74.02161286131559,40.62218380192602]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01793148581856,40.60467612710664],[-74.0181700678162,40.60457546481139],[-74.01841816354282,40.60448737288185],[-74.01867402519612,40.60441258799854],[-74.01884666051637,40.604372398075654]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02980645882604,40.61618076581306],[-74.03008813789242,40.61584378063325]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0217716818721,40.63919193654847],[-74.02174220735287,40.63907249785077],[-74.02171064156752,40.63895526521858],[-74.02165752918506,40.63881172344272],[-74.0215992224088,40.63868943544506],[-74.02158872937285,40.63866742819537],[-74.02148856318281,40.638504533895954],[-74.02137014718652,40.63834973904815],[-74.02123523188197,40.638204735477906]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03649979593658,40.63578261429032],[-74.0366956870326,40.635304052079086]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02452013786399,40.63216736274899],[-74.02202374839493,40.63098801670602]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0326345256723,40.60986210331438],[-74.03249479053753,40.60979497333011],[-74.03234410811235,40.60974108339199],[-74.03218582295283,40.60970183825631],[-74.03202364635744,40.60967795672998],[-74.03185367197298,40.60965469833358],[-74.03168624166389,40.60961420293214],[-74.03152582230847,40.609556866020164],[-74.03137669168525,40.60948396453774],[-74.03124251480898,40.60939755093516],[-74.03112612755817,40.60930032623657],[-74.03107680891608,40.60922672198123],[-74.03101732946419,40.60915707396338],[-74.03094856553987,40.60909257021456],[-74.03087175807111,40.60903422762096]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03187755743556,40.61721328760671],[-74.03167122262958,40.6171106130959],[-74.03160330357393,40.61707681759593],[-74.03084507393038,40.616699488714296]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02119382240137,40.640660502364426],[-74.01965977575708,40.63974211959376]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03918275293425,40.61785548724426],[-74.03876752814024,40.617181129201875]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01536728802037,40.619563617220855],[-74.01316381314865,40.61823617216211]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02173709503862,40.631687882624895],[-74.01973749841753,40.63077744888532],[-74.0195988799454,40.63071433742979],[-74.0192589306462,40.63055955035461]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03425098497237,40.63624080560025],[-74.03455705153256,40.636310279070585],[-74.0346311431607,40.63632956360418]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02982641415649,40.63613858687818],[-74.02942921523434,40.636016506650954],[-74.02894215584342,40.63586681102552]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01931290379294,40.61921695210262],[-74.01989460071066,40.618656476704864]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01500072034628,40.62676890709503],[-74.0128273095168,40.62545573495838]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03616248381722,40.61816830032512],[-74.03649125984288,40.61798915516788]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02453841857515,40.63832493659562],[-74.02424880433644,40.63817869105767],[-74.02396420182187,40.63802785044795],[-74.02366924912953,40.63788866420887],[-74.02336521220563,40.6377617173486],[-74.02305341410933,40.63764749569802]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02101999757603,40.63841201143376],[-74.02108694468097,40.63834699980372]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03039492080207,40.608721072630324],[-74.03079671779996,40.60796647248415]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02000806065679,40.63725981629294],[-74.0198284563523,40.63715424347163],[-74.01968076242356,40.63706742257479],[-74.01954557800228,40.63698831739978],[-74.0190540606447,40.63669904500444]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03505731294625,40.6097408281576],[-74.03502325663713,40.609691715354884],[-74.03498838208205,40.60963566859854]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03344733644003,40.63202844056258],[-74.03299421803494,40.631921022477414]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03203646331005,40.6354752371198],[-74.0323165198636,40.63479116049515]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02250538867234,40.640560907792185],[-74.02246253935158,40.64053889857811]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0318664500191,40.63677131147638],[-74.03188431700718,40.636732719179136],[-74.03189913712497,40.6367010798224],[-74.03218063405437,40.63617208135997],[-74.03218437872638,40.6361671638524],[-74.03219615457772,40.63614735801442],[-74.03221758097386,40.63611168234272]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01916517337347,40.60379778367388],[-74.01910090435524,40.60377437196514]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03255489248096,40.62701008290811],[-74.03283230942773,40.62632904897046]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02101222340077,40.63346837978414],[-74.01973592316727,40.63288491697105]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02423774621609,40.63285893136],[-74.02452013786399,40.63216736274899]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03987461127993,40.62872469808542],[-74.03986889213476,40.6287012606311],[-74.03986369034203,40.62867775397525],[-74.03985900590462,40.628654183813914],[-74.03985484168459,40.62863055701485],[-74.03985119680605,40.62860688061462],[-74.03984807435086,40.62858316131331],[-74.03984547344243,40.62855940497482],[-74.03984339628335,40.62853561880215],[-74.03984184309685,40.628511809328835],[-74.03984081366649,40.62848798325614],[-74.03984030887543,40.62846414761999],[-74.03984032850724,40.628440309121586],[-74.03984087256497,40.62841647379197],[-74.0398419412724,40.628392649169854],[-74.03984353397277,40.62836884095141],[-74.03984565023012,40.62834505650804],[-74.03984828960823,40.62832130270853],[-74.0398514516707,40.62829758608662],[-74.03985513510155,40.628273913176365],[-74.03985933902439,40.62825029017655],[-74.03986406146446,40.62822672496165],[-74.03986930286418,40.62820322289238],[-74.03987506014876,40.6281797908384],[-74.03988133200266,40.62815643600382],[-74.03988811688978,40.62813316442013],[-74.03989541327437,40.6281099826214],[-74.03990321940083,40.628086897309274],[-74.03991153109482,40.62806391501871],[-74.03992034792006,40.628041042450924],[-74.03992966724103,40.628018285470205]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02786539430524,40.60893238159827],[-74.02725974486593,40.60949388465354]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02012665551166,40.635673785779716],[-74.0177562083344,40.63425010916054]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02395966789459,40.615160771407304],[-74.02422409366226,40.61491587050355],[-74.02424279614817,40.61475742175351],[-74.02425056168408,40.614616844440505],[-74.02473347705897,40.61422837252916]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02277383473061,40.621581553445516],[-74.02292851785276,40.62170072461569],[-74.02333754986502,40.62194101795194]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03599609905362,40.609309069918936],[-74.03603977777915,40.609295639001864]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03649979593658,40.63578261429032],[-74.03544163164408,40.635531376259586],[-74.03499884243531,40.635426240975704]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01852944048841,40.632333576625285],[-74.01889421954473,40.63144343450422]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0391088652061,40.625371381658674],[-74.03940662450633,40.62463864368792]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03569291352058,40.61071640424595],[-74.03513038181048,40.61127556492114],[-74.03487149024217,40.611366235710996]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0341899573684,40.615804884024065],[-74.03327338635061,40.615350542745546]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02080897981277,40.64133958160862],[-74.01908019765466,40.6402972882069]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02108694468097,40.63834699980372],[-74.0210486772876,40.638303529489896],[-74.02101552967812,40.63826308446196]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03589868578145,40.63035589610398],[-74.0359144559417,40.63031674543428],[-74.03603691068763,40.63001277281996]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01497963664175,40.64062546817968],[-74.01556266734983,40.64006663684698]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02022933658131,40.64193209968427],[-74.01849303797555,40.64087580502753]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03434972468874,40.637020679512915],[-74.0344241002268,40.63704026162446],[-74.03451022843325,40.6370629109588],[-74.03484871409914,40.637159542346346]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0257105238426,40.61999538774777],[-74.02566120770801,40.62005685017528]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02297788444453,40.62143139583279],[-74.02369674686376,40.62094919252825]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01548864420832,40.62979212096028],[-74.01606909467468,40.6292336382119]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02656062871394,40.62718718062923],[-74.02685720207243,40.62645774644725]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01671283875817,40.60568263485323],[-74.01664484245991,40.60564376022395],[-74.01651772637472,40.605571124398274],[-74.01634056298481,40.60551294912653],[-74.01632223445839,40.60550131650344],[-74.01604435087668,40.60576207505472],[-74.01616775836033,40.60583818781687],[-74.01634014696205,40.605938058157406],[-74.01640553134816,40.60597592481384]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02113216418589,40.623051786081625],[-74.02165021038866,40.6224486469831]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03631596928282,40.617707852005886],[-74.03607763349201,40.61731632634254]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03452255511358,40.61720230259361],[-74.03458526689862,40.61721736753899]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01648765885447,40.62577531294818],[-74.01442148581089,40.624528145447826],[-74.01403349690504,40.62429394156755]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0197189447665,40.64254997093113],[-74.01962203731924,40.64250143174682]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03571148771276,40.619274919844784],[-74.03598944354782,40.61859585874571]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0177962054603,40.634170868506985],[-74.0163860448736,40.63316196515229]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03113030156125,40.63525421064371],[-74.03069231017044,40.63515254274001],[-74.03026763133677,40.635053967601436]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02202374839493,40.63098801670602],[-74.02003020820511,40.63007499298579],[-74.01955007238033,40.62985508792623]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02466370948821,40.63998338594343],[-74.02461453278433,40.63995336415827],[-74.02457354910433,40.639923934992396]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01591473467845,40.633365549075094],[-74.01602010138618,40.633317113159414],[-74.01612995805846,40.633264021233344]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03613434436348,40.63004112661664],[-74.03603691068763,40.63001277281996]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03168478453624,40.61067684567532],[-74.03163231846155,40.610701856956034],[-74.03158013366556,40.61072720754916],[-74.0315282338841,40.61075289594625],[-74.03147662263308,40.6107789203039],[-74.03142530452737,40.610805278443415],[-74.03137428264326,40.610831968521474],[-74.03132356049676,40.61085898886226],[-74.0312731424831,40.61088633745459],[-74.03122303145854,40.610914011952694],[-74.03117323181857,40.610942010848035],[-74.0311237461995,40.610970331459804],[-74.03107457899688,40.610998972279475],[-74.03102573394636,40.61102793096104],[-74.03097721390489,40.611057206331424],[-74.03092902260748,40.61108679453686],[-74.03088116335097,40.611116694906784],[-74.03083364053047,40.61114690475995],[-74.03078645634278,40.611177421415704],[-74.03073961518376,40.61120824370062],[-74.03069311990953,40.611239368431264],[-74.03064697403632,40.61127079376432],[-74.03060118042086,40.61130251768907],[-74.03055574367811,40.611334537356754],[-74.03051066556561,40.611366850589434],[-74.0304659506988,40.61139945537595],[-74.03042160105487,40.61143234920324],[-74.03037762102917,40.611465529390166],[-74.03033401369815,40.61149899342334],[-74.03029078081981,40.61153273996252],[-74.03024792700893,40.61156676532126],[-74.03020545490263,40.61160106765649],[-74.03016336757726,40.61163564395228],[-74.02987563557507,40.611872862190516],[-74.02980667854413,40.61193452990773],[-74.02960034856531,40.61211902790463],[-74.02933821462244,40.612373573749665],[-74.02908989609385,40.61263585968681],[-74.02907476624847,40.61265327915269],[-74.02900218093431,40.61269029122895]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.017460462067,40.62863643595272],[-74.01727561504546,40.62899814917596]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01908019765466,40.6402972882069],[-74.01965977575708,40.63974211959376]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03389413818088,40.622581028767506],[-74.03391035713318,40.62254327372255],[-74.0339203676065,40.62251995662855],[-74.03415755183897,40.621943319379646],[-74.03415974720777,40.62193780719811],[-74.0341747368717,40.62190015232564]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03225653845509,40.627740290327054],[-74.03255489248096,40.62701008290811]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.030665964162,40.63639172695867],[-74.03024374702804,40.63626442413395],[-74.02982641415649,40.63613858687818]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02185196389816,40.63981609782905],[-74.02183558532252,40.639472985583964],[-74.0217985851795,40.63929518543931],[-74.0217716818721,40.63919193654847]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0348848573726,40.62242829228599],[-74.0349045796654,40.622378685721806],[-74.03497879759819,40.6221942186772],[-74.03498955013268,40.622167559566876],[-74.0349922411391,40.622161029983964],[-74.03500193217121,40.622138162874236],[-74.03501813871564,40.6220999488135]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04047541710517,40.62078994423459],[-74.03942183650594,40.62089997571317]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0192056339431,40.603734632362084],[-74.01913887209786,40.60371321100139]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0209540417791,40.638321007931715],[-74.02101552967812,40.63826308446196]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02788792587137,40.63630874892765],[-74.02831656444577,40.63525568567155]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02250538867234,40.640560907792185],[-74.02263060680491,40.640500773512436],[-74.02275582383226,40.6404406395987],[-74.02301540073123,40.6403317961436],[-74.02328274799515,40.64023494589951],[-74.0234477115474,40.640183699606446]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0231679360648,40.61666371395202],[-74.02274096599584,40.61715193809612]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02101552967812,40.63826308446196],[-74.02091701229124,40.63817967475092],[-74.02037998679783,40.63772499451369]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04127389915878,40.620545249874645],[-74.04105720283887,40.61953485681146],[-74.04103227104835,40.619418605231374],[-74.04088886504819,40.61878822908297],[-74.04084361983146,40.61859672770614],[-74.04050563218887,40.617064542623545],[-74.04043585401399,40.616722159288194],[-74.04033458761805,40.616225263170925],[-74.04019026044632,40.61573096379072],[-74.04002530151614,40.61533590629542],[-74.03987723460011,40.61498129907646],[-74.03957348242191,40.61445346501291],[-74.03928413776546,40.614034551159826],[-74.03920068134899,40.61391372144101],[-74.03883577219288,40.61348163073594],[-74.03829786061944,40.612949873519916],[-74.03821602782614,40.612869910379565],[-74.03808304195385,40.612739961609556],[-74.03734484993312,40.61218485223339],[-74.03704671197396,40.611942240306085],[-74.03692400074978,40.611836688134446],[-74.03680564657859,40.61173488272858],[-74.03675852611157,40.61169127913059],[-74.03671180038377,40.61164742945453],[-74.03666547093502,40.61160333604579],[-74.03661953952503,40.61155900141722],[-74.03657400945217,40.61151442774612],[-74.03652888269526,40.611469616372574],[-74.03648415991486,40.61142456980974],[-74.0364398446288,40.61137928973232],[-74.03639593859724,40.61133377965828],[-74.03635244467773,40.61128803992227],[-74.03630936309182,40.61124207437787],[-74.0362666966971,40.61119588352718],[-74.03622444857265,40.61114947088781],[-74.03618261959843,40.6111028384703],[-74.03614121131336,40.61105598744732],[-74.03610022723595,40.61100892100127],[-74.03605966802643,40.61096164147778],[-74.03601953588347,40.610914150551935],[-74.03597983322595,40.61086645073632],[-74.03594056093365,40.61081854387394],[-74.03590172186519,40.610770432644784],[-74.03586331690073,40.61072211972949],[-74.03582534823855,40.6106736063005],[-74.03578781851749,40.61062489520545]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0343355365717,40.62984715685466],[-74.03165800059992,40.62919908300082]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03084507393038,40.616699488714296],[-74.03048495050112,40.61651863433924]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03157081585907,40.6175731393016],[-74.03187755743556,40.61721328760671]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0378975918966,40.632286706407285],[-74.0373379855588,40.63215182073484],[-74.03725223040435,40.632131154915655],[-74.0371680717415,40.6321108662934],[-74.03708657313658,40.63209122525476],[-74.03699464745893,40.63206906587324],[-74.03642637951485,40.63193208913182]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01549855009637,40.606841524276895],[-74.01469487567537,40.606424283197335]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03719749671605,40.63004157093969],[-74.03732104650523,40.629741081858306]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03766509208317,40.61518117776205],[-74.03528582742767,40.61602520732421]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02835031608427,40.62279862692517],[-74.02621402560658,40.621491677902604]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02917223570252,40.613665332380094],[-74.02922249135375,40.61368969674752],[-74.02927435380454,40.61371201632833]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03438213484671,40.639355147613934],[-74.03350157769745,40.63908858359741]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03199920938353,40.617784841479654],[-74.03230579701483,40.61742673534823]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01830796925623,40.6268715915053],[-74.018576202052,40.626317751414284],[-74.01868219687398,40.626098894355685],[-74.0187756079456,40.625863636347496]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03283896605629,40.636302614552854],[-74.03286546876528,40.636254843929834],[-74.03288193205519,40.63622526574846],[-74.03297007220803,40.63604099448367],[-74.03298781199574,40.63598566159275]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0290459533386,40.61345829828121],[-74.02955746230028,40.61304459560068],[-74.0298161671225,40.612835355012095],[-74.0301167037708,40.61260522073694]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02930182080097,40.61789600944142],[-74.03048495050112,40.61651863433924]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0326345256723,40.60986210331438],[-74.0327758936268,40.60976383464716]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01348255916146,40.61103739791961],[-74.01273688241048,40.61058825791962]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0357017562614,40.61051585256555],[-74.0358353564697,40.61037138543281],[-74.03590966881802,40.610282517099826],[-74.0359653648876,40.61018377536049],[-74.03599944496524,40.610078728040754],[-74.03601053047562,40.609971571522514],[-74.03599910655197,40.60986655603834],[-74.03599144258406,40.609809375601806],[-74.03596550986597,40.60975106553831],[-74.03592036661725,40.60969673325108],[-74.03585835442121,40.60965169083391],[-74.03578497120701,40.60961993445984],[-74.03570729428947,40.60960300183534],[-74.03563198877167,40.60959991804486],[-74.03555757706988,40.609612539101285],[-74.03548467576007,40.60964298171223],[-74.0354242142967,40.6096907010588],[-74.03538561881197,40.60975017401116],[-74.03537257118597,40.60981273737182],[-74.0353820550084,40.609870386035354],[-74.03548460996056,40.610097762953934],[-74.03556528781051,40.6103342778818]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03142517458046,40.63697266263546],[-74.03150001091599,40.636993417368984],[-74.03153849305859,40.63700430304219],[-74.03164441191649,40.637034792777655],[-74.03165803206622,40.63703912902205],[-74.03225637978971,40.637243470805615]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03515733062534,40.60970591170685],[-74.03530188599167,40.609657667132176],[-74.03583329875791,40.60948773165801]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03599609905362,40.609309069918936],[-74.03604567505181,40.60935857042495],[-74.03607664215738,40.60940692063411]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03060631327827,40.63896332699042],[-74.03020313633591,40.63883642473269],[-74.02800411516877,40.63814423931867]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0228759874347,40.619466147406214],[-74.02363350473824,40.61853764777728]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03607030710799,40.63730595025948],[-74.03444160139642,40.636799673550165]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03523521442837,40.62764527581542],[-74.03255489248096,40.62701008290811]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.026950773583,40.6335159315419],[-74.02603899600105,40.63330237636062]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01970390025541,40.63608035103739],[-74.01971569892768,40.63608138819437],[-74.01972754717958,40.63608201841487],[-74.01973942060039,40.63608223986024],[-74.01975129455978,40.636082051697066],[-74.01976314596756,40.63608145577214],[-74.01977494975394,40.63608045242483],[-74.01978668150944,40.63607904400475],[-74.01979831792406,40.63607723252629],[-74.01980983524874,40.63607502268434],[-74.01982120995422,40.636072418671226],[-74.01983241807183,40.636069426019574],[-74.01984343717226,40.63606605026173],[-74.01985424504662,40.636062298437786],[-74.0198648199262,40.63605817892796],[-74.01987513916242,40.636053699275045],[-74.01988518208653,40.63604886886428],[-74.01989492803006,40.63604369825361],[-74.01990435764365,40.636038196660515],[-74.01991345069936,40.6360323766532],[-74.01992219026738,40.636026249291604],[-74.02021970090256,40.635732702807026]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0250473472466,40.62358917746349],[-74.02534486402693,40.62285939371732]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02207654556122,40.620974567338685],[-74.02208383401923,40.62096558773604],[-74.02219158527471,40.620837243118004],[-74.02263226204572,40.62032244659847],[-74.0229220192707,40.619983964591476]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03404330705281,40.6233631942251],[-74.03234884873444,40.62296256471544],[-74.03135988374659,40.62272872165521]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03650777979973,40.63901179097763],[-74.03645470561281,40.63899651715679],[-74.03642076105058,40.63898596440511]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02008667268495,40.622420952159324],[-74.01970491557115,40.62218496450551]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03386577352411,40.61659397130616],[-74.03389978866599,40.61651131124679]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03134204356986,40.61111384128102],[-74.03130697688962,40.61113951359394],[-74.03127228204738,40.61116547779788],[-74.03123796343819,40.61119173070897],[-74.0312040252371,40.61121826880828],[-74.03117047096023,40.61124508958225],[-74.03113730588198,40.61127218984675],[-74.03110453285846,40.6112995659157],[-74.03107215584494,40.61132721410275],[-74.03104017967655,40.61135513189395],[-74.03100860698972,40.61138331577083],[-74.03097744327826,40.61141176137652],[-74.03094669051971,40.61144046636535],[-74.03091635332898,40.61146942721833],[-74.03088643478226,40.61149864041687],[-74.03085693927432,40.61152810160435],[-74.03082787032139,40.61155780809966],[-74.03079923055991,40.61158775604929],[-74.03077102460469,40.61161794143162],[-74.03074843461279,40.61164386655122],[-74.0307253755968,40.61166955038247],[-74.03070185173077,40.611694987730594],[-74.03067786674983,40.61172017490861],[-74.03065342636647,40.61174510571622],[-74.03062853475528,40.61176977596373],[-74.03060319740946,40.61179418062354],[-74.03057741740473,40.6118183158414],[-74.03055120155314,40.61184217625423],[-74.03052455402927,40.611865757337384],[-74.03049748010682,40.61188905456586],[-74.0304699850595,40.61191206324716],[-74.03044207372163,40.611934779359004],[-74.0304137522465,40.61195719871123],[-74.03038502524844,40.61197931677907],[-74.03035589954011,40.61200112903708],[-74.03032637885674,40.61202263129582],[-74.03029647067106,40.61204382020239],[-74.0302661791575,40.61206469039448],[-74.03023551112969,40.61208523935708],[-74.03020447230101,40.61210546189496],[-74.03017306860541,40.61212535448818],[-74.0301413061966,40.61214491344917],[-74.03010919122819,40.61216413475535],[-74.02915343608798,40.612694494295916]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03123996401696,40.6112874071268],[-74.03144638542759,40.61111981450731]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02692778872888,40.62421392022086],[-74.02669833117135,40.62407401520679]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0321580508527,40.60874549520581],[-74.03228786881635,40.60892193989224],[-74.03232265751944,40.6090844340803]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03032234460834,40.63964722023463],[-74.02940982440265,40.63935795851155]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03788517257021,40.61274113419476],[-74.03725666587019,40.61225491431615],[-74.03703066351878,40.61206551646257],[-74.03696136213517,40.612007438555196],[-74.03671964068474,40.611790283078776],[-74.03660774329742,40.61169129592343],[-74.0362671322675,40.61136519167749],[-74.03594340814116,40.61102924936061],[-74.03587574173788,40.61094474057697],[-74.03569291352058,40.61071640424595]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02822439711,40.62918642393322],[-74.02824103462196,40.62914848131079],[-74.02835300020536,40.628893174103304]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01815162013094,40.62033644283249],[-74.01594933984525,40.61900487290429]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01560205035204,40.63351697794145],[-74.01514630746092,40.6332219384872]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03531135378017,40.618060142264085],[-74.03567143483521,40.61814305017874]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0203921699701,40.63496479444601],[-74.0205066797487,40.634706342881785]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01448201327624,40.60891037993433],[-74.01376688929142,40.608478685787745]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01381390001302,40.64174524676127],[-74.01439632401156,40.64118583630968]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03168478453624,40.61067684567532],[-74.03218042435367,40.610513614505145],[-74.03268156207943,40.610360456834215]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02582777972842,40.63730700527587],[-74.02547192644472,40.63714013731289]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01774227617491,40.64140075417448],[-74.01556266734983,40.64006663684698]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03556108632614,40.63791729990148],[-74.03487286562138,40.63770451093108],[-74.03460785295549,40.63762257172542],[-74.03415742094354,40.63748330644836]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02889666840994,40.64121402130954],[-74.02910484253009,40.641415432797274],[-74.02932438766243,40.64161017722695],[-74.0295547594865,40.64179768692002],[-74.0297953078998,40.64197744951087],[-74.0300453588338,40.64214901429326]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03499884243531,40.635426240975704],[-74.035150405857,40.63506335741025],[-74.03528321938438,40.634745343530874]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03432262014285,40.622682209635734],[-74.03389413818088,40.622581028767506],[-74.03163907988211,40.62204849142787]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0177562083344,40.63425010916054],[-74.0177962054603,40.634170868506985]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01396088612057,40.63815326741945],[-74.01456685527899,40.63757090781398]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0127753791902,40.63929563223955],[-74.01335669051925,40.638735308633656]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0282796052702,40.6374676390882],[-74.0286577676278,40.63654600852422]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03554966032256,40.61476009258852],[-74.03551061242374,40.61477447696254],[-74.03515574383597,40.61490521502758]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01935922218559,40.603520206226705],[-74.01935308327937,40.603532171685075],[-74.01926195098474,40.603752157200816]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02121548264651,40.61847198527922],[-74.02145207558851,40.618027191687425]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02089938190545,40.61926265491913],[-74.01989460071066,40.618656476704864]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02892473285023,40.612477702955296],[-74.0289466782121,40.61244980855365],[-74.02913136584412,40.61221505468852],[-74.02914181742423,40.61220232603822],[-74.02914187784604,40.61220225348286],[-74.02915234771609,40.61218963472595],[-74.02915241538872,40.61218955395983],[-74.02916285762731,40.612177098214595],[-74.02916295562075,40.61217698125454],[-74.02917364201772,40.61216436612632],[-74.02917368244572,40.61216431837031],[-74.02918440580768,40.61215178900653],[-74.02918446469228,40.61215172030471],[-74.02919504484811,40.61213948247664],[-74.02919525226427,40.61213924470039],[-74.02920616424866,40.61212675147288],[-74.02920618951693,40.612126723489126],[-74.02921715911951,40.61211429122646],[-74.0292172138302,40.61211422922685],[-74.02922823094418,40.61210187032871],[-74.02922824698389,40.61210185223149],[-74.02923937862364,40.612089489114915],[-74.02923939092813,40.612089475374404],[-74.0292506025976,40.61207714775251],[-74.02925065730916,40.61207708793076],[-74.02926190220697,40.6120648472468],[-74.02926193384786,40.61206481373294],[-74.02927327833085,40.612052587094965],[-74.02927348926859,40.61205236037457],[-74.02928472921073,40.61204036763245],[-74.02928478831737,40.612040304458986],[-74.02929625506661,40.61202818936181],[-74.02929630626323,40.612028135069366],[-74.02930785589848,40.612016052282996],[-74.02930796312643,40.612015940178786],[-74.02931953148666,40.61200395673109],[-74.02931960004285,40.612003886518984],[-74.02933128139183,40.611991903543874],[-74.02933135851777,40.61199182512064],[-74.02934310495417,40.61197989205132],[-74.02935500327334,40.61196792342585],[-74.02935507161028,40.611967854721534],[-74.02936697437077,40.61195599750043],[-74.02936705149759,40.61195592125505],[-74.02937890728069,40.611944224202375],[-74.0293790189058,40.61194411393981],[-74.02939113709884,40.61193227408411],[-74.02939118324359,40.61193222967714],[-74.02940332719113,40.61192047776627],[-74.02940339421093,40.61192041341801],[-74.02941536263376,40.61190894216173],[-74.02941559665433,40.61190871912082],[-74.0294279257116,40.6118970160784],[-74.02942795383845,40.611896990271724],[-74.02944033348076,40.61188535188119],[-74.02944039478787,40.611885294235535],[-74.02945281183031,40.611873731557125],[-74.0294528298491,40.61187371513468],[-74.02946536229962,40.61186215644603],[-74.02946537658292,40.61186214371016],[-74.02947798400915,40.61185062604549],[-74.02947804597642,40.61185057007494],[-74.02949067629984,40.61183914136086],[-74.02949071167858,40.61183911002387],[-74.02950344005063,40.61182770155423],[-74.02950367693359,40.61182749023942],[-74.02951627284399,40.61181630796642],[-74.02951633964625,40.61181624931413],[-74.02952917621862,40.611804960429495],[-74.02952923445113,40.61180490998832],[-74.02954214951504,40.6117936589436],[-74.02954226971565,40.6117935547097],[-74.02955519207403,40.61178240417898],[-74.0295552689854,40.61178233882292],[-74.02956830367592,40.61177119647076],[-74.0295683900363,40.611771122903335],[-74.02958148454013,40.611760034981195],[-74.0296142886409,40.611732411732206],[-74.02964747819459,40.61170505742584],[-74.02968105034473,40.611677975078024],[-74.02971500091613,40.61165116837516],[-74.02974932617278,40.61162463983079],[-74.02978402149976,40.61159839279639],[-74.02981908382074,40.6115724301204],[-74.02985450786122,40.61154675481935],[-74.02989029120465,40.61152137041167],[-74.029926428576,40.6114962785737],[-74.02996291602008,40.61147148299176],[-74.02999975002099,40.61144698651444],[-74.03003692508446,40.611422791990826],[-74.03007443857378,40.611398901934194],[-74.03011228433512,40.61137531902634],[-74.0301504601716,40.61135204594794],[-74.03018109309704,40.61133477036395],[-74.03023006782752,40.611306408076295],[-74.03027938560544,40.61127839329992],[-74.03032904225508,40.611250727543215],[-74.03037903294181,40.611223413487494],[-74.0304293530507,40.611196453478975],[-74.03047999906607,40.61116985003108],[-74.03053096615331,40.61114360565758],[-74.03058225057637,40.6111177216993],[-74.03063384684144,40.6110922011728],[-74.03068575099303,40.61106704608906],[-74.03073795907585,40.61104225879412],[-74.03079046625493,40.611017840796656],[-74.03084326835533,40.61099379477781],[-74.03089635988279,40.61097012258151],[-74.03094973710185,40.61094682638621],[-74.03100339517789,40.610923908203176],[-74.03105732993544,40.610901369373366],[-74.03111153588061,40.61087921241084],[-74.03116600905832,40.610857439661686],[-74.0312207446333,40.61083605162942],[-74.03127573755181,40.61081505166561],[-74.0313309842978,40.61079444077606],[-74.0313864780582,40.61077422063752],[-74.03144221553737,40.61075439342842],[-74.03149819212038,40.610734960489935],[-74.0315544018735,40.6107159234986],[-74.03161084128112,40.610697284130346],[-74.03168478453624,40.61067684567532]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02534886452769,40.61472214482855],[-74.02540964782301,40.61474341997537],[-74.02546455733281,40.61476255285916],[-74.02565020416453,40.61482724960668]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03489726686202,40.60979182728423],[-74.03505731294625,40.6097408281576]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01769159650473,40.6173259484068],[-74.01548877590352,40.615997917265965]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03463999435027,40.62910561340451],[-74.03493758410197,40.62837499488119]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03732104650523,40.629741081858306],[-74.03463999435027,40.62910561340451]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0301167037708,40.61260522073694],[-74.03049069960784,40.612173353320536]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01717481839918,40.64195100363017],[-74.01497963664175,40.64062546817968]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02444889042178,40.6250484458383],[-74.02475042751018,40.62432075214108]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03374248159624,40.631296601278436],[-74.03106070351704,40.63066101398831]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03558827806658,40.63976311168031],[-74.03438213484671,40.639355147613934]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03457821372056,40.63424005118241],[-74.03521658870763,40.63438973987444],[-74.03530492279242,40.63441048816965],[-74.03531322148764,40.634412484404464],[-74.03532970159978,40.63441634288552],[-74.03540730129517,40.63443449117356]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02310593208485,40.63999532592684],[-74.02321780213282,40.63990151460357],[-74.02331683024384,40.639797781724845],[-74.0234008536293,40.639685731345956],[-74.0234682183412,40.63956733547941],[-74.02348203738586,40.639533212305636]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03203646331005,40.6354752371198],[-74.0315424419052,40.63535474025528],[-74.03113030156125,40.63525421064371]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02119408413276,40.625815947890985],[-74.02132956679132,40.62548597220487],[-74.02149466602913,40.625083859316064]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0210486772876,40.638303529489896],[-74.02101552967812,40.63826308446196]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02132832742268,40.638916299282236],[-74.02127689735428,40.63878230228756],[-74.0212076655122,40.63865227143843],[-74.02112155518061,40.63852822307352],[-74.02101999757603,40.63841201143376]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03095125999282,40.60682549683299],[-74.03100116586802,40.60684334114023],[-74.0310497082994,40.606876376991785],[-74.03108554455913,40.60692567093187],[-74.03109624199504,40.60698558864954],[-74.03107671421209,40.60704420010944],[-74.03103378566611,40.60709008450753],[-74.03098064022501,40.607118717158976],[-74.03092840915339,40.607132140081774],[-74.02997954531816,40.60712552950822]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02098508311434,40.626323879460436],[-74.0210529134339,40.62636331855861],[-74.02115643231436,40.62642331922225],[-74.02132707380309,40.62652483956534],[-74.02135977554988,40.626520547105436]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03019093198031,40.63279069500373],[-74.0304730729105,40.632098967408616]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02566011106731,40.6293777102856],[-74.02595819003183,40.62864726756076]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03426005919847,40.617858626493046],[-74.03442486409209,40.617897399052914]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03957464140895,40.618500963440496],[-74.03728969733213,40.61930655864202]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03660441542603,40.636569148229],[-74.03609452612885,40.63644918928899],[-74.03516783510013,40.63621825006255],[-74.03472092466451,40.63610686565888]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03250351930691,40.6105896807567],[-74.03265265152646,40.61053783149366]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01432214759274,40.63091131175038],[-74.01490317317815,40.63035265462519]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03414586365614,40.615913472934395],[-74.0341899573684,40.615804884024065]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02101222340077,40.63346837978414],[-74.02137456360131,40.63257860041459]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01310890671809,40.63552850051431],[-74.01324489560523,40.63539747360349]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03489726686202,40.60979182728423],[-74.03505731294625,40.6097408281576]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02108694468097,40.63834699980372],[-74.0210486772876,40.638303529489896]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01304073202043,40.621802868641495],[-74.01362246814824,40.62124382115554]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0260978912955,40.64027001982279],[-74.02623698651284,40.64012649017486]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03607664215738,40.60940692063411],[-74.03611335567324,40.60939472840671]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02002224833126,40.60326237593874],[-74.0200043601791,40.60325926636326],[-74.01998635390301,40.603256582999556],[-74.01996824620832,40.60325432819003],[-74.01995005533928,40.60325250561716],[-74.0199317988797,40.603251115445346],[-74.01991349419428,40.603250160184494],[-74.01989515952631,40.60324964016651],[-74.01987681202012,40.60324955605847],[-74.01985847035846,40.603249907857204],[-74.01984015256464,40.603250695392035],[-74.01982187512317,40.603251917822504],[-74.01980365715585,40.60325357330251],[-74.01978551470775,40.60325566149425],[-74.01976746755975,40.60325817937885],[-74.01974953153675,40.60326112544585],[-74.01973172510057,40.60326449567146],[-74.01971406517477,40.60326828720485],[-74.0196965686828,40.603272496860086],[-74.01967925254765,40.60327711977605],[-74.01966213435205,40.60328215226415],[-74.01964523035959,40.603287589295846],[-74.01962855705332,40.603293424837325],[-74.01961213003737,40.60329965352513],[-74.01959596601486,40.60330626999557],[-74.01958008102898,40.60331326704228],[-74.01956448914483,40.60332063779429],[-74.01954920618611,40.60332837588292],[-74.01953424775623,40.603336473264235],[-74.01952007242099,40.60334588544638],[-74.0195062761139,40.60335561921829],[-74.01949287026187,40.603365665196534],[-74.01947986849012,40.60337601483493],[-74.01946728156611,40.60338665841513],[-74.01945512201586,40.603397586553506],[-74.01944340038686,40.60340878886162],[-74.01943212612792,40.60342025578883],[-74.019421311325,40.603431976276305],[-74.01941096564649,40.603443939768226],[-74.01940109678257,40.60345613604414],[-74.01939171550038,40.60346855354283],[-74.01938282905029,40.60348118103878],[-74.01937444710036,40.60349400663588],[-74.01936657492274,40.603507018941364],[-74.01935922218559,40.603520206226705]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02576515663598,40.62051080618509],[-74.0257226035363,40.620489752653846],[-74.02542226113637,40.6203411346406]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03420240543339,40.63140550925466],[-74.03418775733275,40.631444857537296],[-74.03416872965066,40.63149637287942],[-74.03410900924902,40.63164794804518],[-74.03402791091237,40.631853686309555],[-74.03393047214198,40.63209815223014],[-74.03393186875594,40.632125068302464],[-74.03393562519746,40.63214399641737]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01969473945587,40.637285120781435],[-74.01955318166169,40.63720134283111]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01515631643922,40.60369719971753],[-74.01475993489775,40.603606460597604],[-74.01459842402548,40.60356948577957],[-74.01398026751737,40.60342796688883]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03079671779996,40.60796647248415],[-74.03082834483028,40.607804604506505],[-74.03039238356551,40.60745774941676]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03085413924049,40.61312223923821],[-74.03137808967088,40.61250877934178]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02580960486513,40.60862312746623],[-74.02477732246007,40.6096959975268]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03940662450633,40.62463864368792],[-74.0367255304667,40.623999477990225]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03374248159624,40.631296601278436],[-74.03404156746652,40.6305650302342]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02123523188197,40.638204735477906],[-74.02118998208482,40.63816666828789]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02969105388846,40.63651149079942],[-74.03140036672403,40.63703348175744]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01816532344843,40.626785705088835],[-74.01784193368066,40.62659069387398]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03350157769745,40.63908858359741],[-74.033880137792,40.63816726910346]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02924131468855,40.613606654745],[-74.02928761072664,40.613628705679304],[-74.02933540742167,40.613648819912726]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01635858114757,40.62513669169099],[-74.01652896312834,40.62523723748641],[-74.01676215313397,40.62501133548426],[-74.01679067645863,40.62498365842653]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01376688929142,40.608478685787745],[-74.01549855009637,40.606841524276895]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02661661073996,40.6156432261181],[-74.02673638118364,40.615503743595504],[-74.02697305026821,40.615225175216835],[-74.02712346948107,40.615048115394536],[-74.02719182098417,40.61496739421234],[-74.02747310955147,40.61463519794041],[-74.02774312721826,40.61431969861451],[-74.02783475856046,40.614211262644034],[-74.02797218050948,40.614048622208685],[-74.02821823034827,40.61376616176577],[-74.02834413809332,40.613621621350276],[-74.02869615064377,40.61296500390921],[-74.02874956791189,40.61286536177699]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03583589818798,40.633369846041106],[-74.03315548281145,40.63273497322292]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02027718520742,40.62806209037222],[-74.02059936527971,40.62727660878118]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01734316726642,40.629010403777855],[-74.01727561504546,40.62899814917596]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03957464140895,40.618500963440496],[-74.03918275293425,40.61785548724426]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03105991786607,40.62346289800923],[-74.03055563280209,40.62333927496836],[-74.02910595283603,40.62298388238133],[-74.02835031608427,40.62279862692517]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03677346601324,40.6383702218502],[-74.0370961338768,40.63768152736083],[-74.03717709244647,40.63752641421983],[-74.03737194383578,40.63715308582385],[-74.03786422617532,40.636200239858695],[-74.0378878201129,40.636154571517245],[-74.03808810950053,40.63576688922808],[-74.03855076029791,40.63487350486203],[-74.03865346798239,40.634675172028174],[-74.03906742660554,40.63382990430904],[-74.03920493315412,40.63353904549611],[-74.0397049868956,40.63248129326049],[-74.04004223369768,40.63174952043971],[-74.04008948126032,40.63164699992127],[-74.04037660375684,40.63102398282757],[-74.04044601451304,40.63084769570439],[-74.04045520461626,40.63082435523121],[-74.04074587689504,40.63008610569161]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03016416683954,40.61392701100221],[-74.03085413924049,40.61312223923821]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03263720326892,40.61400991276134],[-74.03183438380226,40.61361024336414],[-74.03125596727217,40.61332228937862],[-74.03085413924049,40.61312223923821]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03869172982165,40.62296928612613],[-74.03898886226693,40.62224739172353]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01916517337347,40.60379778367388],[-74.01918971483897,40.60376183973322],[-74.0192056339431,40.603734632362084]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01769159650473,40.6173259484068],[-74.01832578970308,40.61672605153053]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01548877590352,40.615997917265965],[-74.01611824015598,40.615384035751894]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0265998440278,40.63978656061281],[-74.02664251543516,40.63974743200312]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02927464974715,40.627832923455216],[-74.0295728483016,40.627103552092244]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01475422595298,40.633961648996596],[-74.01514630746092,40.6332219384872]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01514630746092,40.6332219384872],[-74.01317646020486,40.632013765647706]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02748855985243,40.61698424481986],[-74.0277744588336,40.61671556300193],[-74.02870035802583,40.615629982832466]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02799029442514,40.623682495139576],[-74.02803565519747,40.623571774056906]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01701910154738,40.60765441697114],[-74.01623636729718,40.60723326610034]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0177962054603,40.634170868506985],[-74.0178698664736,40.63393364218166]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02556855491359,40.63893891073422],[-74.02528261342258,40.63879724152444]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03515733062534,40.60970591170685],[-74.03530188599167,40.609657667132176],[-74.03583329875791,40.60948773165801]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01346408967055,40.63077917421278],[-74.01304862975314,40.6305236186849]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04074587689504,40.63008610569161],[-74.04089691769751,40.62957735754038],[-74.0409237057661,40.62947189659841],[-74.04098831068691,40.62921755839079],[-74.04109233410914,40.62869754329596],[-74.04115976081653,40.62823084294485],[-74.04118142699748,40.628061126965214],[-74.04133116182336,40.62688823221653],[-74.04134425644423,40.62673833405468],[-74.04135270691617,40.62664160061466],[-74.04141452180089,40.62593400227698],[-74.04145839018116,40.62521936423504],[-74.04147574023597,40.624936718752515],[-74.04149703362005,40.624589829256166],[-74.04150305851839,40.624205436240636],[-74.04150372933402,40.62416263810044],[-74.04150875423863,40.62384231261064],[-74.04150731249499,40.62379342388614],[-74.04146705415175,40.62242828572951],[-74.0414620356002,40.62236717806829],[-74.04138462438782,40.62142456823501],[-74.0413242948703,40.62094546629144],[-74.04127389915878,40.620545249874645]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03232265751944,40.6090844340803],[-74.032637494089,40.609432094762205]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04077867018931,40.63036973344771],[-74.0408427929438,40.63038479228504],[-74.04095391769229,40.63012729424754]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0341111716406,40.60924881734018],[-74.03417463496264,40.60918884940987],[-74.03426120403758,40.609082753825945],[-74.03427290613503,40.60906595270709],[-74.0342842654563,40.60904901498561],[-74.03429528024557,40.609031945687974],[-74.03430620769403,40.609014319213856],[-74.03431676687082,40.60899656267859],[-74.03432858425948,40.60897574819478],[-74.03433989597076,40.60895477119011],[-74.0343506984912,40.6089336380319],[-74.0343609863301,40.60891235726592],[-74.0343707586118,40.608890935091146],[-74.03438000984514,40.60886937904814],[-74.03438873827602,40.60884769701141],[-74.03439693995175,40.60882589585096],[-74.03440461201888,40.608803982939044],[-74.03441175272336,40.60878196598261],[-74.0344183594317,40.60875985252134],[-74.03442443016968,40.60873764959216]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02415343468138,40.62578041492029],[-74.02444889042178,40.6250484458383]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02723320357539,40.61470098398639],[-74.02762741316053,40.61425597872018],[-74.02771873782864,40.61414941588842],[-74.02785946934772,40.61398886420928],[-74.02824518202632,40.613533403201764],[-74.02868311238768,40.61295338032072],[-74.02874956791189,40.61286536177699]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03383017108433,40.641410366676816],[-74.03423723025998,40.64127204362843],[-74.03447039912106,40.64117453776109],[-74.03449703119831,40.64115984037949],[-74.0348775287117,40.64094985268533],[-74.03523874600299,40.640713455427345],[-74.03561334588098,40.64039447543278],[-74.03578097457513,40.640215562821496],[-74.03581340437307,40.64017404269436],[-74.03602440223098,40.639903898137575],[-74.03611001415675,40.63977461973062],[-74.0362356596792,40.639547145076925],[-74.03650777979973,40.63901179097763]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03441519548471,40.637949725244994],[-74.03442511560237,40.63793127956666],[-74.03453387347173,40.637754331171855],[-74.03453883379008,40.63774524327159],[-74.03457194815779,40.63768370077441],[-74.03457641259422,40.63767553191531],[-74.03458573043305,40.63765822995315],[-74.03460785295549,40.63762257172542]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02192439742745,40.63928485919066],[-74.0217716818721,40.63919193654847]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03350157769745,40.63908858359741],[-74.03196319975913,40.63861189086066],[-74.03160913630951,40.6385021796791]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03414129798401,40.618146513742104],[-74.03415562650426,40.61811168627015],[-74.03426005919847,40.617858626493046]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03017406771407,40.61834033481151],[-74.02930182080097,40.61789600944142]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02913136584412,40.61221505468852],[-74.02915631688559,40.61218488511134],[-74.02918170721989,40.61215492968664],[-74.02920753442991,40.6121251915978],[-74.02923379521953,40.61209567453098],[-74.02926048607279,40.61206638233996],[-74.02928760347389,40.61203731904604],[-74.02931514456621,40.612008488000235],[-74.02934310495417,40.61197989205132],[-74.02937148244133,40.611951536057916],[-74.02940027285184,40.61192342253373],[-74.02942947310963,40.611895555499906],[-74.0294590783798,40.61186793847552],[-74.02948908646499,40.61184057397373],[-74.0295194920913,40.61181346685391],[-74.02955029262161,40.611786619294335],[-74.02958148454013,40.611760034981195],[-74.0296142886409,40.611732411732206],[-74.02964747819459,40.61170505742584],[-74.02968105034473,40.611677975078024],[-74.02971500091613,40.61165116837516],[-74.02974932617278,40.61162463983079],[-74.02978402149976,40.61159839279639],[-74.02981908382074,40.6115724301204],[-74.02985450786122,40.61154675481935],[-74.02989029120465,40.61152137041167],[-74.029926428576,40.6114962785737],[-74.02996291602008,40.61147148299176],[-74.02999975002099,40.61144698651444],[-74.03003692508446,40.611422791990826],[-74.03007443857378,40.611398901934194],[-74.03011228433512,40.61137531902634],[-74.0301504601716,40.61135204594794],[-74.03018109309704,40.61133477036395],[-74.03023006782752,40.611306408076295],[-74.03027938560544,40.61127839329992],[-74.03032904225508,40.611250727543215],[-74.03037903294181,40.611223413487494],[-74.0304293530507,40.611196453478975],[-74.03047999906607,40.61116985003108],[-74.03053096615331,40.61114360565758],[-74.03058225057637,40.6111177216993],[-74.03063384684144,40.6110922011728],[-74.03068575099303,40.61106704608906],[-74.03073795907585,40.61104225879412],[-74.03079046625493,40.611017840796656],[-74.03084326835533,40.61099379477781],[-74.03089635988279,40.61097012258151],[-74.03094973710185,40.61094682638621],[-74.03100339517789,40.610923908203176],[-74.03105732993544,40.610901369373366],[-74.03111153588061,40.61087921241084],[-74.03116600905832,40.610857439661686],[-74.0312207446333,40.61083605162942],[-74.03127573755181,40.61081505166561],[-74.0313309842978,40.61079444077606],[-74.0313864780582,40.61077422063752],[-74.03144221553737,40.61075439342842],[-74.03149819212038,40.610734960489935],[-74.0315544018735,40.6107159234986],[-74.03161084128112,40.610697284130346],[-74.03168478453624,40.61067684567532]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03642076105058,40.63898596440511],[-74.03645963711769,40.63889435136922],[-74.03669183967781,40.638347149432676]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02528261342258,40.63879724152444],[-74.02513531926206,40.638732967844696],[-74.02499724156755,40.63865715612971],[-74.02487062773851,40.63857104010865]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03968659646677,40.623956628849086],[-74.03996068960251,40.62327570425802]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02245052470514,40.62120173246406],[-74.02233761319047,40.62113026188576]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03391660521358,40.60891417844936],[-74.033955453406,40.60886026301539],[-74.03397814612792,40.608798614180344],[-74.03398145744485,40.60873374446352],[-74.0339650962018,40.60867093580707],[-74.03393184533599,40.608614894611094],[-74.03388652770808,40.608568655399964],[-74.03366364805419,40.608484549127326]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02971318724587,40.64023833552328],[-74.02965643983067,40.64020377950492],[-74.02963131276093,40.64018848611202],[-74.02956048240651,40.64014540563858],[-74.02954218925755,40.64013456789855],[-74.02941768731807,40.64005957772949],[-74.02937062544534,40.64003267329858]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02259117959424,40.62104586058797],[-74.02245052470514,40.62120173246406]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02740487240644,40.6100459507822],[-74.02710660556804,40.61024395632412]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02788792587137,40.63630874892765],[-74.02603960456793,40.635741189299864]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02517770006332,40.63309649330162],[-74.02423774621609,40.63285893136]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01896027313887,40.6262956399302],[-74.01926375737048,40.62557626279814]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0169877795685,40.62145382444481],[-74.01478487192244,40.620124798828]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03959634008382,40.630612300796386],[-74.03962351403419,40.63058596447851],[-74.0396503340328,40.63055941752518],[-74.03967679590416,40.63053266379125],[-74.03970289855022,40.63050570528767],[-74.03972863823478,40.63047854503149],[-74.03975401144163,40.630451186039686],[-74.03977901729282,40.63042363065821],[-74.03980365249252,40.6303958827416],[-74.03982791440328,40.63036794396629],[-74.0398517999491,40.63033981801921],[-74.03987530715264,40.63031150724669],[-74.0398984338176,40.63028301550286],[-74.03992117774656,40.630254344799056],[-74.03994353520412,40.63022549915752]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02724262167769,40.61244385275721],[-74.02696974235236,40.612303264501946]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01762387638252,40.60360675051379],[-74.01746799668331,40.60350296223571],[-74.01725994155719,40.6034000192381],[-74.01697703241415,40.603267981781414],[-74.01680704384181,40.603196982474714],[-74.0165639736106,40.603104020691994],[-74.01627804685198,40.6029919465553],[-74.01611352638395,40.6029054840191]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02388334141075,40.633724386739026],[-74.02423774621609,40.63285893136]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0209540417791,40.638321007931715],[-74.02090750080546,40.63826920034826],[-74.02087234589322,40.63823014026672],[-74.02069841155868,40.63804480529844],[-74.02037998679783,40.63772499451369]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03278399911363,40.61048532955953],[-74.03303373647016,40.61039886135503],[-74.03359214154472,40.61021636717529],[-74.0345020808211,40.609918978456534],[-74.03489726686202,40.60979182728423]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0331351948914,40.611444473576626],[-74.03255834142894,40.61115589103476]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01894932186951,40.64021823525207],[-74.01676837217506,40.63889900814065]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01273688241048,40.61058825791962],[-74.01375776363825,40.609606725229426],[-74.01448201327624,40.60891037993433]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03642637951485,40.63193208913182],[-74.03672590071159,40.63120193382939]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01698622944993,40.60421699545783],[-74.01762387638252,40.60360675051379]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02132832742268,40.638916299282236],[-74.02082094366662,40.63861280019888]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01735110147658,40.63834114939077],[-74.01793123201446,40.637780982698075]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02052608694426,40.61805784397155],[-74.01984163966091,40.61764397475195]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03819614582365,40.62759933171589],[-74.03841532458546,40.627111346473754]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03163907988211,40.62204849142787],[-74.03115155423009,40.621932844259426],[-74.03006728396737,40.621675620451484],[-74.02892312153189,40.62140418198831]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02649401933346,40.62877474889372],[-74.02650798726242,40.628738022556114],[-74.02653176700701,40.628675584168214],[-74.02657400392089,40.628570807857066],[-74.02662631418204,40.62844597484385],[-74.0266328966032,40.62844367700396],[-74.02665265696498,40.62843875545878],[-74.02667244169076,40.62843483354805],[-74.02673835101622,40.62844604768481],[-74.02682460656597,40.628466208429764],[-74.026851025353,40.62847249715218],[-74.02692588522022,40.628490985027824],[-74.02693492951686,40.628495359763036],[-74.02694536758261,40.62850062508828],[-74.0269535958044,40.628504242951266],[-74.02706839747316,40.628531195632945],[-74.02716565800387,40.62855400986479],[-74.02725526122136,40.628583012663036],[-74.02726209518588,40.628587720608344],[-74.02727233834958,40.62860613393395],[-74.02727400633279,40.62860974461842],[-74.02727425533074,40.62861211274442],[-74.02727453311546,40.62862734957716],[-74.02727455888704,40.628632302220645],[-74.0272742533998,40.62863590466177],[-74.02726016798646,40.628673000521495],[-74.02723792317964,40.62873087303825],[-74.02719495530005,40.62883749576283],[-74.02716871505984,40.62889375758453],[-74.0271512137077,40.62893110620009]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03295871707287,40.6188173952282],[-74.03048497536487,40.61758254562128]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0345526559422,40.60894070568894],[-74.03442443016968,40.60873764959216]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03426005919847,40.617858626493046],[-74.0342380049627,40.61785341906344],[-74.03417648648397,40.61783886738566]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02263792255441,40.62948628108033],[-74.02027718520742,40.62806209037222]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02574552356688,40.63646534460275],[-74.02603960456793,40.635741189299864]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0250906838976,40.63779457402449],[-74.02527185543377,40.637608532159696]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02874956791189,40.61286536177699],[-74.02892473285023,40.612477702955296]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02145207558851,40.618027191687425],[-74.02160848456943,40.61753673829377]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02803565519747,40.623571774056906],[-74.02835031608427,40.62279862692517]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02893798474447,40.60596168694237],[-74.02890396082984,40.6059456373421],[-74.0288696467194,40.60592995117513],[-74.02883504812914,40.60591463128777],[-74.02880017319323,40.60589968136335],[-74.02876502696793,40.60588510374577],[-74.0287296171476,40.60587090178345],[-74.02869395120645,40.6058570779872],[-74.02865803486007,40.60584363470079],[-74.02862187646224,40.605830575272456],[-74.028585482168,40.60581790171082],[-74.02854885901198,40.60580561686187],[-74.02851201490755,40.60579372239875],[-74.02847495557056,40.60578222150286],[-74.02843769045309,40.605771116014495],[-74.02840022439125,40.60576040794259],[-74.02836256639779,40.6057500999652],[-74.02832472328657,40.60574019291812],[-74.02828670275191,40.60573069048488],[-74.02824851072802,40.60572159266386],[-74.02821015688733,40.6057129028031],[-74.02817164694439,40.6057046212361],[-74.02813298947237,40.60569675097612],[-74.02809419106502,40.60568929235648],[-74.02805526029506,40.60568224721773],[-74.02801620441612,40.60567561706575],[-74.0279770306817,40.605669403071346],[-74.02763957507892,40.60564367871165],[-74.0267697212559,40.60569808176101],[-74.02590903856417,40.60575050316976]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02062866059715,40.64217589850549],[-74.02056295535992,40.64214110540959]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04062974587427,40.63006448985859],[-74.04073001627454,40.62975035493216],[-74.04076415156034,40.62964341298614],[-74.04087518819219,40.629203352529146],[-74.04097232139833,40.62872079219713],[-74.04103037440473,40.62834487368898],[-74.04104805479027,40.62823038716361],[-74.04121257729417,40.62692505604596],[-74.04122030643944,40.62686373308173],[-74.04123252983878,40.62671938949113],[-74.04130148999633,40.62590507320313],[-74.04132160558905,40.62550307713368],[-74.04135085050727,40.62491864416779],[-74.04135364022913,40.62486289161301],[-74.04137014707496,40.624532854234786],[-74.04136031405449,40.62419554703034],[-74.04135696908462,40.624080802268196],[-74.04131547799192,40.622657400886],[-74.04130909544155,40.622438437545696],[-74.04121684097537,40.62144338654407],[-74.0411925813513,40.621235485473065],[-74.04111334568839,40.62055643802011]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03007316873776,40.63156241711636],[-74.0305688604995,40.63167998462207],[-74.03063851169657,40.63169649948075]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01343052343195,40.60941243132066],[-74.01371380260652,40.60958062410709],[-74.01375776363825,40.609606725229426]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02371677165152,40.61693704497811],[-74.02483452438825,40.61560252541747]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02094636322941,40.63665099654631],[-74.02093989532531,40.63664440313224],[-74.0209338566164,40.63663757677502],[-74.02092826184207,40.636630534727495],[-74.02092312442191,40.636623293237584],[-74.02091840497025,40.63661578379328],[-74.02091417696847,40.63660810572573],[-74.02091045119833,40.63660027896891],[-74.0209072362418,40.636592321279316],[-74.0209045400219,40.63658425309404],[-74.0209023684818,40.636576092672634],[-74.02090072800543,40.63656786145762],[-74.02089962145737,40.63655957837923],[-74.02089905236248,40.63655126404282],[-74.02089902160634,40.636542938049104],[-74.02089953007487,40.63653462117144],[-74.02090057513522,40.63652633334622],[-74.02090215569393,40.636518094844504],[-74.02090426735899,40.6365099259381],[-74.0209069044186,40.636501846061286],[-74.02091006116113,40.63649387515093],[-74.02091372945583,40.63648603264185],[-74.02091790073159,40.63647833646104],[-74.02092256509877,40.63647080721629],[-74.02092771002764,40.636463461830175],[-74.02093332496803,40.63645631839766],[-74.0209393945317,40.636449394846984],[-74.02094590442928,40.636442706760874],[-74.02095283905257,40.63643627173257],[-74.02096018213298,40.636430105177595],[-74.02096791454262,40.636424221004226],[-74.02097601891354,40.63641863513073],[-74.02098447413816,40.63641335962299],[-74.0209932604288,40.6364084080543],[-74.02100235667791,40.636403792490526],[-74.02100371492043,40.6363949469046],[-74.02100455394192,40.636386063552074],[-74.02100487022989,40.63637716102924],[-74.02100466356987,40.636368255921454],[-74.0210039350676,40.63635936732679],[-74.02100268560835,40.63635051233296],[-74.0210009180566,40.6363417083624],[-74.02099863549714,40.63633297384266],[-74.0209958425535,40.63632432552572],[-74.02099254516902,40.63631578100095],[-74.02098874928681,40.63630735735511],[-74.02098446348877,40.63629907117194],[-74.02097969569724,40.636290939705376],[-74.02097445581303,40.63628297803109],[-74.02096875329778,40.63627520306768],[-74.02096260069128,40.636267630225426],[-74.02095600987347,40.63626027441213],[-74.02094899404361,40.63625315020028],[-74.02094156750044,40.63624627199467],[-74.02093374476236,40.6362396535299],[-74.02090253836163,40.636212064747795],[-74.02087090193228,40.63618476150377],[-74.02083883965435,40.63615774882261],[-74.02080635548718,40.63613102971871],[-74.02077345405048,40.636104608881745],[-74.02074014040316,40.63607848949341],[-74.02070641916437,40.6360526747356],[-74.02067229517371,40.636027169800485],[-74.02063777370965,40.636001976697074],[-74.0206028593917,40.635977100282524],[-74.02056755705877,40.635952543571136],[-74.02053187198965,40.635928310079684],[-74.02049580880328,40.635904402822554],[-74.02045937321847,40.63588082615407],[-74.02042257095371,40.63585758325592],[-74.02038540552823,40.63583467697513],[-74.02034788375995,40.635812110493156],[-74.0203100111476,40.63578988766187],[-74.02021970090256,40.635732702807026]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01630548309925,40.63589567369046],[-74.01410877859782,40.63456399731041]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03037602705967,40.63811791807008],[-74.03039309135316,40.638080020125585],[-74.03039970440551,40.63806543854096],[-74.03043634516078,40.63800249208192],[-74.03045022469801,40.63797981309159],[-74.03061657555746,40.63770363405622],[-74.03063817788815,40.637663600049606]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0177243336457,40.63091050440686],[-74.01812288900891,40.6304716553551]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01819043845173,40.60340780002392],[-74.01798277109108,40.603343931583524],[-74.01764832917624,40.60324911237529],[-74.01614320899506,40.60282237068131],[-74.0159718463255,40.60277637756482]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01849303797555,40.64087580502753],[-74.01908019765466,40.6402972882069]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02546066272338,40.60707666304845],[-74.02567519686234,40.60645386551876]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03232748540657,40.620361849913515],[-74.02984260202672,40.61915381635932]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03053725893822,40.60988983056623],[-74.02986842685246,40.609415116254716]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02363350473824,40.61853764777728],[-74.0227329117209,40.618088109472126]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03129416219217,40.617438136602395],[-74.03157114213704,40.61711440483184],[-74.03160330357393,40.61707681759593]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02199264617141,40.63980018579424],[-74.02261098612834,40.63970852832769]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01955318166169,40.63720134283111],[-74.01932871294058,40.63708062104839]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02461148114473,40.61406757079709],[-74.02474586967874,40.613922201234736],[-74.0247082132657,40.613551709929865],[-74.02469500573287,40.613345376781425]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01958196495558,40.62426700596428],[-74.01976701060362,40.624265965941355]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03307513983295,40.61525192091846],[-74.03337170662628,40.614904675292244]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03060631327827,40.63896332699042],[-74.03089089051595,40.63827883022866]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01582540206918,40.622573607188805],[-74.01640622335879,40.622014176886864]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03791790452361,40.62828155836065],[-74.03523521442837,40.62764527581542]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03871694221942,40.626215895713685],[-74.0360710950868,40.62559887321421]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03062372750874,40.62580375505145],[-74.03060695168685,40.62584458006587],[-74.03058832192302,40.625889881100285],[-74.03058699973919,40.625893087448894],[-74.03052500620498,40.62604320227248],[-74.03051937456314,40.6260567838117],[-74.0305096149794,40.62606175714614],[-74.03049993738762,40.62606668556034],[-74.0304304940063,40.62623500245653],[-74.03040178252792,40.626306601263686],[-74.03040038991428,40.62631017652679],[-74.0304011131555,40.62631611103966],[-74.0304033743123,40.62632321516625],[-74.03040507886237,40.626329140037946],[-74.03039127995667,40.62636860456834],[-74.03038584919949,40.62638212288913],[-74.03036755933805,40.62642125522118],[-74.03035422665486,40.62644551890747],[-74.0303335244575,40.6264831571797]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01965977575708,40.63974211959376],[-74.02026153192729,40.63918045222296]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02603899600105,40.63330237636062],[-74.02517770006332,40.63309649330162]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02195240648099,40.620900712256],[-74.02188450761754,40.62085685192503]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02110195466813,40.626039861248046],[-74.02116907601174,40.62607969661432],[-74.02143497299936,40.626237247286916],[-74.02147830877927,40.62622284881944],[-74.02153808977654,40.62625879549193],[-74.02140162281016,40.62639461068758]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03700355407041,40.62331909077572],[-74.0365454183737,40.623210265228664],[-74.03432262014285,40.622682209635734]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0235186645925,40.634615786682204],[-74.02101222340077,40.63346837978414]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02574989060072,40.61605822319546],[-74.0260701320273,40.61548666695231]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03163907988211,40.62204849142787],[-74.03191786785239,40.62136707146647]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02058200561427,40.622343014433035],[-74.02067901763246,40.622325950302134]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03672590071159,40.63120193382939],[-74.03693147508545,40.63069200317246]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0301167037708,40.61260522073694],[-74.03049069960784,40.612173353320536]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01690570806392,40.6353022348203],[-74.01697745739544,40.635235081662316]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02281427319133,40.616487579503314],[-74.02395966789459,40.615160771407304]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03622076800592,40.6179062668591],[-74.03580789073297,40.617807410616656],[-74.03487295373766,40.617583549634084],[-74.03477265794976,40.617559536107855],[-74.03457832908494,40.61751300193664],[-74.03441229625331,40.61747324841155],[-74.0342406488864,40.617432145868946],[-74.03358936495485,40.61727619660071]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02933540742167,40.613648819912726],[-74.02944823769612,40.6136828759931],[-74.02957293859639,40.61370361002533],[-74.02970532510125,40.61370818645283],[-74.0297445130617,40.61370429634929],[-74.02983984239242,40.613694832895035],[-74.02997015680205,40.61366334409767],[-74.03009019440083,40.613615197594754],[-74.03019493431248,40.61355333168675],[-74.03028117681734,40.61348162756302],[-74.0303056365445,40.61345353372053],[-74.03064831142137,40.61301360103152],[-74.0322115265826,40.61098246224904]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01346408967055,40.63077917421278],[-74.01365604549972,40.630898272623575]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03813109362966,40.61980248725406],[-74.03770067568371,40.61995529454051]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02390357684486,40.61920092432615],[-74.02415094724876,40.61887829956315],[-74.02419822513731,40.61881663834329],[-74.02435368108442,40.618613888262736],[-74.02465489484156,40.61823665952643],[-74.02514551842096,40.61766427439834],[-74.02515253115469,40.617656092765664],[-74.0254046647343,40.61736193724441],[-74.0258226983613,40.616874221209976],[-74.02617532761474,40.616462806831656],[-74.02628975684716,40.616329300249824]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0293562464355,40.63483669220852],[-74.02963292315899,40.63415292918439]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01875180734196,40.62431751087332],[-74.0187927156488,40.62422469662925]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02982641415649,40.63613858687818],[-74.03026763133677,40.635053967601436]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02078876240085,40.635945082445474],[-74.02015258203039,40.63556675262543]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0356098598006,40.61060276377649],[-74.0354591620899,40.610399143211886],[-74.03530530257292,40.610147090453644],[-74.03505731294625,40.6097408281576]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02172925531488,40.62067945213612],[-74.02119841399954,40.620356930495184],[-74.02059484724826,40.61999021361973]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02984260202672,40.61915381635932],[-74.03017406771407,40.61834033481151]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02229638917754,40.63032309233872],[-74.01982886126855,40.62916817814316]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02695244733698,40.63944606403955],[-74.02475437604834,40.63812141809163]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02773394483708,40.62430140322686],[-74.02799029442514,40.623682495139576]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03026763133677,40.635053967601436],[-74.02985778965343,40.63495626053565],[-74.0293562464355,40.63483669220852]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02835031608427,40.62279862692517],[-74.02864338068372,40.62208600871]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02740210088201,40.6405441851475],[-74.02745636342904,40.640570325068765],[-74.02789075151547,40.64077958065081],[-74.02800093377786,40.64082896219758],[-74.02837073189872,40.64099469622524],[-74.02838920082513,40.641002975948076],[-74.02889666840994,40.64121402130954]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0381111352122,40.63025895441205],[-74.03719749671605,40.63004157093969]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02233761319047,40.62113026188576],[-74.02244816627058,40.62097099251375],[-74.02280933117942,40.62049227692301],[-74.02309809440634,40.62008430155043]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03456924818023,40.63532453117172],[-74.03458595398257,40.63528488537767],[-74.03470959958923,40.634991630117185]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01606909467468,40.6292336382119],[-74.01664123839913,40.62868003431317]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02889666840994,40.64121402130954],[-74.02907910310942,40.64127405704605],[-74.02937876997252,40.64137266952767]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02179439170388,40.624354993982585],[-74.02151458743292,40.62418759518767],[-74.02062537093991,40.6236556048074]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02174534085233,40.617197877683054],[-74.02171650236905,40.617190409170036],[-74.02168749122204,40.61718334007113],[-74.02165831576605,40.6171766735677],[-74.02162898721332,40.61717041116525],[-74.02159951391836,40.61716455537504],[-74.02156990621414,40.61715910820536],[-74.02154017377401,40.61715407149711],[-74.02151032627101,40.617149446086046],[-74.02148037381842,40.61714523465062],[-74.02145032564945,40.61714143769165],[-74.02142019253657,40.61713805671479],[-74.02138998327351,40.61713509305857],[-74.02135970863235,40.61713254705599],[-74.02132937850622,40.617130420547966],[-74.02129900256784,40.6171287135327],[-74.02126859136958,40.617127426845805],[-74.02123815370477,40.61712656065318],[-74.02120770100512,40.61712611562282],[-74.02117724272343,40.617126091585426],[-74.0211467889721,40.61712648870664],[-74.0211163496436,40.61712730664964],[-74.02108593485043,40.61712854574759],[-74.02105555426476,40.61713020432349],[-74.02102521843891,40.617132283213074],[-74.0209949366055,40.61713478107444],[-74.02096471975607,40.617137697067996],[-74.02093457734318,40.61714103035443],[-74.02090451859952,40.6171447797594],[-74.02087455517606,40.61714894410818],[-74.02084469476662,40.617153522394254],[-74.02081494836224,40.61715851227032],[-74.02078532585531,40.617163912897034],[-74.02075583691781,40.6171697217598],[-74.02072649122222,40.61717593801933],[-74.02069729866008,40.617182558155854],[-74.02066826802456,40.61718958133026],[-74.02063940920738,40.617197004525394],[-74.0206107327601,40.617204825729125],[-74.02058224637592,40.61721304158963],[-74.02055396060662,40.617221650597415],[-74.02052588380468,40.61723064856291],[-74.02049802674165,40.617240033641515],[-74.02047039755041,40.61724980231388],[-74.02044300546322,40.61725995139543],[-74.0204158590526,40.61727047703166],[-74.02038896777091,40.61728137687567],[-74.02036234106988,40.61729264623516],[-74.0203359866428,40.61730428175834],[-74.02030991350212,40.61731627992573],[-74.02028413066004,40.61732863671524],[-74.0202586460296,40.61734134793746],[-74.0202334679635,40.61735440940286],[-74.02020860525404,40.61736781658682],[-74.02018406625413,40.61738156563492],[-74.02015985777723,40.61739565118527],[-74.02013598905565,40.61741006938327],[-74.0201124673427,40.61742481520201],[-74.02008930099105,40.61743988378189],[-74.02006649703429,40.61745527026356],[-74.02004406294542,40.617470968782456],[-74.0200220061982,40.617486975986864],[-74.0200003349249,40.61750328483941],[-74.01997905506,40.61751989064844],[-74.01995817363705,40.617536788052064],[-74.01993769834904,40.617553971185615],[-74.01991763557007,40.61757143485485],[-74.01989799189383,40.61758917286025],[-74.01987877413394,40.61760717933733],[-74.01985998778507,40.6176254485894],[-74.01984163966091,40.61764397475195]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0253636256148,40.62097721203771],[-74.02576515663598,40.62051080618509],[-74.02592048236816,40.62033037910587],[-74.02601178265576,40.6202243316834],[-74.02631533164195,40.61987174446624]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02030348107586,40.62486681640621],[-74.02126272965195,40.62544565037397],[-74.02132956679132,40.62548597220487]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03669183967781,40.638347149432676],[-74.03694495703624,40.63779328889155],[-74.03696341062336,40.63775290943134],[-74.03727650792912,40.63712314762692],[-74.03761096301204,40.63646334560569],[-74.03775829382731,40.63617269179115],[-74.0379453477792,40.63580366823164],[-74.03828902961355,40.635136108207774],[-74.03852075260697,40.63468600523709],[-74.03894982702717,40.63381202400962],[-74.03895356071465,40.633804061787174],[-74.0395811493761,40.63246582012923],[-74.039582298594,40.63246328033519],[-74.03991999248666,40.63171698516563],[-74.04019216345789,40.63111548172229],[-74.04033329853598,40.6308035645351],[-74.04045158125615,40.63054215151822],[-74.04062974587427,40.63006448985859]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02457354910433,40.639923934992396],[-74.0235493915473,40.639320333692275]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03024374702804,40.63626442413395],[-74.03025688767835,40.63622884164031],[-74.03026713602631,40.63620191308946],[-74.03026820979761,40.63619889628829],[-74.03029294673263,40.636137213311805],[-74.03042795274739,40.63582644408493],[-74.03062672099055,40.635314770740024],[-74.0306364974109,40.635290372965265],[-74.03065984053758,40.63523294968798],[-74.03066498854426,40.63522048519717],[-74.03066878123428,40.635216089912134],[-74.03067657253263,40.63519505110775],[-74.03069231017044,40.63515254274001]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03583589818798,40.633369846041106],[-74.03612991330351,40.632663269752406]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03571148771276,40.619274919844784],[-74.03303206493426,40.6186409349872]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0264643503655,40.63991829269074],[-74.0265998440278,40.63978656061281]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0367255304667,40.623999477990225],[-74.03452815336368,40.623478217269614],[-74.03404330705281,40.6233631942251]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03728969733213,40.61930655864202],[-74.03697139559839,40.61879529176123]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03574203342504,40.615075989423545],[-74.03554966032256,40.61476009258852],[-74.03534760179224,40.614428276285686]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03089089051595,40.63827883022866],[-74.03112359850026,40.63771059377705],[-74.03126827705228,40.63735730812885]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03728235187485,40.62263792793432],[-74.0378401315405,40.62127474544687]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.032637494089,40.609432094762205],[-74.03309259256531,40.60931495065947],[-74.03320700519672,40.609332198947484]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01542409868877,40.63251313909726],[-74.01574804402502,40.63176426870878]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04049062428071,40.630040557714736],[-74.04049404628276,40.63003017911558],[-74.0404969248787,40.63001970504885],[-74.04049925590093,40.6300091521014],[-74.04050103496195,40.62999853686014],[-74.04050225987343,40.62998787624626],[-74.04050292778732,40.62997718718118],[-74.04050303871364,40.62996648574763],[-74.04050259200399,40.629955790038984],[-74.04050158898791,40.629945116472506],[-74.04050002989524,40.629934480963385],[-74.04049791803557,40.6299239016035],[-74.04049525649691,40.629913393804365],[-74.04049205034778,40.629902975322196],[-74.04048830311598,40.62989266156832],[-74.04048402184856,40.629882469628186],[-74.040479212712,40.62987241491212],[-74.04047388341235,40.62986251350014],[-74.04046804275512,40.62985278147184],[-74.04046169976489,40.62984323356645],[-74.04045486412618,40.62983388502558],[-74.04044754750225,40.62982475075513],[-74.04043975957659,40.62981584432139],[-74.04043151443142,40.62980718096444],[-74.04042282460851,40.62979877391452],[-74.04041370286897,40.629790635564184],[-74.04040416483349,40.62978277998021],[-74.04039422546191,40.62977521938687],[-74.04038389949336,40.62976796466821],[-74.04037320408658,40.629761028047746],[-74.04036215508026,40.62975442074416],[-74.04035077051101,40.62974815230022],[-74.04033906907596,40.62974223376612],[-74.04032706815104,40.62973667317704],[-74.04031478643236,40.629731479907974],[-74.04030224481426,40.62972666232791],[-74.04028946133198,40.629722227969246],[-74.04027645775824,40.62971818335787],[-74.04026325234766,40.62971453518849],[-74.04024986885165,40.62971128948373],[-74.04023632552374,40.629708451263014],[-74.04022264545453,40.62970602470642],[-74.04020884953552,40.62970401365975],[-74.04019496041677,40.62970242113055],[-74.04018099876967,40.6297012506297],[-74.04016698680293,40.629700502484425],[-74.0401529478258,40.629700179031985],[-74.0401389025078,40.62970028060023],[-74.04012487349664,40.62970080634359]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02693578540799,40.640281605031376],[-74.02703439376457,40.64034998576443],[-74.02740210088201,40.6405441851475]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02986842685246,40.609415116254716],[-74.02941591965345,40.609079715771784],[-74.02846265641435,40.60836448096973]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02774843865195,40.63730274856897],[-74.02776706435756,40.63726288703278],[-74.02801315700769,40.636733952423334]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0207219318318,40.634169009418805],[-74.01926351278594,40.6334934144416]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03017406771407,40.61834033481151],[-74.03048497536487,40.61758254562128]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01884666051637,40.604372398075654],[-74.01889050112962,40.604362475502775],[-74.01893450186734,40.60435297405486],[-74.01897865679611,40.60434389574306],[-74.0190229573448,40.60433524224389],[-74.01906739757966,40.6043270142283],[-74.01911197068797,40.60431921320503],[-74.01915666853827,40.604311841018074],[-74.01920148519679,40.60430489800338],[-74.01939321452502,40.604277390373746],[-74.01958814946977,40.60426160774012],[-74.01978444539016,40.604257818617796],[-74.0199801903243,40.60426606957033],[-74.02046197579955,40.6043330825425],[-74.02117927174122,40.60442612087531]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02870035802583,40.615629982832466],[-74.02940204798927,40.614813834424275]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02012056882756,40.6390869490181],[-74.01793123201446,40.637780982698075]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01793123201446,40.637780982698075],[-74.01852040600959,40.63721694821191]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01952692715224,40.63966502201572],[-74.02012056882756,40.6390869490181]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01722288166013,40.62810068935286],[-74.01784193368066,40.62659069387398]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02838003879215,40.63002274319229],[-74.02867799741152,40.62929432896287]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0409486735115,40.62985345229276],[-74.04092217165284,40.62995465505887],[-74.04087635200995,40.630111937360105]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01374808840534,40.617676594817674],[-74.01432761381442,40.61711734341869]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03089089051595,40.63827883022866],[-74.03051946198278,40.63816274421844],[-74.03037602705967,40.63811791807008],[-74.03016550866239,40.63805212775785]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02082094366662,40.63861280019888],[-74.02077210038948,40.63858326304127],[-74.02071502826158,40.63854872042211]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03516783510013,40.63621825006255],[-74.03518518661228,40.63617061606025],[-74.03519038028766,40.63615614335704],[-74.0354258600122,40.63557059854461],[-74.03544163164408,40.635531376259586]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02572377067443,40.64063051860539],[-74.02466370948821,40.63998338594343]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01861253218762,40.629859539121846],[-74.01915507960413,40.62927594024435]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01812288900891,40.6304716553551],[-74.01755939514045,40.63013156236207]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02736880517995,40.61323451610855],[-74.02754297260526,40.61293718320398]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0252532717485,40.61667845738943],[-74.02574989060072,40.61605822319546]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0343111306135,40.63592134662414],[-74.03433215141324,40.635881006181414],[-74.03443962123552,40.635619634058884],[-74.03451010010937,40.63544380496571],[-74.03451559177799,40.63541176281469],[-74.03451688832364,40.63540363075786],[-74.03452591779343,40.63535574738586],[-74.03453322629281,40.635316005076504]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0176043718909,40.63583349929484],[-74.01750950259756,40.63576806323548],[-74.01741200863245,40.63570081651156],[-74.01735959970891,40.635664679989624],[-74.01712675950323,40.635487646470565],[-74.01690570806392,40.6353022348203]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02207654556122,40.620974567338685],[-74.02195240648099,40.620900712256]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02058200561427,40.622343014433035],[-74.0197324360998,40.6230505125194],[-74.01939786605321,40.62333671894418],[-74.0193030040956,40.62343821477705],[-74.019219205445,40.623545219706976],[-74.01914727388831,40.62365667065426],[-74.0187927156488,40.62422469662925]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01492199644913,40.63164871613504],[-74.01525214029859,40.63184690370239]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0345526559422,40.60894070568894],[-74.0345190607045,40.609073101722224],[-74.03452375870906,40.60913856142955],[-74.03483935692643,40.609682730039026]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03994353520412,40.63022549915752],[-74.039956318883,40.63020846995319],[-74.03996866728141,40.630191254774395],[-74.03998057380679,40.63017386015721],[-74.03999203560453,40.6301562923013],[-74.04000304762192,40.630138558747355],[-74.04001360502542,40.63012066569574],[-74.04002370540032,40.63010261951353],[-74.04003334325411,40.630084427573976],[-74.04004251617253,40.63006609691426],[-74.0400512206412,40.630047633399236],[-74.0400594524874,40.63002904507181],[-74.04006720995616,40.630010338298796],[-74.04007448843448,40.629991520285635],[-74.04008128682753,40.62997259806898],[-74.0400876009624,40.62995357935671],[-74.04009343018355,40.62993447034768],[-74.04009877141773,40.62991527908441],[-74.04010362203073,40.62989601226905],[-74.04010798114761,40.629876676938146],[-74.04011184745448,40.62985728146865],[-74.04011521787727,40.62983783239532],[-74.0401180926405,40.62981833675428],[-74.0401204702101,40.629798802420005],[-74.04012234905184,40.62977923693183],[-74.04012372938996,40.62975964682329],[-74.04012461035039,40.62974004047117],[-74.04012499193749,40.62972042440909],[-74.04012487349664,40.62970080634359]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01616711475104,40.63948244106678],[-74.01396088612057,40.63815326741945]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01634322391006,40.630285595428546],[-74.01664336539812,40.62957607819243]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02692778872888,40.62421392022086],[-74.02715062715649,40.62400195786662],[-74.02718447464305,40.623969765084865]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03251940529113,40.61753669198706],[-74.03249031503353,40.61757074877668],[-74.03243840636661,40.61763135962702],[-74.03221612537475,40.617890897853336]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02641115145863,40.612906609942215],[-74.02658967920925,40.61259728926806],[-74.02637609057152,40.61245060340205],[-74.02710660556804,40.61024395632412]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02527185543377,40.637608532159696],[-74.02547192644472,40.63714013731289]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03295222200916,40.61028113349408],[-74.03317581379854,40.6100053293751],[-74.03356597892842,40.60966373891987],[-74.03395268214933,40.60938802976432],[-74.03406151167499,40.609295877224575],[-74.0341111716406,40.60924881734018]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03182554447379,40.635992562975595],[-74.03203646331005,40.6354752371198]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03446423136421,40.60851882869996],[-74.03446267246318,40.60842908320731],[-74.03446245646002,40.60837600656363],[-74.0344622102959,40.608310917093426],[-74.03444666769484,40.6082343775794],[-74.03441186761312,40.6081374468374],[-74.0343130451752,40.60794163077413],[-74.03421683727224,40.607797945356914],[-74.03407921475016,40.60765089475918],[-74.0339186094809,40.6075014557844],[-74.03322531181975,40.60694247922794],[-74.03278860673888,40.60661003320143],[-74.03251659324702,40.606402945240845],[-74.03214344715784,40.6062344994004]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02846265641435,40.60836448096973],[-74.0269393000037,40.608110048216886]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02614804195028,40.61454606733913],[-74.02610077000423,40.61462689084058],[-74.02600367490814,40.61479288774544]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02750722453025,40.63215460208875],[-74.02479160206568,40.631505711163186]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0323165198636,40.63479116049515],[-74.02963292315899,40.63415292918439]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01620695995756,40.63322998887184],[-74.01620299731249,40.63312202648287],[-74.01621596169294,40.6328196389354]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02614804195028,40.61454606733913],[-74.02622173088905,40.6145710577595],[-74.02631522758638,40.61460277072263],[-74.02638752268349,40.61462728423337],[-74.02639734332605,40.61463062300736],[-74.02647038251838,40.614655388426044],[-74.02651463147971,40.61467032683149]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02336300700999,40.64014077126573],[-74.02338006681678,40.64013622626988],[-74.02365700473027,40.64006243818422],[-74.023958254087,40.639999879663506],[-74.02426453314892,40.63995361863706],[-74.02457354910433,40.639923934992396]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02724257527268,40.60969437183326],[-74.02740487240644,40.6100459507822]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02611847949083,40.61772764118226],[-74.02595909442329,40.61790573682438],[-74.02594488607367,40.617958015229156],[-74.02592061221426,40.61798627008839],[-74.02589056196321,40.61802124431752]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02080897981277,40.64133958160862],[-74.0208307350269,40.64131226484145],[-74.02086583167788,40.64126820520507],[-74.02090092828253,40.641224145557764]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01994399944483,40.62427494975972],[-74.02007423343322,40.62424643447731]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01612995805846,40.633264021233344],[-74.01620695995756,40.63322998887184]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02045920302128,40.64208105643792],[-74.02042111588045,40.642057327448136],[-74.02039290347214,40.642038985078656]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03303206493426,40.6186409349872],[-74.03331256633761,40.61794500424376]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01594826967052,40.6362527513458],[-74.01606790798363,40.63613845059219]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02094636322941,40.63665099654631],[-74.02024573669517,40.63640957692435]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01907578304655,40.62361467353489],[-74.01938702927659,40.622891818697134]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02385329376379,40.626514473407404],[-74.02290426743478,40.62593885602657],[-74.02149466602913,40.625083859316064]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0190540606447,40.63669904500444],[-74.01898634254977,40.63665861448975],[-74.01805283070652,40.636101252910606],[-74.0176043718909,40.63583349929484]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03177291967661,40.63316482142147],[-74.03019093198031,40.63279069500373]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0229220192707,40.619983964591476],[-74.02301088257899,40.61987987157839],[-74.02318505145092,40.61967585283674]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02722013300452,40.6203223521233],[-74.02631533164195,40.61987174446624]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03493758410197,40.62837499488119],[-74.03523521442837,40.62764527581542]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01970390025541,40.63608035103739],[-74.01750512326755,40.63474754258663]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03240982901937,40.64143059587199],[-74.03155426156417,40.64155202605774],[-74.0313400806407,40.64156640244505],[-74.0311248554375,40.641571882454286],[-74.03090957877178,40.641568418904846],[-74.03072182085549,40.64155984234279]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0357344518362,40.60938952460263],[-74.03599609905362,40.609309069918936]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01573946898866,40.63645223721393],[-74.01594826967052,40.6362527513458]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02574552356688,40.63646534460275],[-74.02323533366493,40.635318753152525]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03384761143502,40.60897712536054],[-74.03391660521358,40.60891417844936]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01316381314865,40.61823617216211],[-74.01374808840534,40.617676594817674]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04087635200995,40.630111937360105],[-74.04074587689504,40.63008610569161]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02949037963523,40.64132096933019],[-74.03001271830603,40.64143925249498],[-74.0303592813187,40.641498188152475],[-74.03055063942224,40.64153072962585],[-74.03072182085549,40.64155984234279]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03692682926332,40.633639278486434],[-74.03697082562302,40.633569829451545],[-74.03701530863195,40.63350056033585],[-74.03706027565099,40.63343147264734],[-74.03710572712035,40.63336256923332],[-74.03715165974108,40.63329385126702],[-74.03719807373349,40.6332253214282],[-74.0372449668984,40.63315698139231],[-74.03729233857617,40.633088833169325],[-74.0373401874471,40.63302087809929],[-74.03738851087313,40.632953119365524],[-74.03743730929342,40.63288555763744],[-74.0374865798497,40.63281819542824],[-74.0375363223221,40.632751034580245],[-74.03758653385209,40.63268407710412],[-74.03763721443951,40.63261732433948],[-74.03768836122615,40.63255077879957],[-74.03773997421241,40.632484442829174],[-74.03779205141898,40.632418317601015],[-74.03784459108655,40.632352404455276],[-74.0378975918966,40.632286706407285]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03502977105705,40.61134142345187],[-74.03520503309636,40.61134300850667],[-74.03538188754395,40.611360289262535],[-74.03555667080771,40.61139356370671],[-74.03572568420066,40.61144246359685],[-74.03588540629288,40.611505981700844],[-74.03603273933976,40.61158249835313],[-74.03616522612148,40.61166996013419],[-74.03753246672564,40.61257229411841],[-74.03788517257021,40.61274113419476]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03457883421241,40.61485994998373],[-74.03470051608272,40.61465860187504]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01690570806392,40.6353022348203],[-74.01675094045274,40.6351508621058],[-74.01669425526964,40.63508183669996],[-74.01660342120816,40.63497122121206],[-74.01659111132112,40.634953545377925],[-74.01646828710105,40.63477707054868],[-74.01638865259227,40.63463734586922],[-74.01636457541497,40.63459509927047],[-74.01635252561574,40.63457394799348],[-74.0162575785086,40.63436356420204],[-74.01618453437295,40.63414780996693],[-74.01613406683865,40.63392868485579],[-74.01610642489518,40.6337082415906],[-74.01610144300595,40.63348852472946],[-74.01612995805846,40.633264021233344]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03592460933342,40.61705482737083],[-74.03568169740524,40.616670587452134]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03274647058772,40.607738290570644],[-74.03193573384303,40.60824384651627],[-74.03188507062245,40.608374463517414],[-74.0321580508527,40.60874549520581]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02892473285023,40.612477702955296],[-74.028470603017,40.61302349341556],[-74.02819944771919,40.6133299237523],[-74.02810683365068,40.61342818422232],[-74.02802238079984,40.61351779763258],[-74.02765323668177,40.61389370146431],[-74.02740545646232,40.61414447519106],[-74.02624732375942,40.61510478138763]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03185652853652,40.611951954590694],[-74.03255834142894,40.61115589103476]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03275211855042,40.61932301589863],[-74.03295871707287,40.6188173952282]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0264643503655,40.63991829269074],[-74.02693578540799,40.640281605031376]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02323533366493,40.635318753152525],[-74.0235186645925,40.634615786682204]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03287451463889,40.633429345431814],[-74.03204523327672,40.63323278037718]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02363350473824,40.61853764777728],[-74.02387367125517,40.6182593190232],[-74.02462461252911,40.617389023513944]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03130872447673,40.61043915726491],[-74.0326345256723,40.60986210331438]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03836395479941,40.616513393337435],[-74.03607763349201,40.61731632634254]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02365861581545,40.625935299253385],[-74.02319919643975,40.625658464915894]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02770568281922,40.639894406609905],[-74.02789633368653,40.63971071733652],[-74.02853941735353,40.63909112941787]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02603960456793,40.635741189299864],[-74.02637946189289,40.63486579752866]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01570811714437,40.626295049370796],[-74.01648765885447,40.62577531294818]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03959634008382,40.630612300796386],[-74.0381111352122,40.63025895441205]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03160913630951,40.6385021796791],[-74.0312528387201,40.638391387119846],[-74.03089089051595,40.63827883022866]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01591473467845,40.633365549075094],[-74.01594446428582,40.633125952470216],[-74.01596849784532,40.63293226148167],[-74.01597999814854,40.63283958274269],[-74.01602971932462,40.63266226357815],[-74.01606565745686,40.63253413237114],[-74.01616292303547,40.63223058090648],[-74.01617167565121,40.632206335441616],[-74.01627168993382,40.63192929689714],[-74.01639180285433,40.631630658444905],[-74.01642190824099,40.631542275778465],[-74.01649678385768,40.63132245865935],[-74.01680939238204,40.630499032721445]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03192153893677,40.61083035531361],[-74.03187955888912,40.610803136471155]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03196319975913,40.63861189086066],[-74.03198447061679,40.638571433352645],[-74.03200301342711,40.638536137482085],[-74.03218301068239,40.63820728043693],[-74.0321915145061,40.638191969303726],[-74.03220618283169,40.638187652008014],[-74.03246079103282,40.63826791534966],[-74.0331077258843,40.63847191445089],[-74.03318178614253,40.63849533368865]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03594936471876,40.639870278220954],[-74.03604151078017,40.63973437910729],[-74.03616971853175,40.639523527738476],[-74.03634762428824,40.639142574900525],[-74.03642076105058,40.63898596440511]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03366364805419,40.608484549127326],[-74.03365735704068,40.608404710832424],[-74.03362333098904,40.60824773287355],[-74.03356892467026,40.60809587585215],[-74.03349578286559,40.60795130021703],[-74.0333146202217,40.607710976872916],[-74.03224740002382,40.60662305774588],[-74.03188910319959,40.60622953633805]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01852944048841,40.632333576625285],[-74.01697095893735,40.63161800324111]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01752337759615,40.62904448813247],[-74.01744831964588,40.62902947021814],[-74.01734316726642,40.629010403777855]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01343052343195,40.60941243132066],[-74.01325956469594,40.609572293753075]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01616711475104,40.63948244106678],[-74.01676837217506,40.63889900814065]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02135412676695,40.63985986082788],[-74.02026153192729,40.63918045222296]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0295728483016,40.627103552092244],[-74.02893158849291,40.62695152766981],[-74.02859230686455,40.626871088041824],[-74.02739102824535,40.6265862758387],[-74.02685720207243,40.62645774644725]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02718246490011,40.61601711616431],[-74.02719446613388,40.61588863610052],[-74.02722697078809,40.61576032205869],[-74.02727996693362,40.61563501129335],[-74.02735248743382,40.61551552200976],[-74.027442736703,40.61540439400269],[-74.02754822234633,40.61530375343453],[-74.02781869460865,40.615051641584],[-74.02796047409782,40.614903903827994],[-74.02808884885275,40.614748694534235],[-74.02820283868036,40.61458709555439],[-74.02830168812861,40.614420285515244],[-74.02838485437434,40.614249499277726]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02059484724826,40.61999021361973],[-74.01931290379294,40.61921695210262]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02387367125517,40.6182593190232],[-74.0238334138221,40.61823992117155],[-74.02300627492286,40.617840853050815],[-74.02296236568002,40.61781966373571]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01606909467468,40.6292336382119],[-74.01357203468916,40.62772787701898]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03642583101983,40.62473459544902],[-74.0367255304667,40.623999477990225]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02580960486513,40.60862312746623],[-74.02725974486593,40.60949388465354]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02637946189289,40.63486579752866],[-74.02538783405295,40.63441278316187],[-74.02388334141075,40.633724386739026]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0178857873427,40.64147118903415],[-74.01849303797555,40.64087580502753]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02176759944302,40.636933967688954],[-74.02094636322941,40.63665099654631]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02176759944302,40.636933967688954],[-74.02078876240085,40.635945082445474]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03339135330052,40.624966792257844],[-74.03070775574493,40.62432825728102]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01970122546571,40.62870221714901],[-74.01832782585751,40.62786195301802]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01793123201446,40.637780982698075],[-74.01573946898866,40.63645223721393]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01469487567537,40.606424283197335],[-74.01651620384442,40.60467228684249]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03543728497804,40.61995580764228],[-74.03571148771276,40.619274919844784]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02894215584342,40.63586681102552],[-74.02913396937063,40.63537274692008]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02247991392478,40.636950778659674],[-74.02078876240085,40.635945082445474]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02417094670037,40.63866937087833],[-74.02453841857515,40.63832493659562]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02773394483708,40.62430140322686],[-74.02718447464305,40.623969765084865],[-74.02534486402693,40.62285939371732]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03556528781051,40.6103342778818],[-74.03543262878762,40.61012994790489],[-74.03515733062534,40.60970591170685]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03076395882779,40.63139134328966],[-74.02808018363976,40.63075415598411]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03005683854005,40.64152123323449],[-74.03022139093981,40.6416087114773],[-74.03072789424091,40.64170616640797],[-74.03090790880503,40.64176581339929],[-74.03097490046422,40.6418102807025],[-74.03102852609189,40.64186523382672],[-74.03106513201047,40.64192690974907],[-74.03109111347194,40.64204811238257],[-74.0310824064596,40.642111817414865],[-74.03105262274676,40.64217799566528],[-74.03099944137865,40.64224055976065],[-74.03092473901326,40.642292504131134],[-74.03083497978052,40.64232802649829],[-74.03073956034721,40.64234449545991],[-74.03064775090701,40.64234299830408],[-74.0305662312065,40.64232727869679],[-74.03049830262174,40.64230206444115],[-74.0303782490625,40.64224574133679],[-74.03026593415332,40.64217924072981],[-74.03016350994709,40.64210357026419],[-74.03007282205004,40.64202008880905],[-74.02999525430292,40.6419303996129],[-74.02959936599987,40.6414297687984]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02190834592302,40.623088246991195],[-74.02158201968092,40.62289223842597],[-74.02134495628933,40.62312513927226],[-74.02131059901643,40.62315887906735]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02297009390854,40.63993460447853],[-74.0235493915473,40.639320333692275]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01717601656473,40.63154107766838],[-74.0177243336457,40.63091050440686]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04079235781758,40.624196572355466],[-74.03968659646677,40.623956628849086]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0346006153585,40.62200073904816],[-74.03488649961561,40.62131959788893]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03404330705281,40.6233631942251],[-74.03432262014285,40.622682209635734]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03732104650523,40.629741081858306],[-74.03762041959803,40.629012751665954]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02160848456943,40.61753673829377],[-74.02174534085249,40.61719787818563]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04032273625293,40.62258947065583],[-74.04031033692397,40.622560649166196],[-74.04029843486646,40.62253170570742],[-74.04028703360125,40.62250264614193],[-74.0402761326904,40.62247347449068],[-74.0402657363144,40.62244419678344],[-74.040255844695,40.62241481720847],[-74.04024646047341,40.622385341460934],[-74.04023758453137,40.622355774398976],[-74.04022921950956,40.62232612088015],[-74.04022136607033,40.6222963866003],[-74.04021402465568,40.622266576417694],[-74.04020719834558,40.62223669451959],[-74.04020088736337,40.62220674777471],[-74.04019509259004,40.62217673986841],[-74.0401898160074,40.62214667699865],[-74.04018505717787,40.62211656385648],[-74.04018081808266,40.62208640563466],[-74.0401770980646,40.62205620752685],[-74.04017389998447,40.62202597489305],[-74.04017122186579,40.62199571275982],[-74.04016906591002,40.62196542698995],[-74.04016743189912,40.62193512177179],[-74.04016632071516,40.621904802633495],[-74.04016573104157,40.62187447510395],[-74.04016566463976,40.62184414454351],[-74.04016612041254,40.621813815643335],[-74.04016709924207,40.621783494099105],[-74.04016860047108,40.62175318493691],[-74.04017062322254,40.621722893350416],[-74.04017316749885,40.62169262453297],[-74.0401762335225,40.62166238401295],[-74.04017982041616,40.62163217648139]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0252664790932,40.6202252087325],[-74.02492499314107,40.62005540036231],[-74.02483883579065,40.62001255425291]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03488649961561,40.62131959788893],[-74.03515779409116,40.6206379203186]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03446045665925,40.60860021023006],[-74.03446423136421,40.60851882869996]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02808018363976,40.63075415598411],[-74.02536097320035,40.630109349572315]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02292928976014,40.63062306606653],[-74.02289892610156,40.63066042597325],[-74.02276245172874,40.630828255763255]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03042727609291,40.625009935881906],[-74.03070775574493,40.62432825728102]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0319567238525,40.62847059683122],[-74.02927464974715,40.627832923455216]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03122817458835,40.6157229509399],[-74.03151434452992,40.61533019183227]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01490900364942,40.61655789281406],[-74.01270818900075,40.61522802485697]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02121548264651,40.61847198527922],[-74.02052608694426,40.61805784397155]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02479160206568,40.631505711163186],[-74.02508631102368,40.63083190581657]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02937876997252,40.64137266952767],[-74.0300453588338,40.64214901429326]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03555598232235,40.634062017580575],[-74.03561814665238,40.63390830663148],[-74.03583589818798,40.633369846041106]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0290459533386,40.61345829828121],[-74.02910308790344,40.61351350420968],[-74.02916866935722,40.61356331320007],[-74.02924131468855,40.613606654745]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04074587689504,40.63008610569161],[-74.04069220769941,40.6300741475738],[-74.04062974587427,40.63006448985859]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03561814665238,40.63390830663148],[-74.03569407997092,40.6339279057053],[-74.03570759264443,40.63393139565303],[-74.03601003209528,40.633999281409054],[-74.03601342422226,40.63399870388087],[-74.03601529173993,40.633998081932496],[-74.03602615214629,40.63399414361933],[-74.03603267627855,40.63399140399078],[-74.0360555539877,40.633979446504156],[-74.03606400249106,40.63397386967669],[-74.03606544254299,40.63397044762163],[-74.03612232085399,40.63383528849411],[-74.03614434932805,40.63378290778583]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03674766335625,40.61472051575813],[-74.03574203342504,40.615075989423545]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0147047735744,40.631140203018205],[-74.01466922668334,40.63117499437071],[-74.01463456639802,40.63120893036576],[-74.01461395668653,40.63122912269661],[-74.01447120201658,40.631369036515416],[-74.01443052562873,40.631408898189186],[-74.014426132665,40.63142656697656],[-74.01480609085517,40.63165924923419],[-74.01485390956934,40.63168851902332]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03515779409116,40.6206379203186],[-74.03543728497804,40.61995580764228]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02910595283603,40.62298388238133],[-74.02912887577975,40.622918147505764],[-74.02914825796645,40.62286451714065],[-74.02919722225359,40.62272911132346],[-74.02923251656325,40.62265822244351],[-74.02923720507053,40.622651422431524],[-74.02924226221639,40.62264846711065],[-74.02925158462064,40.62264321455514],[-74.02925967859956,40.62263888120679],[-74.02927505334377,40.62263639166844],[-74.02928520638008,40.62263862274352],[-74.02944071736562,40.622673693869366],[-74.02957592217712,40.622704294814845],[-74.03061293920263,40.622948370745966],[-74.03067678959866,40.622963968913794],[-74.03069819563542,40.62296938409533],[-74.03070277301403,40.622977947110506],[-74.03070302432937,40.62298417827548],[-74.03070344946393,40.62300932104519],[-74.03069293306564,40.62303951823109],[-74.03067708014578,40.623081874066706],[-74.03063578596252,40.623184562111206],[-74.03062415498901,40.62320706934739],[-74.03059368996529,40.6232660343445],[-74.03055563280209,40.62333927496836]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02446644099014,40.62043675220262],[-74.02365406373,40.61996084407536]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03442443016968,40.60873764959216],[-74.03444442075129,40.60866475508375],[-74.03446045665925,40.60860021023006]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03154600534789,40.63784088301529],[-74.03152150782769,40.637833324984335],[-74.0311968765757,40.637733194789526],[-74.03112359850026,40.63771059377705]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03255834142894,40.61115589103476],[-74.03232784000393,40.61104001817858]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01475993489775,40.603606460597604],[-74.01472943735155,40.60364558338786],[-74.01466803979943,40.603724314661754],[-74.01437672749468,40.60400304496696]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02233761319047,40.62113026188576],[-74.02222073204432,40.621060530577175]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0229098970756,40.63610746601653],[-74.02323533366493,40.635318753152525]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0323165198636,40.63479116049515],[-74.03259356920195,40.63410974953538]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03415742094354,40.63748330644836],[-74.03434972468874,40.637020679512915],[-74.03444160139642,40.636799673550165]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03003589653639,40.616295018413446],[-74.03006527060566,40.6162603764855],[-74.03009183366073,40.61622902236982],[-74.03010527459242,40.616213160399774],[-74.030118715518,40.61619729909827],[-74.03016331392267,40.61614467914949],[-74.03017407349962,40.616131987688654],[-74.03018084425257,40.61613004977997],[-74.03018917378692,40.6161278231443],[-74.03019537722787,40.61612514691647],[-74.03019789293201,40.616122301112725],[-74.03023986949539,40.61607384173206],[-74.03037872086395,40.615913233550074]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02067901763246,40.622325950302134],[-74.02083077035799,40.62215204094804],[-74.02104201559015,40.62186201738322]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02182969955204,40.641029145817654],[-74.02215916475346,40.64079942327392],[-74.02227765242675,40.64069060875752]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02635995559174,40.61825384993942],[-74.02592963837728,40.618040614408486],[-74.02589056196321,40.61802124431752],[-74.02552760871232,40.61784137421778]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02089938190545,40.61926265491913],[-74.02121548264651,40.61847198527922]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01937999454046,40.62426803983217],[-74.01946741815347,40.624267980164056],[-74.01958196495558,40.62426700596428]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02185196389816,40.63981609782905],[-74.02199264617141,40.63980018579424]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01727561504546,40.62899814917596],[-74.01707112858263,40.62947178921133],[-74.01684984100943,40.62994113689325],[-74.01663634217223,40.630422018181434]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01938702927659,40.622891818697134],[-74.01970491557115,40.62218496450551]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03130872447673,40.61043915726491],[-74.03053725893822,40.60988983056623]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02723085006429,40.62895005227942],[-74.02721480316279,40.62898873341787],[-74.02708668631239,40.62929765064224]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02663802521565,40.61594423821987],[-74.02680165899116,40.615736945853115],[-74.02691542180379,40.61558599183289],[-74.02699720456168,40.61548921148956],[-74.02714409130141,40.61531284587685]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01324489560523,40.63539747360349],[-74.01410877859782,40.63456399731041]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02000806065679,40.63725981629294],[-74.0198284563523,40.63715424347163],[-74.01968076242356,40.63706742257479],[-74.01954557800228,40.63698831739978],[-74.0190540606447,40.63669904500444]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02430437611244,40.60945696914183],[-74.02366134413828,40.60908130580522],[-74.02268180743687,40.60850903894092],[-74.02150602890865,40.6078220988329],[-74.02126136788524,40.607665957890184],[-74.02100250909825,40.607521912939404],[-74.02073103593654,40.607391026236115],[-74.02044870997526,40.607274234200325],[-74.02015744567528,40.60717226533558],[-74.01985927346104,40.60708564208159],[-74.01963955729555,40.60703494450821],[-74.01937373858235,40.60698941452398],[-74.01844010324004,40.60687815527406],[-74.01822355993605,40.60688651969022],[-74.01805461723691,40.60692115315858],[-74.01793034859467,40.60695324939452],[-74.01779807423925,40.60700521199258],[-74.01766981078768,40.607078561246716],[-74.0175716080024,40.607159551622345],[-74.01745336979855,40.60725580819146],[-74.01736202925487,40.607327215187006],[-74.01729504722098,40.60737957240774],[-74.01714759707542,40.60751302499603],[-74.01701910154738,40.60765441697114]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01999892578114,40.62145136823829],[-74.02030304230694,40.620705247605486]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03879672709583,40.63132927188658],[-74.03959634008382,40.630612300796386]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02800411516877,40.63814423931867],[-74.02673708899094,40.63765681974629],[-74.02582777972842,40.63730700527587]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02309809440634,40.62008430155043],[-74.02310454437561,40.62007613004211],[-74.02334639906894,40.61976973549253]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01560205035204,40.63351697794145],[-74.01591473467845,40.633365549075094]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03710325401208,40.63179810060745],[-74.03702870632438,40.63178015937463]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02173941742474,40.64092269441724],[-74.0218062696482,40.64088413514356],[-74.02218636940198,40.64066489889651],[-74.02224931714643,40.64062345360239],[-74.02243069905718,40.64052419060327],[-74.0225901676178,40.64043910503215]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0178698664736,40.63393364218166],[-74.01640635137058,40.63306292322013]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03361284109761,40.61721888062908],[-74.03106093000177,40.61596182358245]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0208806207955,40.641380436845324],[-74.02090112395791,40.641356656649705],[-74.02093762609574,40.64130895868899],[-74.02097412883828,40.64126125150225],[-74.02104702548262,40.6411726809843],[-74.02111716424196,40.641087461326656],[-74.02120080566738,40.64098583123523],[-74.02136556525572,40.64076415644252],[-74.02144582166734,40.64057963423182],[-74.02145914643818,40.64054815851417],[-74.02149092308588,40.640473085265945],[-74.0215424913974,40.64033576445143],[-74.02159530903636,40.64014932051991],[-74.0216112324179,40.64007555576033],[-74.02164447961336,40.639834687997556],[-74.02164304454377,40.63981817063281],[-74.02161466072258,40.6394914519345],[-74.02157349935707,40.63931083366617],[-74.02156795963609,40.639289951780505],[-74.02154902467775,40.63922439725644],[-74.02152000640866,40.6391239682063],[-74.02147653651916,40.63900597246773]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0139104241516,40.60601594921489],[-74.01609854581004,40.60392061821091]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03539473682623,40.6162052328757],[-74.03528582742767,40.61602520732421]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03405517325021,40.61430642982158],[-74.03395607481205,40.614256822332656],[-74.03379041752167,40.61417396025341]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0132887723416,40.61466918569875],[-74.01390656440218,40.61405236151451]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01746711446835,40.6049651038237],[-74.01764515125168,40.604842470486446],[-74.01783310206888,40.604728471457086],[-74.01793148581856,40.60467612710664]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03405517325021,40.61430642982158],[-74.03411120023314,40.61433439254727],[-74.03426093640246,40.61440970369088]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01294381978245,40.63568596469938],[-74.01310890671809,40.63552850051431]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01668903337765,40.63230494271675],[-74.01697095893735,40.63161800324111]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03918275293425,40.61785548724426],[-74.0368949794848,40.618662894987246]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03487149024217,40.611366235710996],[-74.03502977105705,40.61134142345187]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01469487567537,40.606424283197335],[-74.0139104241516,40.60601594921489]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02183419266981,40.63756450786067],[-74.02195278042983,40.637452235497214]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0286577676278,40.63654600852422],[-74.02788792587137,40.63630874892765]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02512022214226,40.64121007239311],[-74.0234477115474,40.640183699606446]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02645488791387,40.60800006267817],[-74.02580960486513,40.60862312746623]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02770568281922,40.639894406609905],[-74.02695244733698,40.63944606403955]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03940662450633,40.62463864368792],[-74.03968659646677,40.623956628849086]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02696785882371,40.63990452365057],[-74.02664251543516,40.63974743200312]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03595784256667,40.638821144636054],[-74.03485670659863,40.63847431543151]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01937999454046,40.62426803983217],[-74.01953703920228,40.62401601184536],[-74.01960259430805,40.62392411167892],[-74.01993044930566,40.62350492638515],[-74.02001365615298,40.62340289463249],[-74.02005167531112,40.62335627430744],[-74.02026852495783,40.623090384578084],[-74.02057045450238,40.62273505239102],[-74.02061664333775,40.62268069393568],[-74.0209317650028,40.62232401332878],[-74.02097461532125,40.62227607051391]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02535634457705,40.60735987918201],[-74.02546066272338,40.60707666304845]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03528582742767,40.61602520732421],[-74.0348936622186,40.615375700441724]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03493758410197,40.62837499488119],[-74.03225653845509,40.627740290327054]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01522261794682,40.63197103574545],[-74.01524035990636,40.63191944229604],[-74.01524291182453,40.63191185978132],[-74.0152450950784,40.63189894588557],[-74.01525214029859,40.63184690370239]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01516584854669,40.63213670271802],[-74.01519266633342,40.63207719268876],[-74.01522261794682,40.63197103574545]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03572584040815,40.613103033908445],[-74.0360945834937,40.61255854482404]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0274372501343,40.625027608911445],[-74.0250473472466,40.62358917746349]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02692778872888,40.62421392022086],[-74.02712055256137,40.624331653973464]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0268895184541,40.60606688189295],[-74.02688165221701,40.606111416973526],[-74.02687323070286,40.6061558922078],[-74.02686425368974,40.60620030508276],[-74.026854722713,40.60624465006948],[-74.02684463799025,40.60628892431975],[-74.02683400149698,40.60633312347724],[-74.02682281235137,40.606377243856336],[-74.02681107296823,40.606421280262914],[-74.02679878378508,40.606465230016255],[-74.0267859465574,40.60650908825744],[-74.0267725626017,40.60655285163538],[-74.02675863191524,40.60659651579411],[-74.02674415647375,40.60664007687987],[-74.02672913803319,40.606683531038826],[-74.02671357725049,40.606726874417454],[-74.02669747522198,40.60677010265953],[-74.02668083524254,40.606813212413506],[-74.02666365621023,40.60685619882101],[-74.0266459420796,40.60689905903294],[-74.02662769284805,40.60694178886081],[-74.02660891027149,40.60698438411573],[-74.02658959764504,40.60702684178114],[-74.02656975474596,40.60706915683102],[-74.02654938464954,40.607111326081245],[-74.02652848779312,40.60715334601337],[-74.02650706791077,40.60719521176793],[-74.0264851256601,40.6072369208315],[-74.02646266411575,40.60727846834476]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01734316726642,40.629010403777855],[-74.01741781391817,40.628772409342396],[-74.017460462067,40.62863643595272]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03697139559839,40.61879529176123],[-74.0368949794848,40.618662894987246]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0130231768454,40.6080304206257],[-74.01469487567537,40.606424283197335]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03126827705228,40.63735730812885],[-74.0286577676278,40.63654600852422]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03278399911363,40.61048532955953],[-74.03295222200916,40.61028113349408]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0234477115474,40.640183699606446],[-74.02368355347991,40.640122281083336],[-74.02387940654006,40.6400807965553],[-74.02392429287504,40.640071288530194],[-74.02416873598301,40.640031020368006],[-74.0244156303156,40.640001692280826],[-74.02466370948821,40.63998338594343]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02508631102368,40.63083190581657],[-74.02536097320035,40.630109349572315]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0282052488583,40.619172663284246],[-74.0287007460467,40.61859355146942]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03232784000393,40.61104001817858],[-74.03278399911363,40.61048532955953]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01711050334977,40.635641455823546],[-74.0167970520566,40.635530344183834],[-74.0166954641309,40.635521475108796]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01989460071066,40.618656476704864],[-74.02052608694426,40.61805784397155]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03214569081936,40.63685776473933],[-74.0318664500191,40.63677131147638],[-74.031547580922,40.63667258539087]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02199264617141,40.63980018579424],[-74.02199620318771,40.63968810673829],[-74.02198745361622,40.63957598496947],[-74.0219664819228,40.63946501779472],[-74.02192439742745,40.63928485919066]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0346006153585,40.62200073904816],[-74.0341747368717,40.62190015232564],[-74.03413853362338,40.62189159884346],[-74.03273636314306,40.62156040841758],[-74.03191786785239,40.62136707146647]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01606790798363,40.63613845059219],[-74.01630548309925,40.63589567369046]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02446644099014,40.62043675220262],[-74.02483883579065,40.62001255425291],[-74.02493937607184,40.61989803123739],[-74.02503214302747,40.619792361880165],[-74.02513068567308,40.6196801084748],[-74.02537316768615,40.61940388362679]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01698622944993,40.60421699545783],[-74.01609854581004,40.60392061821091]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02029670597527,40.64197377625254],[-74.02060464466344,40.64166077037703],[-74.02083006358566,40.641434834450365],[-74.0208806207955,40.641380436845324]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03762041959803,40.629012751665954],[-74.03493758410197,40.62837499488119]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03719039134116,40.631819063957124],[-74.03710325401208,40.63179810060745]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01367082889651,40.60918772283376],[-74.01343052343195,40.60941243132066]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0349464362437,40.61428853040123],[-74.03535192832503,40.61367299010914]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02172925531488,40.62067945213612],[-74.02180154239164,40.62060316560633]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03106093000177,40.61596182358245],[-74.03122817458835,40.6157229509399]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02897220554718,40.61351613045301],[-74.02900883778803,40.61348831325624],[-74.0290459533386,40.61345829828121]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02621402560658,40.621491677902604],[-74.0253636256148,40.62097721203771]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02365406373,40.61996084407536],[-74.02454267884777,40.61899006805416]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02037998679783,40.63772499451369],[-74.02011205349368,40.63754353345125],[-74.0199670520607,40.63745229992175],[-74.01988767284934,40.63740166261144],[-74.01983629848256,40.6373688898451],[-74.01969473945587,40.637285120781435]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01548877590352,40.615997917265965],[-74.0132887723416,40.61466918569875]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03444160139642,40.636799673550165],[-74.03453556414968,40.636566609184584],[-74.0346311431607,40.63632956360418],[-74.03472092466451,40.63610686565888]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0187756079456,40.625863636347496],[-74.01898345862661,40.62541158632016],[-74.01919007816649,40.62496219243581],[-74.01958196495558,40.62426700596428]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01926351278594,40.6334934144416],[-74.01824460047568,40.633033568464015]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02637946189289,40.63486579752866],[-74.0266796143697,40.634197255531234]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01958196495558,40.62426700596428],[-74.01977646873424,40.62399794263823],[-74.01980099502991,40.62396401552346],[-74.02001497722152,40.62367818969118],[-74.02019817886723,40.62343347723417],[-74.02022400332798,40.6233989827142],[-74.0206520374496,40.62290299036572],[-74.02074777209626,40.62278804052952],[-74.02101725483419,40.62246446741468],[-74.0211113073394,40.62235153613182],[-74.02120064391093,40.6222449162814]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02149466602913,40.625083859316064],[-74.02007423343322,40.62424643447731]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01647404786725,40.63455400245664],[-74.01638615297222,40.63437419909111],[-74.01631458153591,40.63418900846988],[-74.01626009044294,40.633999736233626],[-74.01622322305087,40.63380775991697],[-74.01620425180195,40.633614528955405],[-74.0162031995393,40.63342147555615],[-74.01620695995756,40.63322998887184]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02963292315899,40.63415292918439],[-74.02991368725351,40.63347412640776]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03453556414968,40.636566609184584],[-74.03446202734997,40.63654606343641],[-74.03410031836755,40.636429175722995],[-74.03409271665252,40.63642733181283],[-74.0340765952247,40.636432938242635],[-74.03407187163216,40.63644129646743],[-74.03405670758723,40.636468676292154],[-74.03399046525891,40.63658887046322],[-74.03398650928519,40.636596228647285],[-74.0339773319116,40.636612134673804],[-74.03395609717417,40.636649098406764]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01857695335988,40.625820029737554],[-74.01873197260363,40.62548802769678],[-74.01879595523144,40.62534199822793],[-74.01900103463993,40.62491699962598],[-74.01901580068703,40.62489171994932],[-74.01914231440227,40.6246750668982],[-74.01937999454046,40.62426803983217]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03693147508545,40.63069200317246],[-74.03719749671605,40.63004157093969]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0395811097823,40.62934957232688],[-74.03857697726073,40.62911341929082]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02090092828253,40.641224145557764],[-74.02104429869043,40.64106134159027],[-74.02117184780207,40.64089077792525],[-74.02128257283124,40.64071381496383]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01680939238204,40.630499032721445],[-74.01693073898797,40.63016061866642],[-74.01704937286613,40.6298297667804],[-74.01734316726642,40.629010403777855]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0250906838976,40.63779457402449],[-74.02262573388903,40.63679904847728]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03023638917101,40.63742756359688],[-74.03017355438932,40.63754507939572],[-74.03002074238991,40.63785817619956],[-74.02999415555,40.63790868393031],[-74.02998911187862,40.637918185953886],[-74.02998301713716,40.637928462400446],[-74.02997171323025,40.63794848366134],[-74.02995077059654,40.63798558160032]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0229098970756,40.63610746601653],[-74.0203921699701,40.63496479444601]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0365845091119,40.61089265321882],[-74.03660037064176,40.610932245651426],[-74.03667278063996,40.6110286192424],[-74.03678367732438,40.61119039886254],[-74.03696921718205,40.61142444497958],[-74.03710721225175,40.6115724294372],[-74.03724067912744,40.61171353075939],[-74.0373424558277,40.61180299840881],[-74.03747138246685,40.611923439086745],[-74.03767948227684,40.61212475342259],[-74.03786268324228,40.61228648128851],[-74.03805267422646,40.61245681424957],[-74.03846207311439,40.612833617268834],[-74.03872672362148,40.61308482466146],[-74.03889411634532,40.6132562381938],[-74.03902506363734,40.6133842686729],[-74.03916501509234,40.613570156739364],[-74.03933883241575,40.61378702941593],[-74.03954423637784,40.61409855954447],[-74.03982638869888,40.61452368653478],[-74.03995053345707,40.614721617727504],[-74.04006564659076,40.6149143851718],[-74.0401875286128,40.61513124614777],[-74.04025523278146,40.61528270259081],[-74.0403409695484,40.61554258038053],[-74.04037295853958,40.615656746455954],[-74.04041329306231,40.615807548323026],[-74.04044956874925,40.61603118679529],[-74.0405062381205,40.616363201713284],[-74.04056743755,40.61671585907407],[-74.04061728393145,40.61697217890549],[-74.04063482416896,40.6170563209492],[-74.04066487700251,40.61723890321579],[-74.04072604114643,40.61753319911499],[-74.0407758686208,40.61775693148532],[-74.0408370244256,40.61803745828432],[-74.04090497703095,40.618350684087616],[-74.04096159571871,40.61859678892674],[-74.04100690257529,40.61878715556244],[-74.04111558025323,40.619233561485416],[-74.04128323337294,40.620052770954366],[-74.04132853417697,40.62025585052886],[-74.04133050639992,40.62026702231631]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0229220192707,40.619983964591476],[-74.0227309635266,40.620105950932164],[-74.02256066583895,40.62028011843779],[-74.02207035595197,40.62077141122383],[-74.02195240648099,40.620900712256]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02619259951591,40.607850269052726],[-74.02535634457705,40.60735987918201]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03762041959803,40.629012751665954],[-74.03791790452361,40.62828155836065]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0206233103417,40.621806251563505],[-74.01999892578114,40.62145136823829]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01935806302573,40.63031045014765],[-74.01861253218762,40.629859539121846]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03700355407041,40.62331909077572],[-74.03728235187485,40.62263792793432]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0326468876647,40.61957917176456],[-74.03017406771407,40.61834033481151]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01835757405783,40.64079334796428],[-74.01894932186951,40.64021823525207]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02807729836564,40.61285475785517],[-74.02724262167769,40.61244385275721]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03191786785239,40.62136707146647],[-74.02920031510213,40.620721364082634]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02991804940461,40.612909999702005],[-74.0301167037708,40.61260522073694]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03566523550579,40.610677006337596],[-74.0356098598006,40.61060276377649]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03871694221942,40.626215895713685],[-74.03888474048244,40.62585431615087],[-74.0391088652061,40.625371381658674]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0295728483016,40.627103552092244],[-74.02987104022792,40.62637344160045]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.028797972029,40.6064893069155],[-74.02876637084445,40.60649310098538],[-74.02873468858635,40.60649647892471],[-74.02870293470679,40.60649943972588],[-74.02867111821864,40.60650198338659],[-74.02863924967266,40.60650410806135],[-74.02860733698257,40.60650581341309],[-74.02857539091967,40.60650709927151],[-74.02854342005709,40.606507965299485],[-74.02851143472631,40.606508410824254],[-74.02847944350054,40.606508435676155],[-74.02844745715133,40.606508040187606],[-74.0284154842518,40.60650722402141],[-74.02838353425504,40.60650598851548],[-74.02835161793196,40.606504332494495],[-74.0283197431971,40.6065022576318],[-74.02828792016263,40.606499764427525],[-74.02825615828102,40.606496852879395],[-74.02822446678552,40.606493524157905],[-74.02819285556886,40.60648977976847],[-74.0281613336442,40.60648562037898],[-74.02812991090407,40.60648104699235],[-74.02809859614244,40.60647606178435],[-74.02806739859226,40.60647066542294],[-74.02803632748706,40.606464860083825],[-74.02800539315905,40.6064586469373],[-74.02797460352276,40.60645202782438],[-74.02794396847158,40.606445005925806],[-74.02791349679862,40.606437581574646],[-74.02788319795783,40.606429758454354],[-74.02785308030289,40.6064215374007],[-74.02782315350782,40.606412922767234],[-74.02779342526689,40.606403915557415],[-74.02776390569319,40.606394518952],[-74.02773460292147,40.60638473596473],[-74.0277055268447,40.606374569106315],[-74.02767668383919,40.606364021725945],[-74.02764808423765,40.606353096669345],[-74.02761973661464,40.60634179762022],[-74.02759164888487,40.606330127424876],[-74.0275638289633,40.6063180894322],[-74.02753628542459,40.60630568782856],[-74.0275090268434,40.60629292680028],[-74.02748206091442,40.60627980869119],[-74.02745539555293,40.60626633802284],[-74.02742903933347,40.6062525188141],[-74.02740299973186,40.60623835592177],[-74.0273772848826,40.60622385252713],[-74.02735190138198,40.60620901298463],[-74.02732685758512,40.60619384248585],[-74.0273021609672,40.60617834454741],[-74.02727781834483,40.60616252503137],[-74.02725383807237,40.60614638745412]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0357017562614,40.61051585256555],[-74.03556528781051,40.6103342778818]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03463999435027,40.62910561340451],[-74.0319567238525,40.62847059683122]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01369310085788,40.60301428369408],[-74.01373511967512,40.60303766490324],[-74.01382909343616,40.60296847601477],[-74.01382987318183,40.60296796261181],[-74.01383027446845,40.602967629348164],[-74.01383075903324,40.60296716975756],[-74.0138387564582,40.602959676558896],[-74.0138652812689,40.60296157330935],[-74.01403750231401,40.60304592256542],[-74.01411010100465,40.60308153789822],[-74.0141415321011,40.60309718544008],[-74.01414472235928,40.60309854471356],[-74.01416377061793,40.603108312831566],[-74.01423087504398,40.603142740648565]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02247991392478,40.636950778659674],[-74.02262573388903,40.63679904847728]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02693578540799,40.640281605031376],[-74.02699329962992,40.64030518239764],[-74.02705236549089,40.6403293956431],[-74.02733016037459,40.640443263200495],[-74.02744090264332,40.640493593865926],[-74.02771495535399,40.640618133113875],[-74.02804107385933,40.640774005603305],[-74.02840354045463,40.64094724826294],[-74.02860168086639,40.641031415861214],[-74.02864909826936,40.64105155789528],[-74.02890106038102,40.64114658029731],[-74.02923285748857,40.64124676939708]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0291039543851,40.60655740829638],[-74.028797972029,40.6064893069155]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01281316989956,40.602778952512395],[-74.01286297414647,40.60274027872143],[-74.01289323286024,40.60274021217237],[-74.01290173997114,40.60274239948271],[-74.01290557993599,40.602743866941495],[-74.01292277202474,40.60275075380598],[-74.01293148032273,40.60275442707452],[-74.01295537214227,40.602765888232106],[-74.01296647965613,40.60277232579262],[-74.0130730630786,40.602835575216396],[-74.01312251396986,40.60286497127135],[-74.01316086985106,40.60288778652557],[-74.01317159922657,40.60289471932549],[-74.01323305637827,40.6029330921751]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0378401315405,40.62127474544687],[-74.03809447949352,40.620584898475926]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.033880137792,40.63816726910346],[-74.03209040108409,40.63761348651111]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0266796143697,40.634197255531234],[-74.026950773583,40.6335159315419]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02607424630311,40.6171524523089],[-74.02664722173601,40.61650772129021]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03019093198031,40.63279069500373],[-74.02750722453025,40.63215460208875]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01439632401156,40.64118583630968],[-74.01497963664175,40.64062546817968]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02591140454368,40.6064996600137],[-74.02567519686234,40.60645386551876]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03539473682623,40.6162052328757],[-74.03414586365614,40.615913472934395]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0409486735115,40.62985345229276],[-74.04102780697559,40.62986314560158],[-74.04095391769229,40.63012729424754]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02937062544534,40.64003267329858],[-74.02949125863923,40.63991314371089]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03693147508545,40.63069200317246],[-74.03618712835667,40.630449765789244],[-74.03609024779193,40.63041824205555],[-74.0359946910694,40.630387141170566],[-74.03589868578145,40.63035589610398],[-74.0343355365717,40.62984715685466]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03603691068763,40.63001277281996],[-74.0359572799325,40.629989591684534]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0187927156488,40.62422469662925],[-74.01907578304655,40.62361467353489]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02867799741152,40.62929432896287],[-74.02897576006832,40.628564077168186]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02108694468097,40.63834699980372],[-74.02116029833357,40.63828079800591],[-74.02123523188197,40.638204735477906]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02664251543516,40.63974743200312],[-74.02650036803593,40.639673316086004]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04062974587427,40.63006448985859],[-74.04049062428071,40.630040557714736]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03255489248096,40.62701008290811],[-74.0303335244575,40.6264831571797],[-74.02987104022792,40.62637344160045]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03692682926332,40.633639278486434],[-74.03583589818798,40.633369846041106]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02149533368774,40.62007384181899],[-74.02123132903111,40.62032555046544],[-74.02119841399954,40.620356930495184]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03278399911363,40.61048532955953],[-74.03303373647016,40.61039886135503],[-74.03359214154472,40.61021636717529],[-74.0345020808211,40.609918978456534],[-74.03489726686202,40.60979182728423]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02628612034283,40.64007452838303],[-74.0265062149532,40.64013693765908],[-74.02663642213628,40.64017843938142],[-74.02672294298247,40.640206011074845],[-74.02675745515546,40.64021826847694],[-74.02693578540799,40.640281605031376]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01514575030541,40.63701460961411],[-74.01573946898866,40.63645223721393]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01697745739544,40.635235081662316],[-74.01647404786725,40.63455400245664]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03144638542759,40.61111981450731],[-74.0319023015974,40.610842074279915],[-74.03192153893677,40.61083035531361]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02466370948821,40.63998338594343],[-74.02494523728929,40.639976571474875],[-74.02522734874299,40.63998381316596],[-74.02550823648176,40.640005102366764],[-74.0257362003176,40.64003394704688],[-74.0257860913095,40.64004025990145],[-74.02601346927251,40.64007751693916],[-74.02623698651284,40.64012649017486]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03014945024137,40.6256909459527],[-74.03042727609291,40.625009935881906]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0227329117209,40.618088109472126],[-74.0218300638167,40.617643463399624]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03621949918892,40.62523729489375],[-74.03629440444766,40.62525381406212],[-74.03631865943677,40.62525914671544],[-74.0363289081662,40.62526151166337],[-74.0378108396491,40.625603699585874],[-74.0387168641305,40.625815578518825],[-74.038807185495,40.62583702558261],[-74.03883456199712,40.62584342816489],[-74.03888474048244,40.62585431615087]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01270818900075,40.61522802485697],[-74.0132887723416,40.61466918569875]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01522379499055,40.60935638411836],[-74.01448201327624,40.60891037993433]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03535192832503,40.61367299010914],[-74.03572584040815,40.613103033908445]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03724455888974,40.63598546946852],[-74.03649979593658,40.63578261429032]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04111334568839,40.62055643802011],[-74.04089225982429,40.6205675662378]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01726142532779,40.62526924225197],[-74.01679067645863,40.62498365842653],[-74.01466131817872,40.62369181153227]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01906269284504,40.63103852457284],[-74.01812288900891,40.6304716553551]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03938233056559,40.62989631922404],[-74.0383518812977,40.62966281148568]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03107191835245,40.636521049503266],[-74.03108012876945,40.63648525146669],[-74.03109018290435,40.636448498688466],[-74.03109116296864,40.63644549949553],[-74.03117231102061,40.63623765605417],[-74.0313748233956,40.635729843295486],[-74.03137585051,40.63572733963643],[-74.03151374912447,40.635421422971795],[-74.03152171950066,40.63540291474753],[-74.0315424419052,40.63535474025528]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02536097320035,40.630109349572315],[-74.02295953768112,40.62870131512131]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01478487192244,40.620124798828],[-74.01536728802037,40.619563617220855]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02535634457705,40.60735987918201],[-74.02420073770841,40.60667516628721],[-74.02313801279013,40.60606717683646]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03578781851749,40.61062489520545],[-74.03574931863533,40.61066010150527],[-74.03569291352058,40.61071640424595]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01805930548775,40.62861955791651],[-74.01832782585751,40.62786195301802]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02227765242675,40.64069060875752],[-74.02231552715662,40.64064838542153],[-74.02246253935158,40.64053889857811]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02117699460089,40.62125785685994],[-74.02172925531488,40.62067945213612]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02979312008893,40.61086565998481],[-74.02807729836564,40.61285475785517]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03295871707287,40.6188173952282],[-74.03303206493426,40.6186409349872]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02957542681239,40.616066234228235],[-74.02962126701001,40.61604035931713],[-74.0296384521246,40.61601994015365],[-74.02965432588765,40.61600106125128],[-74.02969417730382,40.61595502525268],[-74.02971600354445,40.6159298053436],[-74.02973791349235,40.61590450365453],[-74.02974890966276,40.61589181267458],[-74.02987262025292,40.615749048163984],[-74.02965330259964,40.61563997965098],[-74.02958984193515,40.61560842367824]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0163860448736,40.63316196515229],[-74.01640635137058,40.63306292322013]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01735110147658,40.63834114939077],[-74.01514575030541,40.63701460961411]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0225901676178,40.64043910503215],[-74.02310593208485,40.63999532592684]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03813109362966,40.61980248725406],[-74.03810647776218,40.6197625756445],[-74.03797961306607,40.6195570195589],[-74.03786082802691,40.61936288881475]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02246253935158,40.64053889857811],[-74.0225901676178,40.64043910503215]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0253636256148,40.62097721203771],[-74.02446644099014,40.62043675220262]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.037277150459,40.63183994560939],[-74.03719039134116,40.631819063957124]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02534486402693,40.62285939371732],[-74.02297788444453,40.62143139583279]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03265265152646,40.61053783149366],[-74.03278399911363,40.61048532955953]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03432894277553,40.612042924837105],[-74.03487149024217,40.611366235710996]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.029181298129,40.640208304378575],[-74.02906871123548,40.64032115006634],[-74.02905214438354,40.64033778664433],[-74.02908055914348,40.6403553939051],[-74.02908251065865,40.64035670800725],[-74.0292950965905,40.6404875892504],[-74.02933358668142,40.64051128990607],[-74.02939371574907,40.6405483489308]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03364741814288,40.6128332434378],[-74.03185652853652,40.611951954590694]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02490366228277,40.6191699411672],[-74.02487456699991,40.61920343781775],[-74.02456436211807,40.619560668920556],[-74.02455778239354,40.619568108773144]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03472092466451,40.63610686565888],[-74.03499884243531,40.635426240975704]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0234477115474,40.640183699606446],[-74.02340727397285,40.640160834348876],[-74.02336300700999,40.64014077126573]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02868000278448,40.62199620868128],[-74.02892312153189,40.62140418198831]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02839765193403,40.61744349936352],[-74.02748855985243,40.61698424481986]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0208949241506,40.626542992247636],[-74.02098508311434,40.626323879460436],[-74.02104454670462,40.6261793801193],[-74.02110195466813,40.626039861248046],[-74.02119408413276,40.625815947890985]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02102869220572,40.63194142046481],[-74.02089209156752,40.631879624970956]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01697095893735,40.63161800324111],[-74.01733664052384,40.63072928935317]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03766509208317,40.61518117776205],[-74.03744195485375,40.614614769268826],[-74.03707918142358,40.613826740723496]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02803565519747,40.623571774056906],[-74.02566164211383,40.62214065420595]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03151434452992,40.61533019183227],[-74.03194673568348,40.61481445204419]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02920569966861,40.637754663849144],[-74.02922459616848,40.637716179931715],[-74.02923618256047,40.6376924844371],[-74.02937096127144,40.637437531362956],[-74.02937491784357,40.63743026330117],[-74.02940262143127,40.63739166000046]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02927435380454,40.61371201632833],[-74.02939088477517,40.61374984444098],[-74.0295187193457,40.613775098330876],[-74.02965427526304,40.61378538338867],[-74.02979287230629,40.613779125023186],[-74.029863818116,40.613767053075144],[-74.02992925259285,40.613755919172576],[-74.03005818059675,40.613716667849204],[-74.03017512019815,40.61366342550322],[-74.03027672788744,40.61359912849341],[-74.03036970195623,40.61351973211525],[-74.03074400114528,40.613058295314936],[-74.03232784000393,40.61104001817858]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0348936622186,40.615375700441724],[-74.03457883421241,40.61485994998373]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01722288166013,40.62810068935286],[-74.01500072034628,40.62676890709503]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02840552031603,40.64032182910622],[-74.02770568281922,40.639894406609905]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02853941735353,40.63909112941787],[-74.02762394706329,40.63880495150758]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02900836845947,40.62119206102639],[-74.02722013300452,40.6203223521233]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02452013786399,40.63216736274899],[-74.02479160206568,40.631505711163186]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02735286784608,40.637179949465235],[-74.02697782347995,40.63706606842872],[-74.0256661527146,40.63666778118139]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01873294617045,40.61977703674513],[-74.01652978734877,40.618447035351615]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03095125999282,40.60682549683299],[-74.03002274769756,40.606371547612746],[-74.03000099823768,40.606365246158646],[-74.02997908737107,40.6063592803032],[-74.02995702345072,40.606353651049346],[-74.02993481505064,40.60634836208034],[-74.02991247118341,40.606343414734006],[-74.02989000152152,40.60633881152069],[-74.02986741441804,40.60633455361087],[-74.02984471954555,40.606330643682405],[-74.02982192635595,40.606327082570445],[-74.02979904298255,40.60632387161303],[-74.02977607997691,40.606321012985255],[-74.02975304591149,40.60631850701993],[-74.02972995067803,40.60631635505467],[-74.0297068021899,40.60631455826012],[-74.0296836123168,40.60631311713573],[-74.02966038787258,40.60631203184728],[-74.02963714050723,40.60631130322936],[-74.02961387813355,40.60631093111242]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03642583101983,40.62473459544902],[-74.03423145892678,40.624214877779806],[-74.03374211670423,40.62409897210223]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03672590071159,40.63120193382939],[-74.03404156746652,40.6305650302342]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03567138901339,40.634952496449834],[-74.03573774663447,40.6347914177523]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01863896276912,40.627070526373515],[-74.01896027313887,40.6262956399302]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03992966724103,40.628018285470205],[-74.03819614582365,40.62759933171589]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02979312008893,40.61086565998481],[-74.02897939713604,40.61045523894107]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01647404786725,40.63455400245664],[-74.0164172411502,40.634278244524445],[-74.01637986708242,40.63399996231714],[-74.01636218608019,40.633720344598984],[-74.0163642806579,40.63344060695445],[-74.0163860448736,40.63316196515229]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02227765242675,40.64069060875752],[-74.0223336765866,40.64065870181706],[-74.02250538867234,40.640560907792185]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04066167213976,40.62668935722538],[-74.03969489039251,40.62643618965051]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01733664052384,40.63072928935317],[-74.01699572995919,40.630582212938066]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01970491557115,40.62218496450551],[-74.01756994176787,40.62089820597792]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03968659646677,40.623956628849086],[-74.03700355407041,40.62331909077572]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03154600534789,40.63784088301529],[-74.03158208623707,40.637773126767435],[-74.03170810990329,40.63754540494757],[-74.03173077403736,40.6375014266537]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03014945024137,40.6256909459527],[-74.0274372501343,40.625027608911445]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03432894277553,40.612042924837105],[-74.0331351948914,40.611444473576626]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0282052488583,40.619172663284246],[-74.02730164954356,40.61872254016571]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02959936599987,40.6414297687984],[-74.02955655870964,40.64137563177447],[-74.02949037963523,40.64132096933019]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03135989933355,40.62993051264942],[-74.03165800059992,40.62919908300082]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01794424974013,40.63621022375068],[-74.01745337783365,40.635956642036504],[-74.01716610679975,40.63579585103531],[-74.01701715170542,40.63571990636336],[-74.0167752165443,40.635575849291364],[-74.0166954641309,40.635521475108796]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02831656444577,40.63525568567155],[-74.02649344678443,40.63498473970441],[-74.02637946189289,40.63486579752866]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01780244173645,40.62936684005484],[-74.01805930548775,40.62861955791651]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03509032550566,40.60960201210761],[-74.03525978733708,40.60954610976749],[-74.0357344518362,40.60938952460263]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03622076800592,40.6179062668591],[-74.03631596928282,40.617707852005886]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04087635200995,40.630111937360105],[-74.040836821468,40.630221803787514],[-74.04077867018931,40.63036973344771]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02868000278448,40.62199620868128],[-74.02677000503712,40.620846254697554]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02835300020536,40.628893174103304],[-74.02838907093386,40.62880528352537]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01542409868877,40.63251313909726],[-74.01372623491201,40.631486114089114]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01824460047568,40.633033568464015],[-74.01668903337765,40.63230494271675]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02469500573287,40.613345376781425],[-74.02485288026556,40.61330364665004],[-74.02498253643968,40.613048676547045],[-74.02493090135873,40.61292240864163],[-74.02469952289604,40.61287957118757],[-74.02459013256545,40.6129808559933],[-74.02456833386245,40.613216741714474],[-74.02469500573287,40.613345376781425]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03320700519672,40.609332198947484],[-74.03329588477533,40.60918863908337],[-74.03336682427098,40.60903861874358],[-74.03341872590923,40.60888414578027],[-74.0334510237297,40.60872731968973],[-74.03343995348658,40.608660342134634],[-74.03341572135714,40.60859462889354],[-74.03337891958397,40.60853240473893],[-74.033330977342,40.60847564089323],[-74.03297346975809,40.60799788509587]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04017982041616,40.62163217648139],[-74.0400172909373,40.62162071104445],[-74.03989576570638,40.621622779375585],[-74.03985304521277,40.62162350619059],[-74.03969028701802,40.62164064993172],[-74.03953222639291,40.621671665723504],[-74.0378401315405,40.62127474544687]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02318505145092,40.61967585283674],[-74.02293270340282,40.6195046246781]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02313801279013,40.60606717683646],[-74.02312545784142,40.60606139927626],[-74.02311318303585,40.606055282077],[-74.02310120464223,40.606048833109334],[-74.02308953739087,40.60604206074686],[-74.0230781964516,40.60603497319555],[-74.02306719677503,40.60602758033671],[-74.02305655199265,40.60601989154933],[-74.02304627661526,40.60601191621221],[-74.0230363829559,40.606003665044874],[-74.02302688464631,40.60599514826393],[-74.02301779334054,40.60598637776172],[-74.02300912091165,40.60597736325263],[-74.02300087857452,40.60596811830438],[-74.0229930768837,40.6059586536368],[-74.02298572595444,40.60594898131005],[-74.02297883546287,40.60593911455708],[-74.02297241354601,40.60592906560594],[-74.02296646922036,40.60591884735469],[-74.02296100952421,40.60590847303675],[-74.02295604259498,40.60589795605292],[-74.02295157327288,40.60588730980459],[-74.02294760859644,40.605876548362865],[-74.02294415340607,40.60586568563174],[-74.0229412116627,40.605854735012784],[-74.02293878776736,40.60584371124775],[-74.02293688458208,40.60583262824097],[-74.02293550430959,40.605821500064486],[-74.02293464915275,40.60581034146043],[-74.0229343197757,40.60579916683619],[-74.02293451684237,40.60578799009653],[-74.02293523969826,40.60577682631921],[-74.02293648856761,40.60576568924154],[-74.02293826081747,40.60575459343906],[-74.02294055403463,40.60574355331975],[-74.02294336646537,40.60573258345893],[-74.02294669261867,40.60572169692492],[-74.02295053008156,40.605710908628254],[-74.02295487248412,40.605700232642604],[-74.02295971565424,40.605689681868455],[-74.02296505212293,40.60567927021218],[-74.02297087486096,40.60566901174753],[-74.02297717727818,40.60565891904043],[-74.02298395102616,40.60564900515976],[-74.02299118775636,40.60563928267177],[-74.02322142391829,40.605413769589454]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02295953768112,40.62870131512131],[-74.02059936527971,40.62727660878118]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02878765258042,40.60738258183073],[-74.02846265641435,40.60836448096973]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02262573388903,40.63679904847728],[-74.0229098970756,40.63610746601653]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02838485437434,40.614249499277726],[-74.02848373720121,40.614080203943956],[-74.0285998629294,40.613916757190815],[-74.0286977168602,40.613801376245824],[-74.02897220554718,40.61351613045301]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02916023122874,40.640774915867915],[-74.02979466903331,40.64105006008151],[-74.03013289110933,40.641160609402085],[-74.03044289563195,40.64124537453417],[-74.0304802568048,40.64125559442573],[-74.03071436334946,40.64130760951986],[-74.03083488678978,40.64133438566706],[-74.0311948180048,40.64139655957739],[-74.03155802828581,40.64144186402923]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02874956791189,40.61286536177699],[-74.02892473285023,40.612477702955296]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03470051608272,40.61465860187504],[-74.0349464362437,40.61428853040123]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02007423343322,40.62424643447731],[-74.02062537093991,40.6236556048074]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0331351948914,40.611444473576626],[-74.0326937111618,40.61195667217721]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02173941742474,40.64092269441724],[-74.02235353957046,40.64049013888823],[-74.02297009390854,40.63993460447853]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03259356920195,40.63410974953538],[-74.03041897969426,40.63359397897338],[-74.02991368725351,40.63347412640776]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03809447949352,40.620584898475926],[-74.03770067568371,40.61995529454051]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02118998208482,40.63816666828789],[-74.02115312268505,40.63813169160991]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0378975918966,40.632286706407285],[-74.03840315446585,40.631715294441875]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01750512326755,40.63474754258663],[-74.0177562083344,40.63425010916054]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03642637951485,40.63193208913182],[-74.03420240543339,40.63140550925466],[-74.03374248159624,40.631296601278436]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02119382240137,40.640660502364426],[-74.02125122470903,40.64050168453205],[-74.02127773320815,40.6404208285641],[-74.02131203125994,40.64029360078181],[-74.02134630934307,40.640105735233966],[-74.02136503256754,40.6399892721813],[-74.02135412676695,40.63985986082788]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01717481839918,40.64195100363017],[-74.01774227617491,40.64140075417448]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02929556017932,40.62048690775809],[-74.02771303825047,40.61974854921492]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0268895184541,40.60606688189295],[-74.02680029392945,40.60604971308028],[-74.0260898717898,40.60591312207867]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01490317317815,40.63035265462519],[-74.01449663637622,40.63010715337015],[-74.01270270783309,40.62902375201164]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01910090435524,40.60377437196514],[-74.0190283337961,40.60389186628152],[-74.01891655450407,40.60403002485339],[-74.01878558445063,40.604158613674244],[-74.0186376788116,40.604275390439135],[-74.01847566202073,40.604378580161175],[-74.01793148581856,40.60467612710664]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03005683854005,40.64152123323449],[-74.03054176044317,40.64160506082659],[-74.03072664444029,40.641637024412816],[-74.03087289496462,40.64164758342487],[-74.03119427234674,40.64167078515637],[-74.03155090650515,40.64168212485894],[-74.03160550093114,40.64168385668599],[-74.03201707644045,40.64168121214766],[-74.03242743888188,40.641662906926776],[-74.03264498353354,40.64163924296698],[-74.03273838645941,40.6416267045537],[-74.03287461964985,40.64160841564487],[-74.03310231250543,40.641570519394115],[-74.03329533326483,40.64153605500695],[-74.0336321807286,40.64145946702385],[-74.03383017108433,40.641410366676816]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02104201559015,40.62186201738322],[-74.0211257337195,40.62171935312295],[-74.02188450761754,40.62085685192503]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03283230942773,40.62632904897046],[-74.03310842055332,40.625647051398644]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03707918142358,40.613826740723496],[-74.03534760179224,40.614428276285686]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02961387813355,40.60631093111242],[-74.02893798474447,40.60596168694237]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04049062428071,40.630040557714736],[-74.04048536806118,40.63005146903064],[-74.04047958225043,40.63006222355839],[-74.04047327387532,40.630072805882826],[-74.04046645238253,40.63008320209566],[-74.04045912721804,40.63009339728341],[-74.04045130826826,40.63010337737012],[-74.04044300695894,40.630113128614305],[-74.04043423449613,40.630122637442106],[-74.0404250020861,40.63013189061472],[-74.04041532423359,40.6301408750597],[-74.04040521324485,40.63014957837547],[-74.04039468406498,40.63015798832713],[-74.04038375054051,40.63016609418782],[-74.04037242783639,40.630173883554974],[-74.0403607322181,40.63018134586851],[-74.04034867973161,40.63018847107093],[-74.04033628708254,40.63019524910458],[-74.04032357141683,40.63020167074923],[-74.04031054988039,40.63020772661715],[-74.04029724203862,40.630213408492494],[-74.0402836652586,40.63021870916536],[-74.04026983844584,40.63022361991752],[-74.0402557811673,40.63022813504608],[-74.0402415127696,40.63023224801054],[-74.04022705303925,40.63023595243786],[-74.04021242176404,40.630239244132774],[-74.04019764027069,40.63024211822947],[-74.04018272812694,40.63024457019776],[-74.0401677068809,40.63024659768467],[-74.04015259588078,40.630248196662706],[-74.04013741777476,40.63024936578372],[-74.04012219323151,40.63025010286259],[-74.04010694336036,40.630250407221794],[-74.04009168883121,40.63025027868662],[-74.04007645119341,40.630249716914484],[-74.04006125155713,40.630248722568176],[-74.04004611081353,40.63024729781824],[-74.04003105117243,40.630245443662204],[-74.04001609154679,40.6302431636116],[-74.04000125480697,40.63024046017144],[-74.03998656052616,40.630237337858226],[-74.03997202871666,40.63023380001564],[-74.03995768049138,40.63022985199732],[-74.03994353520412,40.63022549915752]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03076395882779,40.63139134328966],[-74.03106070351704,40.63066101398831]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01908870904697,40.62880986967862],[-74.01939273718317,40.62899320034568],[-74.01941256238602,40.629005453060536]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02713876775371,40.625761900638224],[-74.0271530069287,40.62572685847986]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01556266734983,40.64006663684698],[-74.01616711475104,40.63948244106678]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02595819003183,40.62864726756076],[-74.0262631546062,40.627919956893415]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0218300638167,40.617643463399624],[-74.02281427319133,40.616487579503314]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02623698651284,40.64012649017486],[-74.0266059569794,40.64023610670892],[-74.02672639818762,40.640271883460805],[-74.02690348724707,40.64033616621902],[-74.0269565265133,40.64035542492956],[-74.02701730000466,40.64037991404697],[-74.0271819542222,40.64044627916214],[-74.02740210088201,40.6405441851475]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03578781851749,40.61062489520545],[-74.0357579567263,40.610585886666165]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0192589306462,40.63055955035461],[-74.01935806302573,40.63031045014765]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03442486409209,40.617897399052914],[-74.03450324742059,40.61791549396554]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02477732246007,40.6096959975268],[-74.02430437611244,40.60945696914183]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0378401315405,40.62127474544687],[-74.03515779409116,40.6206379203186]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01372623491201,40.631486114089114],[-74.01432214759274,40.63091131175038]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01887440764712,40.63687170404401],[-74.01892465780084,40.63682599451224]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01403349690504,40.62429394156755],[-74.01466131817872,40.62369181153227]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02059936527971,40.62727660878118],[-74.0208949241506,40.626542992247636]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03000540325685,40.60774150653983],[-74.02878765258042,40.60738258183073]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03331256633761,40.61794500424376],[-74.03251940529113,40.61753669198706],[-74.03230579701483,40.61742673534823]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04127389915878,40.620545249874645],[-74.04118740585031,40.62055035098769],[-74.04111334568839,40.62055643802011]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02613488275219,40.61624944121495],[-74.02574989060072,40.61605822319546]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03432262014285,40.622682209635734],[-74.0346006153585,40.62200073904816]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01466131817872,40.62369181153227],[-74.01524185216765,40.62313302617248]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02536097320035,40.630109349572315],[-74.02566011106731,40.6293777102856]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03188910319959,40.60622953633805],[-74.03184722502904,40.60620289541893],[-74.031559420893,40.6060198059185],[-74.03155123025424,40.60601409894484],[-74.03124514567051,40.605829503899464],[-74.03119264829469,40.60580089045979],[-74.03092726450657,40.60565627520922],[-74.0306103501528,40.60550074113889],[-74.03059870954031,40.60549503451327],[-74.03032603457281,40.60537509215105],[-74.03026064986143,40.60534633074061],[-74.02991433912086,40.60521064077185],[-74.02964032095194,40.605113131448874],[-74.02935936175709,40.60502740187849],[-74.02907276020643,40.60495384772029],[-74.02875978979088,40.604885027621194],[-74.02859422907376,40.60485718623077],[-74.0284407301465,40.60483137274003],[-74.02811750631386,40.60479330623635],[-74.02779208060241,40.604771061471205],[-74.02746644841969,40.60476467396785],[-74.02673311712935,40.604762880088785],[-74.02655663485996,40.6047624477334],[-74.02573899089651,40.604818088051445],[-74.02505205646193,40.604899971068754],[-74.02487127360016,40.60490854711072],[-74.02477800482058,40.60491297109266],[-74.0242510481294,40.60493094929197],[-74.02405502202626,40.604934970977425],[-74.02396934846423,40.6049335479593],[-74.02363303529165,40.60492798025317],[-74.02329696415347,40.604905950443346],[-74.02300999672191,40.60488001025655],[-74.02300626422956,40.60487950640621],[-74.02284697346484,40.6048579976298],[-74.0226569504346,40.604830992873076],[-74.02240802416097,40.60478996857496],[-74.02216002619856,40.60473498570717],[-74.02191797143372,40.604676994024054],[-74.0217913446242,40.60463309918552],[-74.02139467297454,40.60449399826911],[-74.0212399084636,40.604445228772704],[-74.02117927174122,40.60442612087531]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03423145892678,40.624214877779806],[-74.03426442747485,40.624134505428174],[-74.03427317395251,40.62411317842293],[-74.03428752753022,40.62407897248074],[-74.03429504717646,40.62406075249254],[-74.03450335451255,40.62354000931789],[-74.0345121359274,40.62351808789061],[-74.03452815336368,40.623478217269614]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0406625157839,40.62491296436131],[-74.04066851552675,40.62486148685876],[-74.0406750218684,40.62481004553012],[-74.04068203239004,40.62475864188393],[-74.04068954819263,40.624707280442955],[-74.04069756729699,40.62465596254804],[-74.04070609102406,40.62460469288943],[-74.04071511827394,40.62455347247257],[-74.04072464860812,40.62450230515063],[-74.04073468092776,40.62445119360436],[-74.04074521545319,40.62440014051401],[-74.04075625020661,40.62434914939824],[-74.04076778628752,40.62429822226688],[-74.0407798223773,40.624247361968195],[-74.04079235781758,40.624196572355466]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01951221265783,40.631064825539895],[-74.0197089878369,40.63081380798731],[-74.01973749841753,40.63077744888532]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01938702927659,40.622891818697134],[-74.0169877795685,40.62145382444481]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02917223570252,40.613665332380094],[-74.02920764006413,40.613641315322916],[-74.02924131468855,40.613606654745]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03285202575337,40.62126596787461],[-74.03290196645239,40.621259713144966],[-74.03299929055937,40.62128576462332],[-74.0333203824999,40.62136325190673],[-74.03422964685988,40.62158057701813],[-74.03423446945858,40.62158172834767],[-74.03424059270613,40.62158534682106],[-74.0342544257506,40.6215960590138],[-74.03425705087967,40.62159858841879],[-74.03415861061436,40.62184133525137],[-74.03415446755523,40.62185171003185],[-74.03413853362338,40.62189159884346]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01726142532779,40.62526924225197],[-74.0179762689204,40.624788030275724]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02724257527268,40.60969437183326],[-74.026964374151,40.6096611722093],[-74.02668853135235,40.609616453579186],[-74.0264162772145,40.60956040515229],[-74.02614880450311,40.60949328752524]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02739102824535,40.6265862758387],[-74.02737458023361,40.62662536235682],[-74.02730368669837,40.62679381272568],[-74.02727345065932,40.626874406896306],[-74.02727276380786,40.62690036010057],[-74.02727297933839,40.62690747465762],[-74.02727525036003,40.62691096759454],[-74.02729081305004,40.62693157679833],[-74.02729135633635,40.62693202732152],[-74.02737867668041,40.626960102796104],[-74.02738593428771,40.626961820917046],[-74.0283683515751,40.6271928900624],[-74.02838410796267,40.62719596635584],[-74.02844363448467,40.62720754999006],[-74.02845363364847,40.627207286171085],[-74.02846293393021,40.62720420435683],[-74.02847265227433,40.6271827338202],[-74.02850165314429,40.62711834804269],[-74.0285689310242,40.62695882225937],[-74.02858123820383,40.626912298327454],[-74.02859230686455,40.626871088041824]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03287451463889,40.633429345431814],[-74.03300972797861,40.633095187369044],[-74.03315548281145,40.63273497322292]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03297346975809,40.60799788509587],[-74.03274647058772,40.607738290570644]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03607763349201,40.61731632634254],[-74.03592460933342,40.61705482737083]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03435188956077,40.61716164135983],[-74.03452255511358,40.61720230259361]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03470524300107,40.63800139985099],[-74.03500891809902,40.638092962800954]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03558827806658,40.63976311168031],[-74.03595784256667,40.638821144636054]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02238878740263,40.6228960101773],[-74.02268668861555,40.622178102265764]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0217716818721,40.63919193654847],[-74.02174220735287,40.63907249785077],[-74.02171064156752,40.63895526521858],[-74.02165752918506,40.63881172344272],[-74.0215992224088,40.63868943544506],[-74.02158872937285,40.63866742819537],[-74.02148856318281,40.638504533895954],[-74.02137014718652,40.63834973904815],[-74.02123523188197,40.638204735477906]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02163305222066,40.64097898811244],[-74.02173941742474,40.64092269441724]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02297788444453,40.62143139583279],[-74.02262514142657,40.62121078448925]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03214569081936,40.63685776473933],[-74.03250380538073,40.63619865497107]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03433357770008,40.63261112138024],[-74.03387257059656,40.632504609918286],[-74.03385483741619,40.632498608403466],[-74.03384686798253,40.63249403621406],[-74.03383634168216,40.63248055862171],[-74.03382969102249,40.63246653039437],[-74.03383257990103,40.63245281481636],[-74.03383772767364,40.632440179132914],[-74.03385228370408,40.63240446009819],[-74.03393335141935,40.63220574544807],[-74.03394095478221,40.632187138483346],[-74.03394113564035,40.63217177589028],[-74.0339388248587,40.63216032197223],[-74.03393650062806,40.632145337727984],[-74.03393562519746,40.63214399641737]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02119408413276,40.625815947890985],[-74.0196317127963,40.62487969357479]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02893158849291,40.62695152766981],[-74.02895326016534,40.626912808512905],[-74.02897717538438,40.626870370319565],[-74.02903027238214,40.62674581475806],[-74.02906405661199,40.62664954976586],[-74.02906581526197,40.626643128784195],[-74.02906547099312,40.626639734069826],[-74.02906326942937,40.62663234125021],[-74.0290599798418,40.62662429165801],[-74.0290547401582,40.62661574667366],[-74.02904147468901,40.626604655605234],[-74.02903201669243,40.626599759119976],[-74.02894942602252,40.62657495286403],[-74.0283014233018,40.62642178239657],[-74.02780510101816,40.626304529715696],[-74.02766815380053,40.626276592833605],[-74.02757464454392,40.62625774922264],[-74.02755385662383,40.62626236493139],[-74.02753231385958,40.62626910575115],[-74.02752718491176,40.62627154770487],[-74.02752385371346,40.62627620429241],[-74.02751148719908,40.626295505217875],[-74.02750790794917,40.626301161508025],[-74.02750683402681,40.626303728137046],[-74.02745828253681,40.62642198685649],[-74.02740709798469,40.62654703645456],[-74.02739102824535,40.6265862758387]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03453827136116,40.61493893814984],[-74.03457883421241,40.61485994998373]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0356098598006,40.61060276377649],[-74.03567061445798,40.610549533212726],[-74.0357017562614,40.61051585256555]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01976701060362,40.624265965941355],[-74.01994399944483,40.62427494975972]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01728366756804,40.60513782469659],[-74.01651620384442,40.60467228684249]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02685720207243,40.62645774644725],[-74.02713876775371,40.625761900638224]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02219951245164,40.637211965502566],[-74.02247991392478,40.636950778659674]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03263386385349,40.631834450377944],[-74.03076395882779,40.63139134328966]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01549855009637,40.606841524276895],[-74.01640553134816,40.60597592481384],[-74.01671283875817,40.60568263485323],[-74.01728366756804,40.60513782469659]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01733664052384,40.63072928935317],[-74.01755939514045,40.63013156236207]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0357344518362,40.60938952460263],[-74.03562633530302,40.609301955243104],[-74.03555694283821,40.609264532827524],[-74.0354827214616,40.60923338917227],[-74.03498173502663,40.6089706264141],[-74.03446423136421,40.60851882869996]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0212304808349,40.64158837204826],[-74.02132163000478,40.641449792263394],[-74.02146714650722,40.641236189071776]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03192153893677,40.61083035531361],[-74.03134204356986,40.61111384128102]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03268156207943,40.610360456834215],[-74.03281702885371,40.61032280362599],[-74.03295222200916,40.61028113349408]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01962203731924,40.64250143174682],[-74.02022933658131,40.64193209968427]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01317646020486,40.632013765647706],[-74.01372623491201,40.631486114089114]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01832782585751,40.62786195301802],[-74.01863896276912,40.627070526373515]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01926195098474,40.603752157200816],[-74.0192056339431,40.603734632362084]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.026950773583,40.6335159315419],[-74.02722955196661,40.63283606406389]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0353058971767,40.63468854087334],[-74.03537622638888,40.63470530528286],[-74.03573774663447,40.6347914177523]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01857695335988,40.625820029737554],[-74.01869333296156,40.62530520136369],[-74.0189145731069,40.624852267049924],[-74.01919994798754,40.62426799817216]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01752337759615,40.62904448813247],[-74.01772147041561,40.62849657258586],[-74.01782202063335,40.62821780226236],[-74.01794642928571,40.62787288261154],[-74.01799364721093,40.62774210185353],[-74.01801391947357,40.62768595513231],[-74.01807992334412,40.62750315323689],[-74.01830796925623,40.6268715915053]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02037998679783,40.63772499451369],[-74.02011205349368,40.63754353345125],[-74.0199670520607,40.63745229992175],[-74.01988767284934,40.63740166261144],[-74.01983629848256,40.6373688898451],[-74.01969473945587,40.637285120781435]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03744823361973,40.63188111578922],[-74.03736205390018,40.631860377817354]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03144638542759,40.61111981450731],[-74.0319023015974,40.610842074279915],[-74.03192153893677,40.61083035531361]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02334639906894,40.61976973549253],[-74.02374385301852,40.619384609720036],[-74.02390357684486,40.61920092432615]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02104454670462,40.6261793801193],[-74.02111164462688,40.62621990892411],[-74.02140162281016,40.62639461068758]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01816532344843,40.626785705088835],[-74.01849089497125,40.62602192842414],[-74.01851096344352,40.62597484879331],[-74.01857695335988,40.625820029737554]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02097461532125,40.62227607051391],[-74.02109701194306,40.622255417118055],[-74.02120064391093,40.6222449162814]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02135977554988,40.626520547105436],[-74.0214083148503,40.62654973279918],[-74.02134847146614,40.62661423878598]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03528321938438,40.634745343530874],[-74.03303298819965,40.634213598390225],[-74.03259356920195,40.63410974953538]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03209040108409,40.63761348651111],[-74.03173077403736,40.6375014266537],[-74.03126827705228,40.63735730812885]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0211145678175,40.641513578214685],[-74.02114391886154,40.641468366786185],[-74.02115900852569,40.641446908981315],[-74.02115975330344,40.64144585056726],[-74.0212011818474,40.6413869402799],[-74.02134518789724,40.64118218955396]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01370634787972,40.63053961669762],[-74.01367400381903,40.630571642805656],[-74.01346408967055,40.63077917421278]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03649125984288,40.61798915516788],[-74.03876752814024,40.617181129201875]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03535192832503,40.61367299010914],[-74.03364741814288,40.6128332434378]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03573774663447,40.6347914177523],[-74.03583581245265,40.63455337120946]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0211145678175,40.641513578214685],[-74.02115977464882,40.6414770988014],[-74.02118407412732,40.6414574812732],[-74.02124787204221,40.641405995391246],[-74.02146714650722,40.641236189071776]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02956408409668,40.61983253884943],[-74.02984260202672,40.61915381635932]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03232748540657,40.620361849913515],[-74.0324744222498,40.62000389694172]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02137456360131,40.63257860041459],[-74.02173709503862,40.631687882624895]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03515779409116,40.6206379203186],[-74.0324744222498,40.62000389694172]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01379032120737,40.625128059623115],[-74.01383009551134,40.625090242107554],[-74.01383013134316,40.62509020574952],[-74.01436470814582,40.624582111881686],[-74.01442148581089,40.624528145447826]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03191786785239,40.62136707146647],[-74.03205002788695,40.62104063232776]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02120064391093,40.6222449162814],[-74.02161286131559,40.62218380192602]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01973592316727,40.63288491697105],[-74.01852944048841,40.632333576625285]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01935806302573,40.63031045014765],[-74.01955007238033,40.62985508792623]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02740210088201,40.6405441851475],[-74.02837933270364,40.64098216733214],[-74.02889666840994,40.64121402130954]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0277909861234,40.6314633669818],[-74.02508631102368,40.63083190581657]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03498838208205,40.60963566859854],[-74.03504956717764,40.60961546036856],[-74.03509032550566,40.60960201210761]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0269393000037,40.608110048216886],[-74.02695791093063,40.60790666999945]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02120064391093,40.6222449162814],[-74.02136838038557,40.62205285805885],[-74.02176394102796,40.62160025228837],[-74.02205536980986,40.621266790688516],[-74.0221190100875,40.62119397129033],[-74.02222073204432,40.621060530577175]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03942183650594,40.62089997571317],[-74.03809447949352,40.620584898475926]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0321580508527,40.60874549520581],[-74.03214377469678,40.608747821318666],[-74.03212961787013,40.60875053824156],[-74.03211559861565,40.60875364211627],[-74.03210173583585,40.608757129251906],[-74.03208804689376,40.608760994450314],[-74.03207454893302,40.60876523335098],[-74.03206126085507,40.60876984008521],[-74.03204819892376,40.60877480912008],[-74.03203538006179,40.608780133749775],[-74.03202282229054,40.60878580626304],[-74.03201054033498,40.60879182079235],[-74.03199855023757,40.60879816845425],[-74.03198686870059,40.60880484103531],[-74.03197551066799,40.6088118308251],[-74.03196448976348,40.6088191272656],[-74.0319538222496,40.60882672180842],[-74.03194351977228,40.60883460506878],[-74.03193359639462,40.608842765818444],[-74.03192406661961,40.60885119333164],[-74.03191494077409,40.60885987772135],[-74.03190656621747,40.60886845099758],[-74.03189858655827,40.60887723977341],[-74.03189101124393,40.60888623382706],[-74.03188384840283,40.60889542260199],[-74.03187710792155,40.60890479470362],[-74.03187079682915,40.608914339073095],[-74.03186492325354,40.608924043981226],[-74.03185949378441,40.60893389887195],[-74.03185451544971,40.6089438901735],[-74.03183139024388,40.6090681012389],[-74.03232265751944,40.6090844340803]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02080897981277,40.64133958160862],[-74.0208307350269,40.64131226484145],[-74.02086583167788,40.64126820520507],[-74.02090092828253,40.641224145557764]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01663634217223,40.630422018181434],[-74.01622232729382,40.63114506850269],[-74.01549947871922,40.63257449032312],[-74.01514630746092,40.6332219384872]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03724455888974,40.63598546946852],[-74.0372612858999,40.63597335843788],[-74.03727761645419,40.63596093676789],[-74.03729354022126,40.63594821233591],[-74.03730904752926,40.6359351925165],[-74.03732412782739,40.635921885857236],[-74.03733877430271,40.63590829989924],[-74.03735297596488,40.635894443525274],[-74.03736672512139,40.635880324276805],[-74.03738001430033,40.63586595086789],[-74.03739283339114,40.635851332348494],[-74.03740517536205,40.63583647793517],[-74.037417033621,40.635821396509236],[-74.03742839981643,40.63580609661747],[-74.03743926845623,40.635790587810924],[-74.03744963118955,40.63577487980917],[-74.03745948296415,40.63575898216307],[-74.03746881718843,40.63574290442404],[-74.0374776288102,40.63572665631052],[-74.03748591145757,40.63571024687124],[-74.03749366073927,40.635693687834745],[-74.03750087248228,40.63567698791396],[-74.03750754163521,40.63566015800003],[-74.03751366358563,40.63564320747614],[-74.03751923570115,40.635626147232564],[-74.03752425424975,40.635608987992434],[-74.03752871593858,40.635591739306065],[-74.0375326183554,40.63557441239868],[-74.0375359593071,40.635557017155236],[-74.03753873594165,40.63553956480114],[-74.03754094694577,40.63552206555609],[-74.03754259166618,40.63550453014217],[-74.03754366834985,40.635486968779205],[-74.03754417656363,40.63546939252425],[-74.03754411565464,40.63545181276947],[-74.03754348672805,40.63543423872852],[-74.03754228847158,40.63541668229643],[-74.03754052331031,40.63539915352403],[-74.03753819103098,40.635381663468294],[-74.03753529449857,40.63536422234747],[-74.03753183393934,40.63534684071575],[-74.03752781177899,40.63532952962919],[-74.03752323154212,40.63531229930578],[-74.03751809411446,40.63529515979691],[-74.0375124047806,40.63527812249272],[-74.03750616574537,40.63526119694153],[-74.03749938075327,40.63524439336127],[-74.037492054429,40.63522772280722],[-74.03748419073644,40.635211194659604],[-74.03747579451966,40.63519481913593],[-74.0374668717222,40.63517860645342],[-74.03745742652796,40.635162566159735],[-74.0374474655399,40.63514670796921],[-74.0374369947014,40.63513104193152],[-74.03742601995519,40.63511557692357],[-74.03741454834378,40.63510032232455],[-74.0374025860307,40.635085288686625],[-74.0373901418166,40.635070483545526],[-74.03737722208453,40.63505591678322],[-74.03736383497603,40.635041597108405],[-74.0373499888524,40.63502753289461],[-74.03702153643188,40.63469802904157],[-74.03700460569758,40.63468250895053],[-74.03698807813817,40.63466673894223],[-74.0369719605736,40.63465072437552],[-74.03695625872466,40.63463447144732],[-74.03694097897221,40.634617986856874],[-74.0369261272573,40.634601277471134],[-74.03691170908026,40.634584348481866],[-74.03689772950278,40.63456720725887],[-74.03688419534518,40.6345498601662],[-74.03687111078906,40.63453231373628],[-74.03685848067589,40.63451457483639],[-74.03684631094686,40.63449665083603],[-74.03683460512389,40.63447854843535],[-74.0368233684878,40.63446027383136],[-74.03681260434104,40.63444183456192],[-74.03680231840494,40.634423238164146],[-74.0367925133218,40.634404491505954],[-74.03678319371318,40.634385601622185],[-74.03677436266139,40.63436657588326],[-74.03676602434834,40.63434742165918]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03361284109761,40.61721888062908],[-74.03386577352411,40.61659397130616]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01382865141811,40.61954666653489],[-74.01382443341791,40.619550521209966],[-74.01381127096789,40.619562463742945],[-74.01379277931814,40.61958017911898],[-74.01364633698213,40.61972050666225],[-74.01361031061053,40.61975202058846],[-74.01360778129344,40.61975262415912],[-74.01358640367029,40.619757182968534],[-74.013584205888,40.61975775081586],[-74.01357918385516,40.61976164142802],[-74.01355695823683,40.61978023991603],[-74.01355187699741,40.619783824793906],[-74.01354530676937,40.61978679702666],[-74.01353517908844,40.619786690163465],[-74.0134900052414,40.61976024719846],[-74.01331988974692,40.61966045320551],[-74.01315951317373,40.619562540199084],[-74.012746333045,40.61930317375322],[-74.01274460608487,40.61929508716139],[-74.01274914207684,40.619285667686],[-74.01277636534668,40.619256037360614],[-74.01281543850563,40.61921382580213],[-74.01282004687887,40.61920932278388],[-74.01287230709607,40.61915945500788],[-74.01291766777732,40.61911634190754],[-74.01292851467903,40.61910603883872],[-74.01294063760032,40.61909456476633],[-74.01296139762171,40.619074849981835],[-74.01299519054784,40.619042742452066]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01728366756804,40.60513782469659],[-74.01746711446835,40.6049651038237]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02325796263634,40.62797141135196],[-74.0208949241506,40.626542992247636]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03250351930691,40.6105896807567],[-74.03268156207943,40.610360456834215]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03214344715784,40.6062344994004],[-74.03201103903743,40.60613044553264],[-74.03185752160113,40.60600980009411],[-74.03176959006387,40.60594725065846],[-74.03169720187492,40.60589575747256],[-74.031598190028,40.60582532754586],[-74.03133803123663,40.605661521856774],[-74.03132445070521,40.60565297990184],[-74.03103780532813,40.605493701350504],[-74.03074688654625,40.60534075381347],[-74.03051643410384,40.6052259356988],[-74.03027892035315,40.605119565796784],[-74.03025899646005,40.605111591802306],[-74.03003516088447,40.60502200387068],[-74.02972894619475,40.60492296340708],[-74.02954101003515,40.604865972742544],[-74.02931593940608,40.60480994599658],[-74.0292000194711,40.60478302275972],[-74.02913261904898,40.6047687487969],[-74.0290910252045,40.60475994294778],[-74.02892505403933,40.60472900720549],[-74.02874696219389,40.60470200901097],[-74.02850399254433,40.60467401829154],[-74.02848924245147,40.60467245957264],[-74.02815396147442,40.604637020669536],[-74.02786800279416,40.60462299748269],[-74.02757199271478,40.60461798118614],[-74.0274533457444,40.60462190882728],[-74.02662518856422,40.60466116591291],[-74.02656959187361,40.604663801111535],[-74.02572580373418,40.60472316652282],[-74.0252925858794,40.604758626051144],[-74.0248564726474,40.604791545669556],[-74.02476319653067,40.60479530639359],[-74.02441884091007,40.60480919033084],[-74.02397309958461,40.60481756027349],[-74.02361227920397,40.60480322646427],[-74.023251938203,40.60477514047224],[-74.02290026223164,40.60473412424404],[-74.0228934475248,40.60473332900095],[-74.02253814341414,40.604677927504135],[-74.0221873487262,40.604609159574586],[-74.02183129712743,40.6045420938355],[-74.0214386477098,40.60441599607948],[-74.0213239486635,40.60438827192331],[-74.02111274529972,40.60432406569492],[-74.02055355979304,40.60415406976462],[-74.01937852416526,40.603788432611694],[-74.01926195098474,40.603752157200816]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04066167213976,40.62668935722538],[-74.04067072092182,40.62664805602255],[-74.04067928548417,40.62660669501487],[-74.04068736363062,40.626565277051235],[-74.04069495536451,40.6265238061524],[-74.0407020602485,40.62648228483159],[-74.04070867696629,40.62644071643989],[-74.0407148055211,40.62639910483059],[-74.040720445916,40.62635745352181],[-74.04072559661414,40.62631576485965],[-74.04073025805877,40.626274043032154],[-74.04073442937313,40.62623229105526],[-74.04073811078005,40.6261905122795],[-74.04074130074348,40.62614871022355],[-74.0407440008057,40.62610688857258],[-74.04074620964971,40.626065049504945],[-74.04074792683933,40.626023197376554],[-74.04074915281699,40.62598133503528],[-74.04074988824527,40.625939465831465],[-74.04075013136867,40.62589759395399],[-74.04074988240897,40.625855721078025],[-74.04074914290945,40.62581385239642],[-74.04074791199301,40.625771990422436],[-74.04074618878275,40.62573013783681],[-74.04074397526134,40.625688299329624]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02730164954356,40.61872254016571],[-74.02687300482306,40.61850920005682],[-74.02684890381747,40.6184972015774],[-74.02635995559174,40.61825384993942]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0341899573684,40.615804884024065],[-74.03453827136116,40.61493893814984]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01582540206918,40.622573607188805],[-74.01362246814824,40.62124382115554]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03607664215738,40.60940692063411],[-74.03611335567324,40.60939472840671]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02415343468138,40.62578041492029],[-74.02349157152236,40.625380505408465],[-74.02179439170388,40.624354993982585]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03250351930691,40.6105896807567],[-74.03265265152646,40.61053783149366]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0360710950868,40.62559887321421],[-74.03339135330052,40.624966792257844]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02708885108355,40.61820715086158],[-74.02687698036772,40.618463254512605],[-74.02684890381747,40.6184972015774]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02149533368774,40.62007384181899],[-74.02190145687003,40.62031969744178]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03259356920195,40.63410974953538],[-74.03272550673316,40.633790235259916],[-74.03274235473312,40.63374942754122],[-74.03287451463889,40.633429345431814]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03588456102733,40.63604999164928],[-74.0359572689164,40.6360673401362],[-74.03620699248872,40.63612704700887],[-74.03622084604173,40.636148340044585],[-74.03621078843503,40.63617299905535],[-74.03612998070008,40.63636817610464],[-74.03611907119583,40.636393024849184],[-74.03609452612885,40.63644918928899]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02897939713604,40.61045523894107],[-74.02986842685246,40.609415116254716]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03487149024217,40.611366235710996],[-74.03502693478693,40.6112969202477],[-74.03566523550579,40.610677006337596]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02937876997252,40.64137266952767],[-74.02959936599987,40.6414297687984]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03649125984288,40.61798915516788],[-74.03622076800592,40.6179062668591]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02195278042983,40.637452235497214],[-74.02024573669517,40.63640957692435]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01892465780084,40.63682599451224],[-74.01899546812677,40.63675410355976]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02725383807237,40.60614638745412],[-74.0268895184541,40.60606688189295]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02933540742167,40.613648819912726],[-74.02947541241734,40.61351297661177],[-74.02960442451446,40.613370346022776],[-74.02972164016325,40.61322172080208],[-74.02982635105357,40.61306796612114],[-74.02991804940461,40.612909999702005]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03598944354782,40.61859585874571],[-74.03552904809666,40.61848392332558],[-74.03430435417751,40.6181861598184],[-74.03414129798401,40.618146513742104],[-74.03331256633761,40.61794500424376]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03331256633761,40.61794500424376],[-74.03358936495485,40.61727619660071]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02222073204432,40.621060530577175],[-74.02215192377125,40.62101947082425],[-74.02207654556122,40.620974567338685]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02318505145092,40.61967585283674],[-74.02351750285276,40.61927778224577],[-74.02367769684693,40.619085965218645]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0208949241506,40.626542992247636],[-74.01926375737048,40.62557626279814]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02916023122874,40.640774915867915],[-74.02939371574907,40.6405483489308],[-74.02971318724587,40.64023833552328],[-74.03032234460834,40.63964722023463]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02030304230694,40.620705247605486],[-74.01873294617045,40.61977703674513]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01989460071066,40.618656476704864],[-74.01769159650473,40.6173259484068]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02003020820511,40.63007499298579],[-74.02000005594016,40.63011353182864],[-74.01978998003511,40.63038214788728],[-74.01978998641727,40.63040367045535],[-74.01978230208664,40.63047999061228],[-74.01963160909997,40.63067252055742],[-74.0195988799454,40.63071433742979]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01652978734877,40.618447035351615],[-74.01711102761195,40.61788751993068]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0196317127963,40.62487969357479],[-74.02007423343322,40.62424643447731]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01995754838745,40.62883781837441],[-74.02027718520742,40.62806209037222]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03595784256667,40.638821144636054],[-74.03602236066493,40.63864135348739],[-74.0360692038621,40.6384578761867],[-74.03609788820769,40.638272243280085],[-74.03610824954124,40.63808602155898],[-74.03607030710799,40.63730595025948]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02714345396993,40.62813104143074],[-74.02712893112133,40.62816783984876],[-74.02710703856661,40.62821799505242],[-74.02708901888857,40.62825972013466],[-74.02703107915761,40.62840324066377],[-74.02702956743896,40.628407005220595],[-74.0270292614001,40.628410904522056],[-74.02702695121262,40.62845467963323],[-74.0270270719453,40.62846123516873],[-74.02703235854955,40.62846864539365],[-74.02791036269075,40.62867958905796],[-74.02792922825824,40.628683988134874],[-74.02808809296432,40.62870825449088],[-74.02809751362805,40.628709585214516],[-74.0281069098199,40.628709195256555],[-74.02812393953339,40.62870303173367],[-74.02812831132374,40.62870049997636],[-74.02814308148292,40.62869066293252],[-74.02814397971353,40.62869014069336],[-74.02815124816324,40.62868787828226],[-74.02815707453897,40.628687021621744],[-74.02816028929342,40.628686579396394],[-74.02816377595121,40.62868643413266],[-74.0282163268309,40.62868975339275],[-74.02823752094608,40.62869297227836],[-74.0282443291486,40.628693249541264],[-74.02828492869475,40.628692600606136],[-74.02829020008411,40.628692274806184],[-74.02830150818225,40.62868464477862],[-74.02830843110327,40.62867648392626],[-74.02832975053659,40.62864236699309],[-74.02836909341127,40.62854861344997],[-74.02839187084184,40.628468011465905],[-74.02840315306487,40.62842811524747]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04032273625293,40.62258947065583],[-74.03936059776535,40.622327654570654]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0218300638167,40.617643463399624],[-74.02160848456943,40.61753673829377]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01926375737048,40.62557626279814],[-74.01945860324523,40.625207413022146],[-74.0196317127963,40.62487969357479]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01676837217506,40.63889900814065],[-74.01456685527899,40.63757090781398]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02462461252911,40.617389023513944],[-74.02371677165152,40.61693704497811]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03869172982165,40.62296928612613],[-74.03728235187485,40.62263792793432]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02872088069836,40.64075095578599],[-74.02686129357187,40.639536290563555]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03049069960784,40.612173353320536],[-74.03065092930589,40.61194040727508],[-74.03067616192742,40.61190568821078],[-74.0307018562561,40.61187116670168],[-74.03072800833544,40.61183684475882],[-74.03075461684838,40.61180272757569],[-74.03078167871833,40.611768818335825],[-74.03080919020897,40.61173511972036],[-74.03083714978288,40.611701635582556],[-74.0308655530446,40.611668369273865],[-74.03089439867658,40.611635324647466],[-74.03092368250314,40.61160250488721],[-74.03095340210749,40.61156991351151],[-74.03098355463288,40.61153755353634],[-74.03101413678345,40.61150542898293],[-74.03104514460303,40.61147354202989],[-74.03107657589506,40.61144189703323],[-74.03110842670368,40.611410496841664],[-74.03114069461198,40.61137934447101],[-74.03117337544438,40.61134844293759],[-74.03120646612517,40.61131779659764],[-74.03123996401696,40.6112874071268]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03468801069191,40.61724546903249],[-74.03470587222623,40.61725524330595],[-74.0347276659357,40.617260324408015],[-74.03474856233366,40.61726518078594],[-74.03476831141563,40.617269740645945],[-74.03477536654331,40.61727016168975],[-74.0347922304968,40.617270787333055],[-74.03479753725233,40.617271352811954],[-74.03488298805706,40.61729114758776]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03274647058772,40.607738290570644],[-74.03262578335463,40.60756777549016],[-74.03249188862115,40.60740249544351],[-74.03234539093644,40.607243342474305],[-74.03218706954219,40.60709112698944],[-74.03201776386052,40.60694660426244],[-74.03045457227749,40.6059598863394],[-74.03011289140728,40.606063644682735]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03499884243531,40.635426240975704],[-74.03456924818023,40.63532453117172],[-74.03453322629281,40.635316005076504],[-74.03275116698742,40.634894075109415],[-74.0323165198636,40.63479116049515]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03021113041939,40.62014827316605],[-74.02956408409668,40.61983253884943]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03441229625331,40.61747324841155],[-74.03442913792716,40.61743186441147],[-74.03452255511358,40.61720230259361]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01932871294058,40.63708062104839],[-74.01892465780084,40.63682599451224]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03444160139642,40.636799673550165],[-74.03395609717417,40.636649098406764],[-74.03283896605629,40.636302614552854],[-74.03280047149336,40.63629067589831],[-74.03250380538073,40.63619865497107]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0212304808349,40.64158837204826],[-74.0212596485647,40.64156089132939],[-74.0212909428982,40.6415304305489],[-74.02135630903751,40.64146843559427],[-74.02156171055366,40.641277838378656],[-74.02182969955204,40.641029145817654]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02082094366662,40.63861280019888],[-74.02095154473442,40.63848106140499],[-74.02101999757603,40.63841201143376]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03243461722793,40.63585686455287],[-74.03298781199574,40.63598566159275]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02056295535992,40.64214110540959],[-74.02075868686609,40.64193812013328],[-74.02085372446696,40.641830373962],[-74.02094273457377,40.64172875247475],[-74.0210589565097,40.641583207190735],[-74.0211145678175,40.641513578214685]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03566523550579,40.610677006337596],[-74.03572204134257,40.61062109533599],[-74.0357579567263,40.610585886666165]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0169877795685,40.62145382444481],[-74.01756994176787,40.62089820597792]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02209239738764,40.62362809124284],[-74.02131059901643,40.62315887906735],[-74.02113216418589,40.623051786081625]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02072169389994,40.64174105727264],[-74.02096223540929,40.64152371893668],[-74.02103195990938,40.6414595781705],[-74.02106239559585,40.64143086593548],[-74.02108950719536,40.64140467409692],[-74.02114153316319,40.641362394275816],[-74.02134518789724,40.64118218955396]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0293562464355,40.63483669220852],[-74.0266796143697,40.634197255531234]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01919994798754,40.62426799817216],[-74.01937999454046,40.62426803983217]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01556266734983,40.64006663684698],[-74.01335669051925,40.638735308633656]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01428474526321,40.62724714740842],[-74.01500072034628,40.62676890709503]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03165800059992,40.62919908300082],[-74.0319567238525,40.62847059683122]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03411074911207,40.61229599133894],[-74.03432894277553,40.612042924837105]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01459842402548,40.60356948577957],[-74.01490256804487,40.603203567582774]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03470524300107,40.63800139985099],[-74.03455115429618,40.637956735245076]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01651620384442,40.60467228684249],[-74.01698622944993,40.60421699545783]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03752544637754,40.619696001852745],[-74.03571148771276,40.619274919844784]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03857697726073,40.62911341929082],[-74.03883161439232,40.62849685557941]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02348203738586,40.639533212305636],[-74.02351787245728,40.63944477391463],[-74.0235493915473,40.639320333692275]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02927464974715,40.627832923455216],[-74.02656062871394,40.62718718062923]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02134518789724,40.64118218955396],[-74.02141800360549,40.64112624480805],[-74.02152224680053,40.64104974476635],[-74.02163305222066,40.64097898811244]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03123996401696,40.6112874071268],[-74.03144638542759,40.61111981450731]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01852040600959,40.63721694821191],[-74.01870014955308,40.63704142079197]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01420288350761,40.62068474388309],[-74.01478487192244,40.620124798828]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02708033873293,40.60741244519307],[-74.02797552206145,40.607603848139874],[-74.02817376375437,40.6076111388283],[-74.02836941726375,40.60756642796844],[-74.02852968361967,40.60747720003638],[-74.02859910853813,40.60704255318637],[-74.0286700336546,40.60699232053274],[-74.02875935630321,40.606957173578024],[-74.02885790361836,40.606942016314875],[-74.02895446719153,40.606947408075264]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02323533366493,40.635318753152525],[-74.0207219318318,40.634169009418805]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02923285748857,40.64124676939708],[-74.02949037963523,40.64132096933019]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02161286131559,40.62218380192602],[-74.02138412390502,40.62239114462523],[-74.02044203091212,40.623431011499804],[-74.020362968152,40.62352096082311],[-74.0200429824302,40.62388498898552],[-74.01993043247799,40.62404204127533],[-74.01989103345402,40.624097025164914],[-74.01976701060362,40.624265965941355]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03299421803494,40.631921022477414],[-74.03263386385349,40.631834450377944]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02537316768615,40.61940388362679],[-74.02490366228277,40.6191699411672],[-74.02454267884777,40.61899006805416]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03016550866239,40.63805212775785],[-74.02995077059654,40.63798558160032],[-74.02920569966861,40.637754663849144],[-74.0282796052702,40.6374676390882]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02664722173601,40.61650772129021],[-74.02628975684716,40.616329300249824]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02295953768112,40.62870131512131],[-74.02325796263634,40.62797141135196]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02613488275219,40.61624944121495],[-74.02618518216887,40.61618484822586],[-74.02630373789869,40.61603260258153],[-74.02645501145544,40.61585543539785],[-74.02661661073996,40.6156432261181]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02923285748857,40.64124676939708],[-74.02933160051806,40.6413177320781],[-74.02937876997252,40.64137266952767]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03487286562138,40.63770451093108],[-74.03489342702811,40.63766754773993],[-74.03501216424628,40.6374541247366],[-74.0350366952782,40.637414025851776]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03819614582365,40.62759933171589],[-74.03551433094704,40.62696173171024]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01574804402502,40.63176426870878],[-74.01544127093105,40.63158075744509],[-74.0147047735744,40.631140203018205],[-74.01432214759274,40.63091131175038]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03011289140728,40.606063644682735],[-74.02912096649753,40.60584475353096],[-74.02893798474447,40.60596168694237]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03996649261121,40.619150841936026],[-74.03957464140895,40.618500963440496]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0207219318318,40.634169009418805],[-74.02101222340077,40.63346837978414]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01913887209786,40.60371321100139],[-74.01912316599487,40.60373977015788],[-74.01910090435524,40.60377437196514]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03551433094704,40.62696173171024],[-74.03578883570226,40.62628504978484]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01640635137058,40.63306292322013],[-74.01641801558006,40.63300602701011],[-74.01649175180819,40.63281917653218],[-74.01668903337765,40.63230494271675]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02145207558851,40.618027191687425],[-74.0218300638167,40.617643463399624]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03623337455562,40.6300699480701],[-74.03613434436348,40.63004112661664]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01918487143968,40.63657561589338],[-74.01697745739544,40.635235081662316]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0360945834937,40.61255854482404],[-74.03487149024217,40.611366235710996]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02574989060072,40.61605822319546],[-74.0250464409755,40.61570811896232],[-74.02483452438825,40.61560252541747]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0196604336372,40.62957688094767],[-74.01982886126855,40.62916817814316]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03187955888912,40.610803136471155],[-74.03168478453624,40.61067684567532]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0190540606447,40.63669904500444],[-74.01898634254977,40.63665861448975],[-74.01805283070652,40.636101252910606],[-74.0176043718909,40.63583349929484]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.030665964162,40.63639172695867],[-74.03113030156125,40.63525421064371]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02056295535992,40.64214110540959],[-74.02045920302128,40.64208105643792]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02180154239164,40.62060316560633],[-74.02227378599942,40.620109058620585]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01870014955308,40.63704142079197],[-74.01878323392015,40.63696028509285]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03135989933355,40.62993051264942],[-74.02867799741152,40.62929432896287]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02985647055807,40.63908971410578],[-74.03040594826037,40.6392638206706],[-74.03047261891031,40.63928530731089]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0265998440278,40.63978656061281],[-74.02890071646947,40.64100808061095],[-74.02923285748857,40.64124676939708]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02276245172874,40.630828255763255],[-74.02258069337678,40.630747487694656]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0213751886626,40.63799853610025],[-74.02183419266981,40.63756450786067]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03415742094354,40.63748330644836],[-74.03242972118488,40.63694608860652],[-74.03214569081936,40.63685776473933]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03339135330052,40.624966792257844],[-74.03374211670423,40.62409897210223]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02959936599987,40.6414297687984],[-74.03005683854005,40.64152123323449]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01887440764712,40.63687170404401],[-74.01858099034033,40.636713008189396],[-74.0185209888438,40.636676006634715],[-74.01797699184934,40.636378967090174],[-74.01785371684261,40.63630912372509],[-74.01766995731853,40.63620501605228],[-74.01740512592319,40.63603462432564],[-74.0173593075988,40.636005086928],[-74.01685207527018,40.63564832194874],[-74.0166954641309,40.635521475108796]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0235186645925,40.634615786682204],[-74.02388334141075,40.633724386739026]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02008667268495,40.622420952159324],[-74.02058200561427,40.622343014433035]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02695791093063,40.60790666999945],[-74.02630048131157,40.60776716929199],[-74.02619259951591,40.607850269052726]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0205066797487,40.634706342881785],[-74.0207219318318,40.634169009418805]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02027718520742,40.62806209037222],[-74.01863896276912,40.627070526373515]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03105991786607,40.62346289800923],[-74.03135988374659,40.62272872165521]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01711050334977,40.635641455823546],[-74.01700518714767,40.63556282551674],[-74.01679830913133,40.635408366648136]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01746711446835,40.6049651038237],[-74.01750868597117,40.604850497235226],[-74.0180470260697,40.6043657351263],[-74.01811904973285,40.60431522232409],[-74.01817646660614,40.60425260881735],[-74.01821458630181,40.604181957281035],[-74.01823145051426,40.60410847200049]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02924131468855,40.613606654745],[-74.02991804940461,40.612909999702005]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03612991330351,40.632663269752406],[-74.03393562519746,40.63214399641737],[-74.03344733644003,40.63202844056258]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01873294617045,40.61977703674513],[-74.01931290379294,40.61921695210262]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02800411516877,40.63814423931867],[-74.0282796052702,40.6374676390882]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01659362914246,40.642511031200556],[-74.01439632401156,40.64118583630968]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03448084402132,40.63489555062494],[-74.03504481887747,40.63503213266631],[-74.03507422139327,40.63504086802115],[-74.035150405857,40.63506335741025]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02986842685246,40.609415116254716],[-74.03039492080207,40.608721072630324]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02200366499811,40.618938675789984],[-74.0227329117209,40.618088109472126]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01664336539812,40.62957607819243],[-74.01606909467468,40.6292336382119]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02676711059985,40.61657486832318],[-74.02694376836668,40.616340126312195],[-74.02718246490011,40.61601711616431]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03374211670423,40.62409897210223],[-74.03404330705281,40.6233631942251]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0228759874347,40.619466147406214],[-74.02200366499811,40.618938675789984]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.031547580922,40.63667258539087],[-74.03107191835245,40.636521049503266],[-74.030665964162,40.63639172695867]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01275595716372,40.622541678141495],[-74.01278948008404,40.62250901250818],[-74.01330118974086,40.62201054364687],[-74.0133330454533,40.62197951681244]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02595819003183,40.62864726756076],[-74.02355676027709,40.627242523740215]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02067901763246,40.622325950302134],[-74.02097461532125,40.62227607051391]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01570811714437,40.626295049370796],[-74.01379032120737,40.625128059623115],[-74.01340877238549,40.6248958784662]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03770067568371,40.61995529454051],[-74.03752544637754,40.619696001852745]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02367769684693,40.619085965218645],[-74.02400392302262,40.61871615323999],[-74.02411845764121,40.61858631536635],[-74.02429696747419,40.618383952535886],[-74.0244850334826,40.6181579812354],[-74.02449182643193,40.61815021683707],[-74.02498256212598,40.61758693304521],[-74.02499393805607,40.61757189184281],[-74.02524348876071,40.61727645044505],[-74.02562198968278,40.61683974931274],[-74.02613488275219,40.61624944121495]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02920034571171,40.640189298467135],[-74.02924678569751,40.640145485850454],[-74.02937062544534,40.64003267329858]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03263720326892,40.61400991276134],[-74.03316279012168,40.6134020726199]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03006728396737,40.621675620451484],[-74.03008369331855,40.62163501137069],[-74.03010336020446,40.62158629722967],[-74.03017213668505,40.62141601819059],[-74.03019181597391,40.62136730386249]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01356337940096,40.60258487627696],[-74.01262197243585,40.60235826756745]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02566164211383,40.62214065420595],[-74.02621402560658,40.621491677902604]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02822505661118,40.60944585664699],[-74.02772006930651,40.60992407107728],[-74.02740487240644,40.6100459507822]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01609854581004,40.60392061821091],[-74.0157345210512,40.60383805802677],[-74.01515631643922,40.60369719971753]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02039290347214,40.642038985078656],[-74.02072169389994,40.64174105727264]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03453827136116,40.61493893814984],[-74.0338176525864,40.61458678736568],[-74.03263720326892,40.61400991276134]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03310842055332,40.625647051398644],[-74.03339135330052,40.624966792257844]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02710660556804,40.61024395632412],[-74.02497932521149,40.60974197468559]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02913396937063,40.63537274692008],[-74.02831656444577,40.63525568567155]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02395564987297,40.64232680143745],[-74.02182969955204,40.641029145817654]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03358936495485,40.61727619660071],[-74.03361284109761,40.61721888062908]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01922137397284,40.60381610950833],[-74.01908372828288,40.604020455095494],[-74.01907512106538,40.60403459832363],[-74.01906606847471,40.60404857845165],[-74.01905657666323,40.604062388609755],[-74.01904664958462,40.60407601975062],[-74.01903629405052,40.60408946450174],[-74.01902551555357,40.604102714820634],[-74.0190143209054,40.60411576316731],[-74.01900271691764,40.60412860200168],[-74.01899070886311,40.60414122294631],[-74.01897830509253,40.60415361996864],[-74.01896551263717,40.60416578469095],[-74.01895233830928,40.604177711415964],[-74.01893879067872,40.60418939159818],[-74.01892821877223,40.60419724894545],[-74.0189180417165,40.60420540392592],[-74.0189082746746,40.604213844140034],[-74.01889892885332,40.60422255819408],[-74.01889002029486,40.604231533353285],[-74.01888155998608,40.604240757386385],[-74.01887355979267,40.604250216721624],[-74.01886603158064,40.604259898792485],[-74.01885898677601,40.60426978952474],[-74.0188524330681,40.60427987484478],[-74.01884638144342,40.604290140845976],[-74.01884083981089,40.604300572617],[-74.01883581695884,40.604311155749016],[-74.01884666051637,40.604372398075654]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02722013300452,40.6203223521233],[-74.02771303825047,40.61974854921492]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03272550673316,40.633790235259916],[-74.03265270636416,40.633769445055925],[-74.03060620637963,40.6332924894379],[-74.0305744545272,40.63328672568839],[-74.03054271868446,40.63328998501478],[-74.03050152894822,40.63337710293209],[-74.03048759703711,40.63341248799098],[-74.03044810374477,40.63351322165759],[-74.03044529409426,40.63352050771641],[-74.03043419679932,40.633551398231376],[-74.03041897969426,40.63359397897338]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02059936527971,40.62727660878118],[-74.01896027313887,40.6262956399302]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02268668861555,40.622178102265764],[-74.02283833914143,40.62178924567171],[-74.02277383473061,40.621581553445516]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03642076105058,40.63898596440511],[-74.03595784256667,40.638821144636054]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0197189447665,40.64254997093113],[-74.01993770878927,40.64233180068142],[-74.01994280019363,40.642326723017916],[-74.02029670597527,40.64197377625254]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03070775574493,40.62432825728102],[-74.02799029442514,40.623682495139576]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01962203731924,40.64250143174682],[-74.0178857873427,40.64147118903415]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03667838248343,40.63905846791726],[-74.03650777979973,40.63901179097763]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02026153192729,40.63918045222296],[-74.02019620621383,40.639138724334174],[-74.02012056882756,40.6390869490181]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01621596169294,40.6328196389354],[-74.01625099128185,40.63269836105971],[-74.01635195664252,40.63234884627835],[-74.016385640441,40.63224561321813],[-74.0165046283751,40.63188094174945],[-74.0165202760718,40.63183797914047],[-74.01658124076424,40.63167059656832],[-74.01667381154517,40.63141642940025],[-74.01699572995919,40.630582212938066]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03485670659863,40.63847431543151],[-74.033880137792,40.63816726910346]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03268156207943,40.610360456834215],[-74.03281702885371,40.61032280362599],[-74.03295222200916,40.61028113349408]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01762387638252,40.60360675051379],[-74.01604929666969,40.60318110834597],[-74.01536645243371,40.602996512077965],[-74.01452089665703,40.60281266301773]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03265265152646,40.61053783149366],[-74.03278399911363,40.61048532955953]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0391088652061,40.625371381658674],[-74.03642583101983,40.62473459544902]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03446423136421,40.60851882869996],[-74.03437841050534,40.60846996524843]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03505731294625,40.6097408281576],[-74.03511482326047,40.6097196305825],[-74.03515733062534,40.60970591170685]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02062866059715,40.64217589850549],[-74.02092794693945,40.641883383220126],[-74.02116984138752,40.64164695250149],[-74.0212304808349,40.64158837204826]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0229999167796,40.63094161046602],[-74.02276245172874,40.630828255763255]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03366364805419,40.608484549127326],[-74.03356909800601,40.608463765657184],[-74.0335599517596,40.60845975935892],[-74.03355108209244,40.608455408036974],[-74.033542508794,40.608450723077596],[-74.03353425605025,40.608445716200826],[-74.03352634299159,40.60844039963075],[-74.033518789848,40.608434786596376],[-74.03351161641079,40.6084288923371],[-74.03350483961313,40.60842273108806],[-74.03349847748757,40.60841631775413],[-74.03349254608962,40.60840966992123],[-74.03348705971514,40.60840280299797],[-74.03348203288105,40.608395734905756],[-74.03347747768615,40.60838848339921],[-74.03347340557022,40.60838106707079],[-74.03343037295448,40.60823774646437],[-74.03340235428969,40.60814191779581],[-74.03339889964127,40.60813006126366],[-74.03339489835824,40.608118304905055],[-74.0333903546247,40.608106663293725],[-74.03338527438326,40.608095151002914],[-74.03337966467586,40.6080837831081],[-74.03337353232371,40.60807257284204],[-74.03336688348915,40.608061534777875],[-74.03335972829036,40.60805068164478],[-74.0333520748684,40.608040028685465],[-74.03334393334086,40.60802958762388],[-74.03333531272732,40.608019372362264],[-74.03332622468452,40.60800939546178],[-74.03331668020941,40.60799966898123],[-74.03330669161821,40.60799020564912],[-74.03329627078654,40.60798101635131],[-74.03328543025025,40.607972113648685],[-74.03327418496194,40.607963507588565],[-74.03326254811633,40.607955209559],[-74.03325456441506,40.60795133457763],[-74.03324630963353,40.60794780662668],[-74.03323780861561,40.607944635080614],[-74.03322908796473,40.607941831323565],[-74.03322017604128,40.607939403723805],[-74.03321109922659,40.60793735914232],[-74.03320188654031,40.607935705612086],[-74.0331925674396,40.60793444681022],[-74.033183170063,40.607933587084304],[-74.03317372452665,40.60793312927364],[-74.03316425984694,40.607933074877586],[-74.03315480613846,40.607933423552424],[-74.0331453928563,40.607934174954565],[-74.0331360498939,40.607935326059895],[-74.03312680560602,40.607936874012275],[-74.03311768988493,40.60793881344218],[-74.03310872976515,40.60794113864584],[-74.0330999549178,40.60794384157341],[-74.03309139215654,40.607946914343295],[-74.03308306807423,40.60795034723123],[-74.03297346975809,40.60799788509587]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01965977575708,40.63974211959376],[-74.01960300625424,40.639709034877946],[-74.01952692715224,40.63966502201572]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02200366499811,40.618938675789984],[-74.02121548264651,40.61847198527922]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03569291352058,40.61071640424595],[-74.03566523550579,40.610677006337596]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01995754838745,40.62883781837441],[-74.01970122546571,40.62870221714901]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01889421954473,40.63144343450422],[-74.01906269284504,40.63103852457284]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02566120770801,40.62005685017528],[-74.02557995053986,40.620158140619374]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01697745739544,40.635235081662316],[-74.01750512326755,40.63474754258663]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02762394706329,40.63880495150758],[-74.02780166452438,40.63862547161211],[-74.02800411516877,40.63814423931867]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0227329117209,40.618088109472126],[-74.02292884091298,40.617858888091604],[-74.02296236568002,40.61781966373571],[-74.02371677165152,40.61693704497811]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0383518812977,40.62966281148568],[-74.03857697726073,40.62911341929082]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0319567238525,40.62847059683122],[-74.03225653845509,40.627740290327054]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02839765193403,40.61744349936352],[-74.02957542681239,40.616066234228235]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01524185216765,40.62313302617248],[-74.0133330454533,40.62197951681244],[-74.01304073202043,40.621802868641495]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02163305222066,40.64097898811244],[-74.02174752152138,40.640795350672946],[-74.02181730471531,40.6406516870179],[-74.02184087288579,40.640603162289054],[-74.02191158398422,40.64040460267926],[-74.02195868569102,40.640202021823875],[-74.02198174115127,40.63999786072468],[-74.02199264617141,40.63980018579424]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01604820400777,40.63103288814215],[-74.01634322391006,40.630285595428546]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0368949794848,40.618662894987246],[-74.03649125984288,40.61798915516788]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04137844996096,40.62053853911515],[-74.04139881805321,40.62067922917478],[-74.04141498112595,40.62079569976448]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01976701060362,40.624265965941355],[-74.01927505769753,40.62496896832612],[-74.0192618264208,40.624989592825905],[-74.01914099758676,40.62517800155709],[-74.01901086964173,40.62542217178294],[-74.0187756079456,40.625863636347496]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02149466602913,40.625083859316064],[-74.02179439170388,40.624354993982585]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03134204356986,40.61111384128102],[-74.02999806839702,40.61203416771512],[-74.02977001731122,40.612186010238865],[-74.02955260385633,40.612347133021736],[-74.02934679718919,40.61251688050303],[-74.02915343608798,40.612694494295916]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03283230942773,40.62632904897046],[-74.03062372750874,40.62580375505145],[-74.03014945024137,40.6256909459527]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01514630746092,40.6332219384872],[-74.01542409868877,40.63251313909726]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03268156207943,40.610360456834215],[-74.03287382809454,40.610104185365195],[-74.03309092156645,40.60982822176678],[-74.03321587179305,40.60967435860072],[-74.03332762000366,40.6095142762607],[-74.03342543409812,40.60934897548099],[-74.03350871150587,40.60917952715042],[-74.03357880210949,40.609034081306305],[-74.03363000697416,40.60888157205835],[-74.03366072000146,40.60872419687724],[-74.03366993842347,40.608564387756495],[-74.03366364805419,40.608484549127326]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02552760871232,40.61784137421778],[-74.02607424630311,40.6171524523089]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01999892578114,40.62145136823829],[-74.01815162013094,40.62033644283249]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01824460047568,40.633033568464015],[-74.01852944048841,40.632333576625285]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04141498112595,40.62079569976448],[-74.04143512171842,40.6209408320896],[-74.04148170770321,40.62144341424252],[-74.04151388603327,40.62175710648324],[-74.04155265788445,40.622231065241586],[-74.04156344360472,40.622438090053805],[-74.04157611001251,40.62270530073399],[-74.04158773575506,40.62306579849891],[-74.04160217050094,40.62336114380131],[-74.04169641605249,40.62366514687486],[-74.04175071867652,40.62390401395192],[-74.04177652035975,40.624142891022686],[-74.04178514838702,40.624266674540664],[-74.04177951735262,40.62437743335631],[-74.0417710143615,40.62445344574309],[-74.04175112486101,40.62455335068962],[-74.04172839662422,40.62467063073211],[-74.0416772318318,40.62489433382386],[-74.04158623264674,40.625228807894864],[-74.04156920569933,40.62534825750975],[-74.04153013801472,40.62597228929763],[-74.04152122986005,40.626117054911866],[-74.04150141847275,40.626342918237526],[-74.04148447142089,40.62659266961105],[-74.04145049732989,40.62696186988203],[-74.04140517462307,40.6274179423635],[-74.04137114044103,40.62769158826128],[-74.04132858163585,40.62800867119272],[-74.04129450721133,40.628219337843895],[-74.04121215458893,40.62871885713028],[-74.04116267446909,40.62901940837252],[-74.04112122814345,40.6291836324468],[-74.04101886007525,40.62958543270623],[-74.0409486735115,40.62985345229276]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02708033873293,40.60741244519307],[-74.02737016000603,40.60692858370878]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03707918142358,40.613826740723496],[-74.03705767225796,40.61378643919641],[-74.03703568901449,40.613746286080996],[-74.03701323477341,40.613706284726575],[-74.03699031107597,40.61366643814785],[-74.03696691858467,40.6136267505326],[-74.03694306015912,40.61358722388995],[-74.03691873778057,40.613547861904614],[-74.03689395321008,40.6135086677588],[-74.03686870842864,40.61346964480212],[-74.03684300563661,40.61343079554653],[-74.03681684615573,40.61339212384446],[-74.03679023306591,40.61335363271013],[-74.03676316768814,40.61331532465573],[-74.03673565288271,40.613277203198166],[-74.03670769041027,40.61323927084947],[-74.03667928269186,40.61320153196427],[-74.03665043214731,40.613163988551875],[-74.03662114141669,40.613126643459076],[-74.03659141160162,40.613089500370805],[-74.0365612462213,40.61305256179856],[-74.03653064725633,40.61301583075687],[-74.03649961756662,40.612979310260066],[-74.03646815957268,40.612943003825066],[-74.03643627503457,40.6129069132938],[-74.03640396725227,40.61287104251806],[-74.03637123820575,40.61283539350721],[-74.03633809163449,40.612799969945314],[-74.0363045295186,40.61276477417683],[-74.03627055405856,40.61272980955124],[-74.03623616877324,40.612695078412536],[-74.03620137674204,40.612660583439805],[-74.03616617928601,40.61262632798284],[-74.03613058080325,40.6125923142178],[-74.0360945834937,40.61255854482404]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01652978734877,40.618447035351615],[-74.01432761381442,40.61711734341869]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03567143483521,40.61814305017874],[-74.0357938461805,40.61784200383465],[-74.03580789073297,40.617807410616656]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01566220606678,40.63080357912659],[-74.01562155478064,40.63084471142277],[-74.01552224407676,40.63094544776286],[-74.01549621406863,40.63098710943997],[-74.01549968181156,40.63100430008801],[-74.01542906057333,40.63112021542459]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0157345210512,40.60383805802677],[-74.01583337707719,40.603601381985456]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03219532767785,40.62068747034614],[-74.03232748540657,40.620361849913515]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03225653845509,40.627740290327054],[-74.0295728483016,40.627103552092244]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01475422595298,40.633961648996596],[-74.01560205035204,40.63351697794145]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03165800059992,40.62919908300082],[-74.02897576006832,40.628564077168186]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02545703087748,40.62000193724366],[-74.02511091221538,40.61983122026371],[-74.02503214302747,40.619792361880165]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0265998440278,40.63978656061281],[-74.02650036803593,40.639673316086004]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0262631546062,40.627919956893415],[-74.02656062871394,40.62718718062923]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03374211670423,40.62409897210223],[-74.03105991786607,40.62346289800923]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02961387813355,40.60631093111242],[-74.03011289140728,40.606063644682735]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03483935692643,40.609682730039026],[-74.03498838208205,40.60963566859854]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03879672709583,40.63132927188658],[-74.03693147508545,40.63069200317246]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0291039543851,40.60655740829638],[-74.02961387813355,40.60631093111242]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04021916085469,40.62270544974613],[-74.03924408682435,40.62247901811727]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02188450761754,40.62085685192503],[-74.02174045799462,40.62077461407756],[-74.02186581681508,40.62064172707104],[-74.02180154239164,40.62060316560633]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02385329376379,40.626514473407404],[-74.02415343468138,40.62578041492029]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02897576006832,40.628564077168186],[-74.02927464974715,40.627832923455216]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03079671779996,40.60796647248415],[-74.03000540325685,40.60774150653983]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02461148114473,40.61406757079709],[-74.02433480324261,40.614133152269254],[-74.0239643165225,40.614167778251144],[-74.02368763738318,40.61423097523384],[-74.02298496423504,40.61411918294725]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02279661900184,40.61457960193802],[-74.02298496423504,40.61411918294725],[-74.02385181294233,40.61200004036806],[-74.02457855492976,40.61022330197482]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02957542681239,40.616066234228235],[-74.02870035802583,40.615629982832466]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03797502733808,40.615858807553956],[-74.03766509208317,40.61518117776205]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03487295373766,40.617583549634084],[-74.03488991369639,40.6175414091382],[-74.03490890389106,40.61749414398557],[-74.03496826726874,40.61734504486161],[-74.03497277612257,40.617333705806956],[-74.0349810855508,40.61731494540747],[-74.03493885602501,40.617304296378826],[-74.03491394146451,40.6172982159499],[-74.03488298805706,40.61729114758776]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01969473945587,40.637285120781435],[-74.01955318166169,40.63720134283111]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03168478453624,40.61067684567532],[-74.03110738897593,40.610939388262196],[-74.03106198939156,40.6109590329242],[-74.031016868473,40.610979047564506],[-74.03097203259388,40.6109994303389],[-74.03092748702814,40.61102017823078],[-74.03088323529195,40.611041289899326],[-74.03083928353854,40.61106276216014],[-74.03079563726219,40.61108459283423],[-74.03075230107774,40.611106779575294],[-74.03070927959976,40.611129319199414],[-74.0306665781025,40.61115220902506],[-74.0306242009816,40.61117544787869],[-74.03058215460979,40.61119903140325],[-74.03054044250321,40.611222957922855],[-74.03049906905659,40.611247224086135],[-74.03045804020383,40.61127182721141],[-74.03041736055982,40.61129676461735],[-74.03037703429972,40.61132203328771],[-74.03033706669812,40.61134763087606],[-74.03029746171019,40.611373553863636],[-74.03025822417042,40.61139979889892],[-74.03021935825454,40.611426363970885],[-74.030180868577,40.611453245057966],[-74.0301427601928,40.61148043998136],[-74.03010503705687,40.61150794455217],[-74.03006770378443,40.61153575625663],[-74.0298466203807,40.61170206776585],[-74.02966212896327,40.61186047259775],[-74.0296392727425,40.61188009177773],[-74.02944721879905,40.61206880939084],[-74.02927181772574,40.61226704093138],[-74.02911422622068,40.612473480294014],[-74.0290174182382,40.612622144654395],[-74.02900218093431,40.61269029122895]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03938233056559,40.62989631922404],[-74.03953322182424,40.629558176377444]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01630548309925,40.63589567369046],[-74.0166954641309,40.635521475108796]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01686613159697,40.62092648889473],[-74.01712983809608,40.620683516575916],[-74.01716386615648,40.62065217306243]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03498838208205,40.60963566859854],[-74.03487862301877,40.60945691200269],[-74.03464428366026,40.609088714773094],[-74.0345526559422,40.60894070568894]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0342406488864,40.617432145868946],[-74.0342573262003,40.617391599754654],[-74.03435188956077,40.61716164135983]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02209239738764,40.62362809124284],[-74.02238878740263,40.6228960101773]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02916023122874,40.640774915867915],[-74.02840552031603,40.64032182910622]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02929556017932,40.62048690775809],[-74.03021113041939,40.62014827316605]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04021916085469,40.62270544974613],[-74.04032273625293,40.62258947065583]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03442443016968,40.60873764959216],[-74.03427448586955,40.6085091149792],[-74.03422632375609,40.6084391228115],[-74.03419760483185,40.60840420943524],[-74.03386307876802,40.607997524247786],[-74.03382840054967,40.60795437261873],[-74.0337838265928,40.60789891385592],[-74.03375042641655,40.6078573553633],[-74.03362114438174,40.60770764559617],[-74.03349921829452,40.60756868571808],[-74.03344558129177,40.60751161733144],[-74.03341112906303,40.607474049418705],[-74.0333762410963,40.607436714989966],[-74.03334092113072,40.60739961789695],[-74.03330517136602,40.60736276065152],[-74.03326899444181,40.60732614626804],[-74.0332323936569,40.60728977725812],[-74.03319537165083,40.60725365663609],[-74.03315793194238,40.607217787416054],[-74.03312007607204,40.60718217261272],[-74.03308180843753,40.6071468147373],[-74.03304313101849,40.607111715966724],[-74.03300404689426,40.607076879817804],[-74.03296456024302,40.60704230947197],[-74.0329246732639,40.60700800660347],[-74.03288438903603,40.606973974394094],[-74.03284371085782,40.606940215187834],[-74.03280264180837,40.6069067321665],[-74.03276118606536,40.60687352767386],[-74.03271934516874,40.606840604222015],[-74.03267712417568,40.606807964657065],[-74.03263452506555,40.606775611155975],[-74.0325915517964,40.60674354656514],[-74.03241721350359,40.60660035870952],[-74.03233566824512,40.60653929020582],[-74.03223420667986,40.60646330608977],[-74.03204309777377,40.606332828438056],[-74.03203454037137,40.60632749988181],[-74.03188910319959,40.60622953633805]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03230579701483,40.61742673534823],[-74.03209446071162,40.617321397787926],[-74.03187755743556,40.61721328760671]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0192056339431,40.603734632362084],[-74.01926218296954,40.603619914564675],[-74.01929338052263,40.603515259610326],[-74.01930558922007,40.60340732108458],[-74.01929818557059,40.60329912467338],[-74.0192716659853,40.60319373221884],[-74.01923150391265,40.603102173745],[-74.01917959966825,40.60301717329991],[-74.01911789305836,40.60294500635251],[-74.01904372405421,40.602879497032994],[-74.0189590773079,40.60282241761533],[-74.01886648219508,40.60277505663019],[-74.01876777916155,40.602729902255895],[-74.01865952117151,40.602695097118065],[-74.01854466185512,40.60267222419824],[-74.01842667533649,40.60266218456133],[-74.01830924761762,40.602665093540736],[-74.01819586380492,40.60268026773782],[-74.01795938174125,40.60274404355745],[-74.01771414024418,40.60279307902045],[-74.01746257327925,40.60282644592503],[-74.01720728064882,40.60284352247522],[-74.0169510024933,40.60284402880366],[-74.0166965164232,40.6028280727241],[-74.01644648076537,40.60279605945593],[-74.01618006473487,40.602743047341406],[-74.0159718463255,40.60277637756482]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02390357684486,40.61920092432615],[-74.0248488142437,40.61834193326643],[-74.02607424630311,40.6171524523089]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01664336539812,40.62957607819243],[-74.0169264479982,40.62883563868563]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02179439170388,40.624354993982585],[-74.02209239738764,40.62362809124284]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0252664790932,40.6202252087325],[-74.02519417274536,40.62030992783345]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02991368725351,40.63347412640776],[-74.03019093198031,40.63279069500373]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03070775574493,40.62432825728102],[-74.03105991786607,40.62346289800923]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03578883570226,40.62628504978484],[-74.0360710950868,40.62559887321421]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02555039791707,40.61989253931775],[-74.02545703087748,40.62000193724366]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0260669286775,40.639358431671816],[-74.02596303227422,40.63924060460108],[-74.02584425503406,40.639130398467195],[-74.0257121242771,40.63902939033085],[-74.02556855491359,40.63893891073422]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02457855492976,40.61022330197482],[-74.02477732246007,40.6096959975268]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01955318166169,40.63720134283111],[-74.01932871294058,40.63708062104839]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01892465780084,40.63682599451224],[-74.0184136008854,40.63650501430083],[-74.01794424974013,40.63621022375068]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03194673568348,40.61481445204419],[-74.0320208222862,40.61472745880179]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03234884873444,40.62296256471544],[-74.03236365060735,40.62292545041661],[-74.03238803797956,40.62286435217633],[-74.03246524879128,40.62267095261905],[-74.03246570835088,40.62266787280802],[-74.03246597812873,40.62266381099698],[-74.03246665782632,40.62265134783773],[-74.03246659799137,40.62264947488307],[-74.03246547351287,40.62264703497665],[-74.03245854255063,40.62263632950035],[-74.03208997883755,40.622550613344636],[-74.03205858522279,40.62254333677998]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03840315446585,40.631715294441875],[-74.03722756827788,40.63133711148936]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02487062773851,40.63857104010865],[-74.02453841857515,40.63832493659562]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01970390025541,40.63608035103739],[-74.02012665551166,40.635673785779716]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04133050639992,40.62026702231631],[-74.04137844996096,40.62053853911515]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03616248381722,40.61816830032512],[-74.03622076800592,40.6179062668591]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02336300700999,40.64014077126573],[-74.02310593208485,40.63999532592684]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02722955196661,40.63283606406389],[-74.02452013786399,40.63216736274899]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01594933984525,40.61900487290429],[-74.01652978734877,40.618447035351615]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03583329875791,40.60948773165801],[-74.03607664215738,40.60940692063411]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03697139559839,40.61879529176123],[-74.03598944354782,40.61859585874571]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02590903856417,40.60575050316976],[-74.02586127385598,40.60575427696474],[-74.025813456227,40.605757634107015],[-74.02576559095313,40.60576057359016],[-74.02571768506913,40.605763095245],[-74.02566974451054,40.605765198567575],[-74.0256217752134,40.60576688422665],[-74.02557378377237,40.60576815088048],[-74.02552577590349,40.60576899869529],[-74.02547775908116,40.605769427669436],[-74.02542973924136,40.60576943830413],[-74.02538172144021,40.60576902959312],[-74.0253337135921,40.605768202372275],[-74.02528572119286,40.60576695580279],[-74.02523775061829,40.60576529105596],[-74.02518980846367,40.60576320829791],[-74.02514190066448,40.60576070685724],[-74.02509403315702,40.60575778807296],[-74.02504621297587,40.60575445144098],[-74.02499844605721,40.60575069813278],[-74.02495073811725,40.60574652881729],[-74.0249030968501,40.60574194315788],[-74.02485552665307,40.605736941991296],[-74.02480803500107,40.60573152648874],[-74.02476062826946,40.605725696816435],[-74.0237926704174,40.60562039516242],[-74.02358198392871,40.605493345685296],[-74.02356341205513,40.60548584302015],[-74.02354460818931,40.60547868517431],[-74.02352558288304,40.60547187549608],[-74.02350634646875,40.60546541867407],[-74.02348691147633,40.60545931772112],[-74.02346728779858,40.605453577325925],[-74.02344748862461,40.605448199998634],[-74.02342752406643,40.60544318875263],[-74.02340740665397,40.605438546935844],[-74.0233871475982,40.605434277393904],[-74.0233667598685,40.60543038297211],[-74.0233462540158,40.60542686500848],[-74.02332564234966,40.60542372517573],[-74.02330493718026,40.60542096698941],[-74.02328415015725,40.60541859094973],[-74.02326329490901,40.60541659872917],[-74.02324238132688,40.60541499116331],[-74.02322142391829,40.605413769589454]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02940204798927,40.614813834424275],[-74.03016416683954,40.61392701100221]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02508631102368,40.63083190581657],[-74.02491292845055,40.63085791413604],[-74.02263792255441,40.62948628108033]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02146714650722,40.641236189071776],[-74.02152001080422,40.641153367378756],[-74.02163305222066,40.64097898811244]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0139104241516,40.60601594921489],[-74.01315606807276,40.605621663449085]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0257312094176,40.63407700943491],[-74.02603899600105,40.63330237636062]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02417094670037,40.63866937087833],[-74.02418334434746,40.638540080016476],[-74.02383973080106,40.63834387373157],[-74.02348620674894,40.63814011927233],[-74.02328796152378,40.63800175861811],[-74.02312275998243,40.63789107104167],[-74.02290800817151,40.63777787683085],[-74.02268665427249,40.63767474863199],[-74.02239922852347,40.63754898605913],[-74.02216136185936,40.63745089295317],[-74.02195278042983,40.637452235497214]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02115312268505,40.63813169160991],[-74.02106300303572,40.63805595478976],[-74.02102338956485,40.63802106753185],[-74.02098343401775,40.63798640715618],[-74.02094313683533,40.63795197667777],[-74.0209025019766,40.63791777743581],[-74.02086153142174,40.63788381211003],[-74.02082022715042,40.63785008187244],[-74.02077859158241,40.637816588732555],[-74.02073662757721,40.63778333436481],[-74.02069581573917,40.63775146758026],[-74.02065470250697,40.637719827668796],[-74.02061328898031,40.637688414965],[-74.02057157735904,40.63765723181357],[-74.02052957094233,40.6376262797213],[-74.02048727083012,40.637595559860415],[-74.02044467944226,40.637565075078115],[-74.02041707838863,40.63754555420173],[-74.02038935884737,40.6375261315114],[-74.02030818957937,40.6374668650815],[-74.02000806065679,40.63725981629294]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0260898717898,40.60591312207867],[-74.02588379293921,40.60587453848587]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02039290347214,40.642038985078656],[-74.02029670597527,40.64197377625254]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03552904809666,40.61848392332558],[-74.03554607917103,40.61844315125788],[-74.03567143483521,40.61814305017874]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01664123839913,40.62868003431317],[-74.01428474526321,40.62724714740842]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02231790349825,40.621917050375515],[-74.02277383473061,40.621581553445516]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02900218093431,40.61269029122895],[-74.02895442099513,40.612753105343096],[-74.02885593598724,40.612905246043226],[-74.02882067088225,40.61300628471903],[-74.02880653703416,40.613113053609524],[-74.02881539944336,40.61322159153602],[-74.02884736187869,40.613327583592174],[-74.02890072267037,40.61342688887178],[-74.02897220554718,40.61351613045301]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03194673568348,40.61481445204419],[-74.03016416683954,40.61392701100221]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01756994176787,40.62089820597792],[-74.01815162013094,40.62033644283249]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02559306536594,40.619842541575814],[-74.02555039791707,40.61989253931775]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02021970090256,40.635732702807026],[-74.02012665551166,40.635673785779716]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02125420001359,40.61948204691554],[-74.02129109545038,40.619445695214814],[-74.02155163211434,40.61918838556409],[-74.02193729252328,40.61942987727268]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01679830913133,40.635408366648136],[-74.01684406285652,40.6353623128963],[-74.01690570806392,40.6353022348203]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03344733644003,40.63202844056258],[-74.03374248159624,40.631296601278436]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0179762689204,40.624788030275724],[-74.01875180734196,40.62431751087332]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02089209156752,40.631879624970956],[-74.02030387849568,40.631613518866104]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03122817458835,40.6157229509399],[-74.02940204798927,40.614813834424275]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0166954641309,40.635521475108796],[-74.01597591545298,40.63474447814678],[-74.01475422595298,40.633961648996596]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01774227617491,40.64140075417448],[-74.01835757405783,40.64079334796428]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03699464745893,40.63206906587324],[-74.03701191625477,40.63202606058249],[-74.03710325401208,40.63179810060745]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03135988374659,40.62272872165521],[-74.02864338068372,40.62208600871]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02263792255441,40.62948628108033],[-74.02295953768112,40.62870131512131]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02216115992056,40.616165728681295],[-74.02279661900184,40.61457960193802]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02601178265576,40.6202243316834],[-74.02596859157991,40.620203701062124],[-74.02566120770801,40.62005685017528]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02645488791387,40.60800006267817],[-74.02619259951591,40.607850269052726]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01452089665703,40.60281266301773],[-74.01356337940096,40.60258487627696]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02090092828253,40.641224145557764],[-74.02099806771845,40.641037197970896],[-74.02119382240137,40.640660502364426]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0256661527146,40.63666778118139],[-74.02574552356688,40.63646534460275]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01522379499055,40.60935638411836],[-74.01701910154738,40.60765441697114]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03992966724103,40.628018285470205],[-74.03995558522679,40.627969703034516],[-74.03998200196224,40.62792127672353],[-74.04000891349006,40.62787300905121],[-74.04003631959101,40.62782490253023],[-74.04006421850788,40.62777696168411],[-74.04009260892144,40.627729188020744],[-74.04012148797406,40.627681584388704],[-74.04015085456787,40.6276341546412],[-74.04018070650483,40.62758690145909],[-74.04021104246617,40.62753982702031],[-74.04024186047451,40.62749293517837],[-74.04027315855129,40.62744622777636],[-74.04030493493879,40.627399708332625],[-74.04033718721935,40.62735337969556],[-74.04036991407438,40.62730724421071],[-74.04040311308653,40.62726130522906],[-74.04042277209817,40.627228165332426],[-74.0404419648478,40.62719486644407],[-74.04046069001973,40.62716141359052],[-74.04047894453835,40.62712781029124],[-74.04049672686732,40.62709406023259],[-74.04051403437113,40.62706016743639],[-74.04053086639288,40.62702613542123],[-74.04054721897774,40.62699196804184],[-74.0405630923491,40.626957670156685],[-74.04057848299124,40.626923244447674],[-74.04059339068766,40.62688869543834],[-74.0406078121432,40.62685402698319],[-74.0406217469213,40.62681924327078],[-74.0406351932659,40.62678434798753],[-74.04066167213976,40.62668935722538]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02566011106731,40.6293777102856],[-74.02325796263634,40.62797141135196]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02555039791707,40.61989253931775],[-74.02520756426793,40.61971902115014],[-74.02513068567308,40.6196801084748]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02591140454368,40.6064996600137],[-74.02569689568053,40.607122819001304]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02192439742745,40.63928485919066],[-74.02189276432635,40.639178901121774],[-74.02186969890013,40.63910165947781],[-74.0218517602475,40.639049153437114],[-74.0218120261507,40.63893289522214],[-74.0217442063013,40.638784628621444],[-74.02168096633332,40.63865263332276],[-74.02159666308945,40.638525946064256],[-74.02149265734563,40.638407448370316],[-74.02137119467564,40.63829968821369],[-74.02123523188197,40.638204735477906]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02838003879215,40.63002274319229],[-74.02566011106731,40.6293777102856]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02728962652525,40.63651793874527],[-74.02725224229981,40.63658843154688],[-74.02704505252854,40.63692812926782],[-74.02704383624076,40.636930416485505],[-74.02703816662171,40.6369411252356],[-74.02701432967045,40.6369862375526],[-74.02700889653902,40.63699717140394],[-74.02699664916243,40.637024333833295],[-74.02697782347995,40.63706606842872]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01955007238033,40.62985508792623],[-74.0196604336372,40.62957688094767]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02101999757603,40.63841201143376],[-74.02098624581943,40.63836667651965],[-74.0209540417791,40.638321007931715]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02319919643975,40.625658464915894],[-74.02268549708923,40.62534891440046]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01548864420832,40.62979212096028],[-74.01285741032181,40.62820635131714]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02536070952918,40.62011479353869],[-74.02502078166262,40.619939915015635],[-74.02493937607184,40.61989803123739]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01699572995919,40.630582212938066],[-74.0170384945062,40.63045758676256],[-74.0172329556587,40.62989087412502],[-74.01751444055509,40.62907053600981],[-74.01752337759615,40.62904448813247]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01679830913133,40.635408366648136],[-74.01674167040059,40.63535639365458],[-74.0166400659101,40.63525354471389],[-74.01661244431195,40.635225337238474],[-74.01654684343654,40.63514436290309],[-74.01644208153871,40.63502025972691],[-74.01619966973622,40.634654565936266],[-74.01606372905741,40.634344311592024],[-74.01599390681763,40.63410331509114],[-74.01594501767822,40.633859074298186],[-74.01591739428738,40.63361318239014],[-74.01591473467845,40.633365549075094]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04074397526134,40.625688299329624],[-74.04073384544616,40.625659215745685],[-74.04072426526183,40.62563002441263],[-74.04071523625049,40.625600731361104],[-74.04070676061357,40.6255713421189],[-74.04069883967392,40.62554186372186],[-74.04069147409344,40.62551230102819],[-74.04068466761375,40.62548266140797],[-74.0406784202373,40.62545295005467],[-74.04067273328648,40.625423173334],[-74.04066760764397,40.625393337611825],[-74.04066304595128,40.625363449085846],[-74.04065904711184,40.625333513620035],[-74.0406556137671,40.62530353724453],[-74.04065274526043,40.625273526158175],[-74.040650442255,40.62524348739701],[-74.04064870563299,40.62521342665671],[-74.04064753671638,40.625183349632806],[-74.04064693396903,40.62515326252444],[-74.04064689849395,40.62512317253496],[-74.04064743051349,40.625093085025206],[-74.04064852893161,40.62506300669669],[-74.04065019441045,40.6250329429101],[-74.0406524260741,40.62500290086948],[-74.04065522414518,40.624972886270626],[-74.04065858796706,40.62494290531235],[-74.0406625157839,40.62491296436131]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02388334141075,40.633724386739026],[-74.02137456360131,40.63257860041459]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01623636729718,40.60723326610034],[-74.01549855009637,40.606841524276895]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01835757405783,40.64079334796428],[-74.01616711475104,40.63948244106678]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01931290379294,40.61921695210262],[-74.01711102761195,40.61788751993068]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03551433094704,40.62696173171024],[-74.03283230942773,40.62632904897046]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01907578304655,40.62361467353489],[-74.01640622335879,40.622014176886864]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03019181597391,40.62136730386249],[-74.0301387237302,40.621357618882286],[-74.03011175247848,40.6213527001012]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02897576006832,40.628564077168186],[-74.02840315306487,40.62842811524747],[-74.02714345396993,40.62813104143074],[-74.0262631546062,40.627919956893415]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02366134413828,40.60908130580522],[-74.02367268097102,40.60866665379529],[-74.02349286861931,40.60852671116284],[-74.02348815078076,40.60852521073215]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01832578970308,40.61672605153053],[-74.01611824015598,40.615384035751894]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04145631606293,40.62053354081697],[-74.04137844996096,40.62053853911515]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03483935692643,40.609682730039026],[-74.03498838208205,40.60963566859854]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0247082132657,40.613551709929865],[-74.02491768433391,40.613530220843735],[-74.02504584720045,40.61346347962428],[-74.02519268465883,40.61317157496507],[-74.02533962552594,40.613156055454965],[-74.02547097893444,40.61325847974117],[-74.02528664890049,40.61361472377615],[-74.02509131298667,40.61381133395154],[-74.02499446814676,40.614019835732655],[-74.02473347705897,40.61422837252916],[-74.02461148114473,40.61406757079709]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03797502733808,40.615858807553956],[-74.03568169740524,40.616670587452134]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03594936471876,40.639870278220954],[-74.03537192963131,40.64038118620142],[-74.03507846713502,40.64059991311224],[-74.03433477951984,40.64098893639217],[-74.03407740244343,40.64109143799221],[-74.0338104540738,40.641180551114374],[-74.03373768961299,40.64120041991347],[-74.03353576593955,40.64125555478606],[-74.03325528954954,40.64131590794121],[-74.03297103416493,40.64136128596171]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03048495050112,40.61651863433924],[-74.03003589653639,40.616295018413446],[-74.02980645882604,40.61618076581306]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04137844996096,40.62053853911515],[-74.04127389915878,40.620545249874645]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02940262143127,40.63739166000046],[-74.02982580354184,40.637522819474675]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01945860324523,40.625207413022146],[-74.01950775644231,40.625241237618006],[-74.02009422496316,40.625602695223336],[-74.02015102833555,40.62560628698077],[-74.02026465327637,40.62567478792408],[-74.02025991977492,40.62569642810583],[-74.02031673553377,40.62573969694197],[-74.02035390432427,40.62573374728693],[-74.02056546720223,40.62585808931105]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02592048236816,40.62033037910587],[-74.02587810617325,40.62030894747941],[-74.02557995053986,40.620158140619374]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02305341410933,40.63764749569802],[-74.02286160607476,40.63758400199598],[-74.02267705250354,40.637506936400385],[-74.02250218886294,40.63741710813445],[-74.02233923628125,40.637315651313486],[-74.02219951245164,40.637211965502566]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03488649961561,40.62131959788893],[-74.03219532767785,40.62068747034614]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03544163164408,40.635531376259586],[-74.03545779247382,40.63549087460433],[-74.03563714471528,40.635041622705174]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03435188956077,40.61716164135983],[-74.03432514401418,40.61715558882512],[-74.03424742265106,40.61713738553657],[-74.03427372800962,40.617067146079755]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03446045665925,40.60860021023006],[-74.03437841050534,40.60846996524843]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02569689568053,40.607122819001304],[-74.02646266411575,40.60727846834476]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02030304230694,40.620705247605486],[-74.02059484724826,40.61999021361973]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02123523188197,40.638204735477906],[-74.02136398515202,40.638081970883746],[-74.0213751886626,40.63799853610025]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01875180734196,40.62431751087332],[-74.01582540206918,40.622573607188805]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02365406373,40.61996084407536],[-74.02330490054331,40.62019705477609],[-74.02301711541767,40.620537604148744],[-74.02259117959424,40.62104586058797]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02631533164195,40.61987174446624],[-74.02730164954356,40.61872254016571]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02789633368653,40.63971071733652],[-74.02793261167855,40.639733743859864],[-74.02804168218638,40.63980326474075],[-74.02847658870655,40.640064415967984],[-74.0285468749763,40.640109343910375],[-74.02855289382872,40.6401129533242],[-74.02856610161744,40.64012090178163],[-74.02859610088227,40.64013893144311]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01664123839913,40.62868003431317],[-74.01722288166013,40.62810068935286]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0169264479982,40.62883563868563],[-74.01722288166013,40.62810068935286]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0178698664736,40.63393364218166],[-74.01795101835532,40.63372994095136]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02475437604834,40.63812141809163],[-74.0250906838976,40.63779457402449]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02722955196661,40.63283606406389],[-74.02750722453025,40.63215460208875]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01634322391006,40.630285595428546],[-74.01548864420832,40.62979212096028]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02661661073996,40.6156432261181],[-74.026651124589,40.61545531554817],[-74.0268512511768,40.615167192498824],[-74.02699350116102,40.61498157050905],[-74.02723320357539,40.61470098398639]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01784193368066,40.62659069387398],[-74.01648765885447,40.62577531294818]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02614804195028,40.61454606733913],[-74.02620328480252,40.61445099551053],[-74.02629205313491,40.61429820211615]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03168478453624,40.61067684567532],[-74.03218042435367,40.610513614505145],[-74.03268156207943,40.610360456834215]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02128257283124,40.64071381496383],[-74.0213622829722,40.640519900262326],[-74.02137004420528,40.64050101467999],[-74.02142297984223,40.64035002401499],[-74.02146995212195,40.64014602106652],[-74.02150410300612,40.63984759174341],[-74.02150629075572,40.63981814519407],[-74.02150795332359,40.63978867796929],[-74.02150909093262,40.63975919710527],[-74.02150970336483,40.63972970645518],[-74.02150978974338,40.639700212720356],[-74.02150935073024,40.63967072059146],[-74.0215083856682,40.6396412357646],[-74.0215068958792,40.639611763600406],[-74.0215048809257,40.639582309124805],[-74.0215023405906,40.6395528788714],[-74.02149927641548,40.63952347736315],[-74.02149568884255,40.63949410979332],[-74.02149157765463,40.639464782527966],[-74.02148694461349,40.63943550092763],[-74.02148179060086,40.63940626934783],[-74.02147611561946,40.639377093987015],[-74.02146992099098,40.6393479795357],[-74.02146320825747,40.639318932192026],[-74.02144397190042,40.63923700598852],[-74.02141657305772,40.639136594871054],[-74.02137997466572,40.63902804374103],[-74.02132832742268,40.638916299282236]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03404156746652,40.6305650302342],[-74.03135989933355,40.62993051264942]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02483452438825,40.61560252541747],[-74.02395966789459,40.615160771407304]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03364741814288,40.6128332434378],[-74.03411074911207,40.61229599133894]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03295222200916,40.61028113349408],[-74.0331456392176,40.61022748804165],[-74.03354242808052,40.610100922898674],[-74.03444464220135,40.609813133280305],[-74.03483935692643,40.609682730039026]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03487149024217,40.611366235710996],[-74.0356098598006,40.61060276377649]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02545703087748,40.62000193724366],[-74.02536070952918,40.62011479353869]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01830796925623,40.6268715915053],[-74.01824028152453,40.62683090803958],[-74.01816532344843,40.626785705088835]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0271530069287,40.62572685847986],[-74.0274372501343,40.625027608911445]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0373379855588,40.63215182073484],[-74.03735599852362,40.63210767143332],[-74.03744823361973,40.63188111578922]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0260701320273,40.61548666695231],[-74.02624732375942,40.61510478138763]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02537316768615,40.61940388362679],[-74.02635995559174,40.61825384993942]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03660441542603,40.636569148229],[-74.03724455888974,40.63598546946852]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02015258203039,40.63556675262543],[-74.0177962054603,40.634170868506985]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02123523188197,40.638204735477906],[-74.02118998208482,40.63816666828789],[-74.02115312268505,40.63813169160991]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02762394706329,40.63880495150758],[-74.0250906838976,40.63779457402449]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01982886126855,40.62916817814316],[-74.01995754838745,40.62883781837441]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01729192069578,40.64202171255359],[-74.01723502474022,40.6419873575008],[-74.01717481839918,40.64195100363017]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02534486402693,40.62285939371732],[-74.02566164211383,40.62214065420595]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02268668861555,40.622178102265764],[-74.02231790349825,40.621917050375515]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01425792813643,40.63035001695897],[-74.01445808828751,40.63014636645505],[-74.01449663637622,40.63010715337015]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02104201559015,40.62186201738322],[-74.02075945798437,40.622149073510776],[-74.02058200561427,40.622343014433035]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02137456360131,40.63257860041459],[-74.02062091808762,40.63223369500391],[-74.01889421954473,40.63144343450422]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01815162013094,40.62033644283249],[-74.01873294617045,40.61977703674513]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03032234460834,40.63964722023463],[-74.03047261891031,40.63928530731089],[-74.03060631327827,40.63896332699042]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01323203355358,40.64230518489309],[-74.01381390001302,40.64174524676127]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03554966032256,40.61476009258852],[-74.03558903958204,40.61474709473532],[-74.03572959052832,40.61470071029379],[-74.03593817993365,40.61462581161481]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04089225982429,40.6205675662378],[-74.04074787591178,40.620259609089224],[-74.0406679645741,40.620207676817664],[-74.04049177065124,40.62020641654085]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03051946198278,40.63816274421844],[-74.03050241090976,40.63820299276999],[-74.03049330634255,40.638224598820216],[-74.03043839527727,40.63835023560537],[-74.03035785352135,40.63852472323222],[-74.03032307754998,40.638607076004476],[-74.03024253652815,40.6387578441941],[-74.03022473795177,40.6387934553752],[-74.03020313633591,40.63883642473269]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0128273095168,40.62545573495838],[-74.01340877238549,40.6248958784662]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02573279357522,40.61485603020237],[-74.02576206811797,40.614806008563725],[-74.02588156598644,40.61460178878877]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02573279357522,40.61485603020237],[-74.02566532659877,40.61497049214681],[-74.02558901393031,40.615099959069546]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02565020416453,40.61482724960668],[-74.02573279357522,40.61485603020237]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02289665168085,40.62148341699414],[-74.02297788444453,40.62143139583279]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.033880137792,40.63816726910346],[-74.03405447039279,40.63773724719329],[-74.03415742094354,40.63748330644836]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03250351930691,40.6105896807567],[-74.03226356291654,40.61064500427452],[-74.03222416212235,40.6106593558072],[-74.03218497140391,40.61067403713205],[-74.03214599449706,40.61068904674051],[-74.03210723755515,40.61070438178306],[-74.03206870409474,40.61072004175636],[-74.03203039917007,40.610736023811256],[-74.03199232827565,40.61075232643863],[-74.03195449470738,40.61076894729245],[-74.03191690308051,40.610785884863866],[-74.03187955888912,40.610803136471155]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03019181597391,40.62136730386249],[-74.03023928905878,40.62136639058269],[-74.030315666973,40.62138466008682],[-74.03121530030043,40.62159930129527],[-74.03123689446684,40.62160446453035],[-74.03125225692632,40.62162711744997],[-74.03125526376614,40.62163699513458],[-74.03125528978002,40.621641840227355],[-74.03125330588522,40.62167172002721],[-74.0312526108779,40.62167683537238],[-74.03125123020253,40.621680716886964],[-74.03124094924758,40.621707996382085],[-74.03122972382535,40.62173683398291],[-74.03119225637359,40.62183079563377],[-74.03116697100153,40.62189419889869],[-74.03115155423009,40.621932844259426]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03498838208205,40.60963566859854],[-74.03504956717764,40.60961546036856],[-74.03509032550566,40.60960201210761]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02479160206568,40.631505711163186],[-74.02292928976014,40.63062306606653],[-74.02229638917754,40.63032309233872]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0338176525864,40.61458678736568],[-74.03385252695495,40.61454566835521],[-74.03405517325021,40.61430642982158]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03072182085549,40.64155984234279],[-74.03097918649017,40.64159487586304],[-74.03126687052996,40.641620489826316],[-74.0315522542591,40.64163243338196],[-74.0315566166122,40.641632612277995],[-74.03184680606265,40.64163113676768],[-74.03213577167271,40.641616107817825],[-74.0322118502859,40.6416085636686],[-74.03242190503693,40.641587733123686],[-74.03263666320946,40.6415708687709],[-74.03284956000356,40.641542342560165],[-74.03305898730845,40.64150237174574],[-74.03323028153822,40.641471083349174],[-74.03357737659064,40.64139298832653],[-74.03389772640703,40.64130578743341],[-74.0340180092422,40.641267068092226],[-74.03414947709604,40.64122474729596],[-74.03437440913484,40.641133431060986],[-74.03442301988704,40.64110918336474],[-74.03517655881343,40.64065851609213],[-74.03548217710437,40.64040174734608],[-74.03548476843794,40.640398799218524],[-74.03594936471876,40.639870278220954]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0217769278977,40.619805253716834],[-74.02174892786876,40.619832058600764],[-74.02149533368774,40.62007384181899]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03676602434834,40.63434742165918],[-74.03555598232235,40.634062017580575]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03255834142894,40.61115589103476],[-74.03309396270785,40.61057341558719],[-74.03478316305544,40.61008613407038]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01490317317815,40.63035265462519],[-74.01548864420832,40.62979212096028]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02444889042178,40.6250484458383],[-74.02209239738764,40.62362809124284]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01889421954473,40.63144343450422],[-74.0177243336457,40.63091050440686]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03650777979973,40.63901179097763],[-74.03654820136742,40.638914182414894],[-74.03656467831946,40.6388743946925],[-74.03677346601324,40.6383702218502]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03542256249388,40.64082704454895],[-74.03506222985993,40.64109958704122],[-74.03441765311428,40.641464095120185],[-74.03367756540725,40.64212277665252]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01913887209786,40.60371321100139],[-74.01871382289123,40.603582075404674],[-74.01819043845173,40.60340780002392]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02161286131559,40.62218380192602],[-74.02231790349825,40.621917050375515]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0300453588338,40.64214901429326],[-74.03009334904546,40.642186670507634],[-74.03019968406268,40.642257414170324],[-74.03031329805333,40.64232124945711],[-74.03043302069408,40.64237756283222],[-74.03066060177558,40.64242129480739],[-74.0308594609591,40.642400043073685],[-74.03107561847291,40.6423095009295],[-74.03138279994019,40.64205858744062],[-74.03161321263454,40.641942267317],[-74.0323781351911,40.64177208149963],[-74.03243158820219,40.64176052171868],[-74.03354258683184,40.64153617212451],[-74.03383017108433,40.641410366676816]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02483452438825,40.61560252541747],[-74.02534886452769,40.61472214482855],[-74.02641115145863,40.612906609942215]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0381111352122,40.63025895441205],[-74.0383518812977,40.62966281148568]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02499105006059,40.63358147276902],[-74.02517770006332,40.63309649330162]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03996068960251,40.62327570425802],[-74.04014730501646,40.622863984382946],[-74.04021916085469,40.62270544974613]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02117927174122,40.60442612087531],[-74.02051379205398,40.60423752795864],[-74.0195068073356,40.60390918245437],[-74.01922137397284,40.60381610950833]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01819043845173,40.60340780002392],[-74.01802660963725,40.603272207692186],[-74.01801413298271,40.60326708175066],[-74.01800192548887,40.603261592395036],[-74.01799000540146,40.603255747328866],[-74.01797839118619,40.603249555260874],[-74.01796709889122,40.60324302557028],[-74.0179561463233,40.603236168473664],[-74.01794555040976,40.60322899368515],[-74.01793532522078,40.603221511756985],[-74.01792548812386,40.603213734581125],[-74.01791605230997,40.60320567287747],[-74.01790703250931,40.603197340046165],[-74.01789844191282,40.60318874680709],[-74.0178902937124,40.60317990773335],[-74.01788259978035,40.60317083455019],[-74.01787537176995,40.603161541830936],[-74.01786861979554,40.60315204314394],[-74.0178623555101,40.60314235222492],[-74.01785658661068,40.60313248448538],[-74.01785132321169,40.603122454163795],[-74.017846571911,40.60311227616931],[-74.01784234062528,40.60310196574592],[-74.01783863507328,40.603091538305456],[-74.01783546163307,40.603081009092165],[-74.01783282426528,40.603070394858285],[-74.01783072693017,40.60305971084849],[-74.0178291727089,40.60304897281003],[-74.01782816490255,40.6030381969927],[-74.01782770395477,40.603027399479295],[-74.01782779118855,40.603016597022496],[-74.0178284257284,40.603005804532536],[-74.01782960757866,40.60299503909736],[-74.01783133410567,40.60298431663263],[-74.01783360355493,40.6029736527188],[-74.01783641197426,40.602963063941836],[-74.01783975541106,40.60295256571498],[-74.01784362815452,40.60294217378681],[-74.01784802537296,40.60293190373824],[-74.01785294047623,40.60292177081536],[-74.01785836555551,40.602911790599535],[-74.01786429270147,40.602901976996876],[-74.01787071312627,40.60289234609143],[-74.01787761716209,40.60288291111943],[-74.01788499426216,40.6028736863224],[-74.01789283366016,40.602864686612016],[-74.01790112348996,40.602855923884604],[-74.01790985210583,40.60284741204678],[-74.01791900544397,40.602839164167925],[-74.01792857031944,40.60283119180949],[-74.01793853288807,40.60282350703564],[-74.01794887710756,40.60281612140827],[-74.01795958803457,40.602809046321596],[-74.0179706498464,40.602802292332335],[-74.01798204584085,40.60279586882462],[-74.01799375975557,40.6027897861877],[-74.01800577247032,40.60278405263341],[-74.01801806772264,40.60277867804841],[-74.01803062595233,40.60277366913684],[-74.01804342825903,40.60276903444557],[-74.01805645706047,40.602764779505755],[-74.01806969103833,40.602760912194526],[-74.01808311173114,40.60275743804319],[-74.01809669913858,40.60275436157807],[-74.01811043194144,40.60275168715829],[-74.01812428948021,40.60274941998043],[-74.01813825219352,40.6027475622254],[-74.01815229854238,40.602746117917256],[-74.0181664078661,40.602745088064424],[-74.01818055884488,40.602744474345556],[-74.0181947303787,40.60274427877432],[-74.01820890114692,40.60274450001383],[-74.01823032736473,40.60274099090327],[-74.01825186513462,40.60273790561963],[-74.01827350126943,40.602735245840215],[-74.01829521928501,40.60273301307534],[-74.0183170068736,40.60273120950482],[-74.01833884777058,40.60272983580134],[-74.01836072834917,40.60272889313972],[-74.01838263278425,40.60272838185752],[-74.01840454832806,40.6027283024594],[-74.01842645871591,40.602728655282974],[-74.0184483492214,40.60272943949299],[-74.0184702066572,40.6027306557617],[-74.01849201519752,40.60273230191376],[-74.01851376055563,40.60273437728142],[-74.01853542822488,40.60273688086185],[-74.01855700391809,40.602739810479534],[-74.01857847290863,40.60274316446161],[-74.01859982134889,40.602746940632514],[-74.01862103341287,40.60275113614687],[-74.01864209679147,40.60275574849381],[-74.01866299653763,40.60276077399023],[-74.01868371880367,40.60276621029301],[-74.01870424930182,40.60277205338392],[-74.01872457550257,40.60277829890933],[-74.01874468223897,40.60278494301866],[-74.01876455698147,40.602791981190755],[-74.01878418632121,40.60279940873714],[-74.01880355728883,40.6028072206342],[-74.01882265669516,40.60281541169078],[-74.01884147179058,40.602823976883286],[-74.01893188168236,40.6028728242314],[-74.01901325629899,40.60293220941048],[-74.01908255886397,40.60300050271824],[-74.01913753180786,40.60307545279376],[-74.01917685113881,40.603154422300406],[-74.01921360940655,40.603241685413565],[-74.01923447751302,40.60333381420902],[-74.01923809605373,40.60342821540505],[-74.01922408673586,40.60352204308245],[-74.01919313358788,40.60361250575099],[-74.01913887209786,40.60371321100139]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01448201327624,40.60891037993433],[-74.01623636729718,40.60723326610034]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02059484724826,40.61999021361973],[-74.02089938190545,40.61926265491913]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01456685527899,40.63757090781398],[-74.01514575030541,40.63701460961411]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03607030710799,40.63730595025948],[-74.03608746184302,40.63727330111042],[-74.03610507691681,40.63724079404582],[-74.03612315035193,40.63720843342187],[-74.0361416799507,40.637176222924644],[-74.03616066373564,40.63714416674278],[-74.03618009994845,40.63711226772457],[-74.03619998529224,40.63708053005905],[-74.0362203182289,40.63704895709703],[-74.03624109656103,40.63701755285967],[-74.03626231743118,40.63698632086571],[-74.03628397864199,40.63695526513631],[-74.03630607733568,40.63692438852008],[-74.03632861043508,40.63689369470339],[-74.03635157706239,40.63686318787447],[-74.03637497238068,40.63683287088257],[-74.03639879573198,40.636802747580816],[-74.0364230435994,40.636772821823186],[-74.03644771246566,40.63674309662606],[-74.03647280013303,40.636713575172905],[-74.03649830374454,40.63668426148502],[-74.03652421956302,40.63665515857886],[-74.03655054627039,40.63662626947007],[-74.03657727859078,40.63659759834827],[-74.03660441542603,40.636569148229]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01892465780084,40.63682599451224],[-74.0184136008854,40.63650501430083],[-74.01794424974013,40.63621022375068]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02261098612834,40.63970852832769],[-74.02192439742745,40.63928485919066]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02536070952918,40.62011479353869],[-74.0252664790932,40.6202252087325]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02631533164195,40.61987174446624],[-74.02537316768615,40.61940388362679]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01755939514045,40.63013156236207],[-74.01780244173645,40.62936684005484]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03523521442837,40.62764527581542],[-74.03551433094704,40.62696173171024]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02007423343322,40.62424643447731],[-74.02008241644769,40.624104979160286],[-74.02048383227941,40.62358176015833],[-74.02073621126854,40.62325278244574],[-74.02144351782536,40.62241088235501],[-74.02161286131559,40.62218380192602]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03160913630951,40.6385021796791],[-74.03209040108409,40.63761348651111]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0268776058058,40.6373906299475],[-74.02704901447754,40.63745657939607],[-74.0274995244708,40.63762249260564]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0287007460467,40.61859355146942],[-74.02930182080097,40.61789600944142]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03042727609291,40.625009935881906],[-74.02781309671755,40.62438995034653],[-74.02773394483708,40.62430140322686]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02991368725351,40.63347412640776],[-74.02722955196661,40.63283606406389]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01620695995756,40.63322998887184],[-74.0163860448736,40.63316196515229]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01278547561228,40.60542947959574],[-74.01418866233085,40.60386812584718],[-74.01378073348609,40.60364946526914]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02334639906894,40.61976973549253],[-74.02326643434552,40.619724680591446],[-74.02318505145092,40.61967585283674]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04141240413853,40.62025916405394],[-74.04145631606293,40.62053354081697]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03106070351704,40.63066101398831],[-74.02838003879215,40.63002274319229]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02713876775371,40.625761900638224],[-74.02475042751018,40.62432075214108]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02176040916885,40.63982434619838],[-74.02185196389816,40.63981609782905]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01432761381442,40.61711734341869],[-74.01490900364942,40.61655789281406]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03155802828581,40.64144186402923],[-74.03240982901937,40.64143059587199]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03515733062534,40.60970591170685],[-74.03512641757725,40.60965694137785],[-74.03509032550566,40.60960201210761]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0327758936268,40.60976383464716],[-74.03320700519672,40.609332198947484]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0371680717415,40.6321108662934],[-74.03718565939973,40.63206727569625],[-74.037277150459,40.63183994560939]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01926351278594,40.6334934144416],[-74.01973592316727,40.63288491697105]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02151458743292,40.62418759518767],[-74.0214982204076,40.62422961613009],[-74.02147361022263,40.624291549734345],[-74.02137901091915,40.62450795349861],[-74.02128556963419,40.624760602474275]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03736205390018,40.631860377817354],[-74.037277150459,40.63183994560939]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02219951245164,40.637211965502566],[-74.02176759944302,40.636933967688954]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03167122262958,40.6171106130959],[-74.03163855327205,40.61714846233809],[-74.0316110810798,40.61718030289201],[-74.031607502605,40.61718443748304],[-74.0316025651167,40.61718921157017],[-74.03158173095547,40.61721453090633],[-74.03157183317201,40.61722607820625],[-74.03156343343592,40.6172306729815],[-74.03155555272735,40.617234736882224],[-74.03155424230218,40.61723631285083],[-74.0314277969371,40.61739065195288],[-74.03136341577189,40.617469239898575]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02395966789459,40.615160771407304],[-74.02279661900184,40.61457960193802]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03728235187485,40.62263792793432],[-74.03682119486643,40.622528357448815],[-74.03501813871564,40.6220999488135],[-74.0346006153585,40.62200073904816]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02546066272338,40.60707666304845],[-74.02569689568053,40.607122819001304]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02603960456793,40.635741189299864],[-74.0235186645925,40.634615786682204]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02395564987297,40.64232680143745],[-74.02456733672958,40.64177087260064]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01648765885447,40.62577531294818],[-74.01726142532779,40.62526924225197]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03809447949352,40.620584898475926],[-74.03543728497804,40.61995580764228]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02140162281016,40.62639461068758],[-74.02144918033243,40.62642326497867],[-74.02145375486803,40.626425938720686],[-74.02135977554988,40.626520547105436]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0206233103417,40.621806251563505],[-74.02090368274169,40.621526166359786],[-74.02117699460089,40.62125785685994]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01729192069578,40.64202171255359],[-74.0178857873427,40.64147118903415]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0177562083344,40.63425010916054],[-74.01749215233902,40.634083764299255],[-74.01733863069313,40.634012958993054],[-74.01645178317794,40.63335239687772],[-74.0163860448736,40.63316196515229]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02022933658131,40.64193209968427],[-74.02053788495638,40.641616701573085],[-74.0207610806815,40.64138854240536],[-74.02080897981277,40.64133958160862]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02029670597527,40.64197377625254],[-74.02060464466344,40.64166077037703],[-74.02083006358566,40.641434834450365],[-74.0208806207955,40.641380436845324],[-74.02090112395791,40.641356656649705],[-74.02093762609574,40.64130895868899],[-74.02097412883828,40.64126125150225],[-74.02104702548262,40.6411726809843],[-74.02111716424196,40.641087461326656],[-74.02120080566738,40.64098583123523],[-74.02136556525572,40.64076415644252],[-74.02144582166734,40.64057963423182],[-74.02145914643818,40.64054815851417],[-74.02149092308588,40.640473085265945],[-74.0215424913974,40.64033576445143],[-74.02159530903636,40.64014932051991],[-74.0216112324179,40.64007555576033],[-74.02164447961336,40.639834687997556],[-74.02164304454377,40.63981817063281],[-74.02161466072258,40.6394914519345],[-74.02157349935707,40.63931083366617],[-74.02156795963609,40.639289951780505],[-74.02154902467775,40.63922439725644],[-74.02152000640866,40.6391239682063],[-74.02147653651916,40.63900597246773]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03509032550566,40.60960201210761],[-74.03525978733708,40.60954610976749],[-74.0357344518362,40.60938952460263]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02628612034283,40.64007452838303],[-74.02635007613429,40.64001846526114],[-74.0264643503655,40.63991829269074]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02012056882756,40.6390869490181],[-74.02071502826158,40.63854872042211]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02835300020536,40.628893174103304],[-74.02736200279284,40.628667807402294]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01500072034628,40.62676890709503],[-74.01570811714437,40.626295049370796]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02867799741152,40.62929432896287],[-74.02822439711,40.62918642393322],[-74.02723085006429,40.62895005227942],[-74.0271512137077,40.62893110620009],[-74.02649401933346,40.62877474889372],[-74.02595819003183,40.62864726756076]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0360710950868,40.62559887321421],[-74.03621949918892,40.62523729489375],[-74.03642583101983,40.62473459544902]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01910090435524,40.60377437196514],[-74.01908143119798,40.60376772948884],[-74.01866021768471,40.60364106759185],[-74.0182528881678,40.60352130112829],[-74.0179396896302,40.60341633131932],[-74.01777672095405,40.60337074467101],[-74.01611352638395,40.6029054840191]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03472092466451,40.63610686565888],[-74.03369256690526,40.6358649139405],[-74.03316296914741,40.63574030086181],[-74.03203646331005,40.6354752371198]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03135988374659,40.62272872165521],[-74.03163907988211,40.62204849142787]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0365454183737,40.623210265228664],[-74.03655911754639,40.62316996250069],[-74.03656648059793,40.62314775371955],[-74.03656779017182,40.623144628054035],[-74.03676260499965,40.62266757886803],[-74.0367640797564,40.622663804810976],[-74.03676776214667,40.622654780366425],[-74.03679862635957,40.62258013575527],[-74.03680441005018,40.62256683329234],[-74.03682119486643,40.622528357448815]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04141240413853,40.62025916405394],[-74.04133050639992,40.62026702231631]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0235493915473,40.639320333692275],[-74.0213751886626,40.63799853610025]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03338384096558,40.637537735473565],[-74.03396842368615,40.63771194116319],[-74.03397842583304,40.63771491904255],[-74.03405447039279,40.63773724719329]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03285202575337,40.62126596787461],[-74.03281740064554,40.62127019211833],[-74.03272713442814,40.62124917305208],[-74.03248836684766,40.62119227378508]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02238878740263,40.6228960101773],[-74.02165021038866,40.6224486469831]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02892312153189,40.62140418198831],[-74.02900836845947,40.62119206102639]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02885230062411,40.640802441399224],[-74.02872088069836,40.64075095578599]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01285741032181,40.62820635131714],[-74.01357203468916,40.62772787701898]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0269393000037,40.608110048216886],[-74.02645488791387,40.60800006267817]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02229638917754,40.63032309233872],[-74.02263792255441,40.62948628108033]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03568169740524,40.616670587452134],[-74.03539473682623,40.6162052328757]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03183438380226,40.61361024336414],[-74.03179181944525,40.613660504103436],[-74.03156420053745,40.61392933648825],[-74.0310046887715,40.61363961984884],[-74.03121648719838,40.61337215269415],[-74.03125596727217,40.61332228937862]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03725223040435,40.632131154915655],[-74.03727004259096,40.632087284795226],[-74.03736205390018,40.631860377817354]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02277383473061,40.621581553445516],[-74.02289665168085,40.62148341699414]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02864338068372,40.62208600871],[-74.02868000278448,40.62199620868128]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02165021038866,40.6224486469831],[-74.02231790349825,40.621917050375515]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02369674686376,40.62094919252825],[-74.02446644099014,40.62043675220262]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03315548281145,40.63273497322292],[-74.03344733644003,40.63202844056258]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0291039543851,40.60655740829638],[-74.02895446719153,40.606947408075264]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03595784256667,40.638821144636054],[-74.03607270469281,40.63893623154832],[-74.03612405753265,40.63900570958857],[-74.03610416530033,40.639122987440956],[-74.03606145754802,40.63922507007476],[-74.03601303673345,40.63930543776579],[-74.03599311544325,40.639370594818224],[-74.03598745712327,40.639450949104315],[-74.03595042791268,40.639509596486654],[-74.03587637075164,40.639631234389334],[-74.03582509208807,40.63970074453197],[-74.03574245839775,40.63977677941555],[-74.0356733410975,40.63979431380046],[-74.03563203156583,40.63978962425193],[-74.03558827806658,40.63976311168031]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03202032036847,40.608015072335],[-74.03142129934174,40.608031618641675],[-74.03134839341736,40.608127472013564]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03192153893677,40.61083035531361],[-74.03250351930691,40.6105896807567]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02872088069836,40.64075095578599],[-74.02696785882371,40.63990452365057]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03558827806658,40.63976311168031],[-74.03556964241854,40.63976325180404],[-74.03555102063787,40.63976382799705],[-74.03553243163643,40.63976483824314],[-74.03551389190753,40.63976628169961],[-74.03549541838477,40.639768158361235],[-74.03547702975979,40.639770465709354],[-74.03545874208505,40.63977320089111],[-74.03544057361287,40.6397763623931],[-74.03542254061519,40.639779946524826],[-74.03540466090367,40.63978395009778],[-74.0353869498707,40.639788369756715],[-74.03536942576686,40.639793200470265],[-74.03535210442452,40.6397984390506],[-74.03533500145461,40.63980407929445],[-74.03531813378798,40.63981011583582],[-74.03530151791625,40.639816544314],[-74.03528516725088,40.63982335802386],[-74.0352690993817,40.63983054992389],[-74.03525332860025,40.639838113978826],[-74.03523786919742,40.63984604281315],[-74.0352227365637,40.63985432905102],[-74.03520794411004,40.63986296481463],[-74.03519350656691,40.63987194205822],[-74.03517943734494,40.639881252233884],[-74.03516574963491,40.63989088679375],[-74.03515245530762,40.639900836352766],[-74.03513956843344,40.63991109202774],[-74.0351271004428,40.63992164342854],[-74.03511506276688,40.63993248133776],[-74.03510346705605,40.63994359519768],[-74.03509232408148,40.63995497528849],[-74.03508164527305,40.639966609879856],[-74.03507143854263,40.639978488582734],[-74.03506171554017,40.63999059983421],[-74.03505248483708,40.640002932742455],[-74.03504375434443,40.64001547524314],[-74.03503553263333,40.64002821577426],[-74.03502782783505,40.64004114277404],[-74.0350206478601,40.6400542430054],[-74.03501399754114,40.64006750524255],[-74.03500788412904,40.64008091641617],[-74.03500231421526,40.64009446412725],[-74.03498567845502,40.64011726244066],[-74.03496854840512,40.640139847973266],[-74.03495092955977,40.640162214022034],[-74.03493282631372,40.64018435405177],[-74.03491424372199,40.640206262532324],[-74.03489518683939,40.640227933430864],[-74.03487566138051,40.64024936071439],[-74.03485567174052,40.640270538517875],[-74.0348352242939,40.64029146097564],[-74.03481432409548,40.64031212188735],[-74.03479297686064,40.64033251656023],[-74.03477118852385,40.64035263862616],[-74.0347489663395,40.64037248238676],[-74.03472631426392,40.64039204365234],[-74.03470323999086,40.6404113157192],[-74.03467974879565,40.640430293224576],[-74.03465584881324,40.64044897197758],[-74.03463154509903,40.64046734644798],[-74.03460684512761,40.64048541127235],[-74.03458175483443,40.640503161590345],[-74.03455628169449,40.640520592541144],[-74.03453043296315,40.64053769993407],[-74.03450421589487,40.640554477735726],[-74.03447763686584,40.64057092259333],[-74.0344507037909,40.64058702947844],[-74.03442342304591,40.64060279436821],[-74.03439580342526,40.64061821189884],[-74.03436785218494,40.64063327871736],[-74.03433957658068,40.64064799096822],[-74.03431098496728,40.640662343622814],[-74.0342820848206,40.64067633316061],[-74.0342528844963,40.64068995606077],[-74.03422339147002,40.640703208300174],[-74.03419361365732,40.64071608585554],[-74.03416356029382,40.640728585708416],[-74.03413323885582,40.64074070484085],[-74.03410265747873,40.640752439062],[-74.03407182517824,40.64076378518595],[-74.03404776176421,40.64078297783747],[-74.03402329880157,40.64080187474689],[-74.03399844156594,40.64082047088657],[-74.03397319709246,40.64083876139583],[-74.03394757197691,40.64085674225179],[-74.0339215725948,40.640874408929086],[-74.03389520554131,40.64089175606456],[-74.0338684774123,40.640908779802906],[-74.0338413943635,40.640925475618765],[-74.03381396518995,40.6409418393211],[-74.03378619516782,40.640957866552384],[-74.03375809265235,40.64097355312169],[-74.03372966401967,40.64098889534132],[-74.03370091696549,40.641003889355595],[-74.03367185830554,40.641018530806534],[-74.03364249595563,40.64103281617349],[-74.03361283805178,40.641046742438355],[-74.0335828907499,40.64106030507585],[-74.03355266240592,40.641073500900255],[-74.03352216071609,40.6410863268936],[-74.03349139359626,40.64109877953525],[-74.03346036918262,40.641110855807135],[-74.03342909495125,40.641122552188776],[-74.03339757925839,40.64113386599708],[-74.03336582980023,40.64114479387905],[-74.03333385537323,40.641155333821615],[-74.03330166301407,40.64116548297456],[-74.03326926151887,40.64117523848715],[-74.03323665946395,40.64118459784385],[-74.03320386542569,40.64119355852905],[-74.03317088666101,40.64120211819512],[-74.03313773350625,40.64121027533116],[-74.0331044121186,40.64121802742233],[-74.0330709326141,40.64122537212016],[-74.03303730312989,40.64123230808195],[-74.03300353202253,40.64123883279226],[-74.03296962830933,40.64124494574579],[-74.03293560100664,40.641250644426904],[-74.03290145825193,40.64125592799553],[-74.03286720862195,40.64126079443879],[-74.03283286069413,40.64126524308401],[-74.0327984248049,40.641269272420374],[-74.03275472347867,40.64127793855732],[-74.03271088712698,40.64128619862714],[-74.03266692146752,40.64129405028266],[-74.03262283397822,40.6413014928515],[-74.03257863015764,40.641308525494345],[-74.03253431682361,40.64131514686886],[-74.03248990145401,40.6413213561352],[-74.03244538932749,40.64132715245412],[-74.03240078770203,40.64133253498579],[-74.03235610361541,40.64133750238791],[-74.03231134300637,40.6413420543237],[-74.03226651291327,40.641346190623516],[-74.03222162059379,40.641349909777496],[-74.03217667132677,40.641353211281526],[-74.03213167281066,40.64135609546844],[-74.03208663142368,40.64135856133123],[-74.03204155332432,40.64136060819801],[-74.0319964466511,40.6413622369041],[-74.0319513169022,40.64136344560516],[-74.0319061708967,40.64136423547197],[-74.0318610163327,40.64136460599976],[-74.03181585848921,40.64136455701954],[-74.03177070484435,40.641364088026684],[-74.03172556243719,40.641363200191925],[-74.03168043786584,40.64136189234076],[-74.03163533685013,40.64136016631448],[-74.03159026752753,40.6413580207706],[-74.03154523539766,40.641355456880405],[-74.03150024771891,40.64135247464192],[-74.03145531087051,40.641349075058606],[-74.03141043255056,40.641345257793375],[-74.03136561781899,40.64134102452022],[-74.03132087525361,40.6413363749018],[-74.03127620947436,40.64133131027718],[-74.0312316283994,40.641325830644305],[-74.03118713818829,40.641319937676855],[-74.03114274653939,40.641313631707945],[-74.03109845829223,40.641306913406474],[-74.03104682139552,40.64129966533695],[-74.0309952872446,40.64129200576675],[-74.03094386111907,40.64128393569973],[-74.03089254873812,40.641275455469575],[-74.03084135560134,40.64126656624763],[-74.03079028786803,40.6412572690376],[-74.03073935037808,40.641247565178595],[-74.0306885495103,40.64123745483658],[-74.0306378905449,40.64122694035575],[-74.03058737854107,40.64121602190245],[-74.03053701965857,40.641204701485606],[-74.03048681939642,40.64119297927149],[-74.03043678303462,40.64118085726922],[-74.03038691607289,40.64116833715286],[-74.03033722313077,40.64115541959154],[-74.03028771168732,40.64114210625877],[-74.03023838548266,40.64112839849404],[-74.03018925067637,40.64111429830631],[-74.03014031232766,40.64109980602956],[-74.03009157659672,40.64108492501297],[-74.03004304722299,40.64106965525586],[-74.02999473058631,40.64105399960476],[-74.02994663262604,40.64103795956619],[-74.02989875752166,40.64102153564188],[-74.02985111033395,40.64100473185154],[-74.02980369744131,40.640987548026196],[-74.0297565230242,40.64096998701308],[-74.02970959324193,40.64095205048617],[-74.0296629120547,40.64093374062259],[-74.02961648518205,40.64091505943155],[-74.02957031834342,40.64089600875466],[-74.0295244157189,40.64087659076903],[-74.02947878258816,40.64085680765153],[-74.02943342379106,40.640836661579065],[-74.02938834460701,40.64081615422592],[-74.02934355053604,40.64079528877402],[-74.02916023122874,40.640774915867915]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0169264479982,40.62883563868563],[-74.01664123839913,40.62868003431317]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02173709503862,40.631687882624895],[-74.02202374839493,40.63098801670602]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02261098612834,40.63970852832769],[-74.0228587022124,40.639631620481964],[-74.02309897759815,40.63954079080953],[-74.02332981376723,40.63943672562356],[-74.0235493915473,40.639320333692275]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01918487143968,40.63657561589338],[-74.01970390025541,40.63608035103739]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01849303797555,40.64087580502753],[-74.01843070336886,40.64083732705414],[-74.01835757405783,40.64079334796428]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0304730729105,40.632098967408616],[-74.0277909861234,40.6314633669818]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02892473285023,40.612477702955296],[-74.0289466782121,40.61244980855365],[-74.02913136584412,40.61221505468852]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03048497536487,40.61758254562128],[-74.03084507393038,40.616699488714296]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02927435380454,40.61371201632833],[-74.02930136559192,40.613681733787644],[-74.02933540742167,40.613648819912726]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01594933984525,40.61900487290429],[-74.01374808840534,40.617676594817674]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02588379293921,40.60587453848587],[-74.02590903856417,40.60575050316976]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04077867018931,40.63036973344771],[-74.04074290202045,40.630460723221844],[-74.04058634778987,40.63082562377774],[-74.04038993619504,40.63127523337887],[-74.04023906318461,40.6316140705147],[-74.03982352610501,40.63251088388536],[-74.03970670214066,40.63276742530382],[-74.03957574400917,40.63305196230526],[-74.03946754781347,40.633264825459506],[-74.03918853277798,40.63386009245468],[-74.0389351291978,40.63436605566625],[-74.03872443511312,40.63480263754546],[-74.03849380331877,40.63527397245331],[-74.03827582093577,40.635722333328694],[-74.03814641249353,40.63596034273821],[-74.03785598896754,40.63657502850024],[-74.03767375155235,40.63694644763752],[-74.0375142901662,40.637267910418295],[-74.03731496629547,40.6376784252953],[-74.03719537048738,40.637923864976116],[-74.03710709610772,40.638104144268475],[-74.03697203389261,40.638418079867826],[-74.03667838248343,40.63905846791726]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03298781199574,40.63598566159275],[-74.03302817174756,40.63599416883255],[-74.0330324853533,40.635991232326155],[-74.03304758588399,40.635977512761855],[-74.03305385562976,40.635964021395345],[-74.03312541117832,40.63580624739872],[-74.03314015102893,40.63578019129255],[-74.03316296914741,40.63574030086181]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02723320357539,40.61470098398639],[-74.0267077251169,40.61509075385551],[-74.02632231133784,40.61525756264974],[-74.02622113375811,40.61533375697056],[-74.0260701320273,40.61548666695231]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0367255304667,40.623999477990225],[-74.03700355407041,40.62331909077572]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02987104022792,40.62637344160045],[-74.03014945024137,40.6256909459527]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02146714650722,40.641236189071776],[-74.02177493676653,40.641015197899435],[-74.02185068603521,40.640966871013156],[-74.02222905228213,40.6407220552078],[-74.02223113737973,40.64072070603331],[-74.02227765242675,40.64069060875752]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.0179762689204,40.624788030275724],[-74.01524185216765,40.62313302617248]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01984163966091,40.61764397475195],[-74.01832578970308,40.61672605153053]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01357203468916,40.62772787701898],[-74.01428474526321,40.62724714740842]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.03316279012168,40.6134020726199],[-74.03137808967088,40.61250877934178]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02736880517995,40.61323451610855],[-74.02667043372095,40.61299411945527],[-74.02641115145863,40.612906609942215]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.01335669051925,40.638735308633656],[-74.01396088612057,40.63815326741945]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.04079235781758,40.624196572355466],[-74.04080041561227,40.62417208919098],[-74.04080794895164,40.624147509715485],[-74.04081495564118,40.62412283979333],[-74.04082143348681,40.62409808612659],[-74.04082738161352,40.6240732550817],[-74.04083279716777,40.62404835352848],[-74.0408376790548,40.62402338800099],[-74.04084202683964,40.623998365368145],[-74.04084583854797,40.62397329199677],[-74.04084911352507,40.623948174923406],[-74.0408518511153,40.62392301967676],[-74.04085404978512,40.62389783429878],[-74.04085571019854,40.623872624987825],[-74.04085683016147,40.62384739827834],[-74.04085741055842,40.62382216137375],[-74.04085745117379,40.623796920305175],[-74.04085695245229,40.62377168210866],[-74.04085591307937,40.62374645348585],[-74.04085433503849,40.62372124096959],[-74.04085221723521,40.62369605159651],[-74.04084956143289,40.62367089156447],[-74.0408463671968,40.62364576807736],[-74.04084263651058,40.623620688003086],[-74.04083836981802,40.62359565703743],[-74.04083356778395,40.62357068271889],[-74.0408282326111,40.62354577074261],[-74.04082236496461,40.623520929149606],[-74.04081596726667,40.62349616296486],[-74.04080903996227,40.62347147989442],[-74.04080158613414,40.623446886470724],[-74.04079360732528,40.62342238822158],[-74.04078510529989,40.623397992852546],[-74.0407760824803,40.623373705723616],[-74.04076654173006,40.62334953453995],[-74.0407564845919,40.623325484494245],[-74.0407459152483,40.62330156295617],[-74.0407348352423,40.623277775621034],[-74.04072324787627,40.62325412885358],[-74.04069708447307,40.623218666081385],[-74.04067136951029,40.62318301266424],[-74.04064610562888,40.62314717362744],[-74.04062129502782,40.62311115031066],[-74.04059693946849,40.62307494757195],[-74.04057304202985,40.62303856775589],[-74.04054960491247,40.62300201488271],[-74.04052662943694,40.62296529213522],[-74.04050411802321,40.62292840286345],[-74.04048207331078,40.62289134991472],[-74.04046049684108,40.622854138147105],[-74.04043939081312,40.62281676923537],[-74.04041875654842,40.622779248037624],[-74.04039859690627,40.62274157740111],[-74.04037891276772,40.62270376101143],[-74.04035970699216,40.6226658018833],[-74.04034098090061,40.62262770420475],[-74.04032273625293,40.62258947065583]]}},{"type":"Feature","properties":null,"geometry":{"type":"LineString","coordinates":[[-74.02624732375942,40.61510478138763],[-74.02651463147971,40.61467032683149],[-74.02736880517995,40.61323451610855]]}}]} ================================================ FILE: test/distortion.html ================================================ GeoJSON Buildings Example ================================================ FILE: test/extrude-bevel.html ================================================ Simple Extrude Example ================================================ FILE: test/extrude-dude.html ================================================ Duuude ================================================ FILE: test/extrude-exclude-bottom.html ================================================ Simple Extrude Example ================================================ FILE: test/extrude-hole.html ================================================ Extrude with Hole ================================================ FILE: test/extrude-multipolygon.html ================================================ Extrude with Hole ================================================ FILE: test/extrude-normal.html ================================================ Normal Example ================================================ FILE: test/extrude-polyline.html ================================================ Simple Extrude Example ================================================ FILE: test/extrude-simple.html ================================================ Simple Extrude Example ================================================ FILE: test/extrude-simplify.html ================================================ Simple Extrude Example ================================================ FILE: test/extrude-star.html ================================================ Star Extrude Example ================================================ FILE: test/extrude-uv.html ================================================ UV Example ================================================ FILE: test/geojson.html ================================================ GeoJSON Buildings Example ================================================ FILE: test/lib/claygl-advanced-renderer.js ================================================ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('claygl')) : typeof define === 'function' && define.amd ? define(['claygl'], factory) : (global.ClayAdvancedRenderer = factory(global.clay)); }(this, (function (claygl) { 'use strict'; // Generate halton sequence // https://en.wikipedia.org/wiki/Halton_sequence function halton(index, base) { var result = 0; var f = 1 / base; var i = index; while (i > 0) { result = result + f * (i % base); i = Math.floor(i / base); f = f / base; } return result; } var SSAOGLSLCode = "@export car.ssao.estimate\n#define SHADER_NAME SSAO\nuniform sampler2D depthTex;\nuniform sampler2D normalTex;\nuniform sampler2D noiseTex;\nuniform vec2 depthTexSize;\nuniform vec2 noiseTexSize;\nuniform mat4 projection;\nuniform mat4 projectionInv;\nuniform mat4 viewInverseTranspose;\nuniform vec3 kernel[KERNEL_SIZE];\nuniform float radius : 1;\nuniform float power : 1;\nuniform float bias: 0.01;\nuniform float intensity: 1.0;\nvarying vec2 v_Texcoord;\nfloat ssaoEstimator(in vec3 originPos, in vec3 N, in mat3 kernelBasis) {\n float occlusion = 0.0;\n for (int i = 0; i < KERNEL_SIZE; i++) {\n vec3 samplePos = kernel[i];\n#ifdef NORMALTEX_ENABLED\n samplePos = kernelBasis * samplePos;\n#endif\n samplePos = samplePos * radius + originPos;\n vec4 texCoord = projection * vec4(samplePos, 1.0);\n texCoord.xy /= texCoord.w;\n texCoord.xy = texCoord.xy * 0.5 + 0.5;\n vec4 depthTexel = texture2D(depthTex, texCoord.xy);\n float z = depthTexel.r * 2.0 - 1.0;\n#ifdef ALCHEMY\n vec4 projectedPos = vec4(texCoord.xy * 2.0 - 1.0, z, 1.0);\n vec4 p4 = projectionInv * projectedPos;\n p4.xyz /= p4.w;\n vec3 cDir = p4.xyz - originPos;\n float vv = dot(cDir, cDir);\n float vn = dot(cDir, N);\n float radius2 = radius * radius;\n vn = max(vn + p4.z * bias, 0.0);\n float f = max(radius2 - vv, 0.0) / radius2;\n occlusion += f * f * f * max(vn / (0.01 + vv), 0.0);\n#else\n if (projection[3][3] == 0.0) {\n z = projection[3][2] / (z * projection[2][3] - projection[2][2]);\n }\n else {\n z = (z - projection[3][2]) / projection[2][2];\n }\n float factor = step(samplePos.z, z - bias);\n float rangeCheck = smoothstep(0.0, 1.0, radius / abs(originPos.z - z));\n occlusion += rangeCheck * factor;\n#endif\n }\n#ifdef NORMALTEX_ENABLED\n occlusion = 1.0 - occlusion / float(KERNEL_SIZE);\n#else\n occlusion = 1.0 - clamp((occlusion / float(KERNEL_SIZE) - 0.6) * 2.5, 0.0, 1.0);\n#endif\n return pow(occlusion, power);\n}\nvoid main()\n{\n vec2 uv = v_Texcoord;\n vec4 depthTexel = texture2D(depthTex, uv);\n#ifdef NORMALTEX_ENABLED\n vec2 texelSize = 1.0 / depthTexSize;\n vec4 tex = texture2D(normalTex, uv);\n vec3 r = texture2D(normalTex, uv + vec2(texelSize.x, 0.0)).rgb;\n vec3 l = texture2D(normalTex, uv + vec2(-texelSize.x, 0.0)).rgb;\n vec3 t = texture2D(normalTex, uv + vec2(0.0, -texelSize.y)).rgb;\n vec3 b = texture2D(normalTex, uv + vec2(0.0, texelSize.y)).rgb;\n if (dot(tex.rgb, tex.rgb) == 0.0\n || dot(r, r) == 0.0 || dot(l, l) == 0.0\n || dot(t, t) == 0.0 || dot(b, b) == 0.0\n ) {\n gl_FragColor = vec4(1.0);\n return;\n }\n vec3 N = tex.rgb * 2.0 - 1.0;\n N = (viewInverseTranspose * vec4(N, 0.0)).xyz;\n vec2 noiseTexCoord = depthTexSize / vec2(noiseTexSize) * uv;\n vec3 rvec = texture2D(noiseTex, noiseTexCoord).rgb * 2.0 - 1.0;\n vec3 T = normalize(rvec - N * dot(rvec, N));\n vec3 BT = normalize(cross(N, T));\n mat3 kernelBasis = mat3(T, BT, N);\n#else\n if (depthTexel.r > 0.99999) {\n gl_FragColor = vec4(1.0);\n return;\n }\n mat3 kernelBasis;\n#endif\n float z = depthTexel.r * 2.0 - 1.0;\n vec4 projectedPos = vec4(uv * 2.0 - 1.0, z, 1.0);\n vec4 p4 = projectionInv * projectedPos;\n vec3 position = p4.xyz / p4.w;\n float ao = ssaoEstimator(position, N, kernelBasis);\n ao = clamp(1.0 - (1.0 - ao) * intensity, 0.0, 1.0);\n gl_FragColor = vec4(vec3(ao), 1.0);\n}\n@end\n@export car.ssao.blur\n#define SHADER_NAME SSAO_BLUR\nuniform sampler2D ssaoTexture;\n#ifdef NORMALTEX_ENABLED\nuniform sampler2D normalTex;\n#endif\nvarying vec2 v_Texcoord;\nuniform vec2 textureSize;\nuniform float blurSize : 1.0;\nuniform int direction: 0.0;\n#ifdef DEPTHTEX_ENABLED\nuniform sampler2D depthTex;\nuniform mat4 projection;\nuniform float depthRange : 0.05;\nfloat getLinearDepth(vec2 coord)\n{\n float depth = texture2D(depthTex, coord).r * 2.0 - 1.0;\n return projection[3][2] / (depth * projection[2][3] - projection[2][2]);\n}\n#endif\nvoid main()\n{\n float kernel[5];\n kernel[0] = 0.122581;\n kernel[1] = 0.233062;\n kernel[2] = 0.288713;\n kernel[3] = 0.233062;\n kernel[4] = 0.122581;\n vec2 off = vec2(0.0);\n if (direction == 0) {\n off[0] = blurSize / textureSize.x;\n }\n else {\n off[1] = blurSize / textureSize.y;\n }\n vec2 coord = v_Texcoord;\n float sum = 0.0;\n float weightAll = 0.0;\n#ifdef NORMALTEX_ENABLED\n vec3 centerNormal = texture2D(normalTex, v_Texcoord).rgb * 2.0 - 1.0;\n#endif\n#if defined(DEPTHTEX_ENABLED)\n float centerDepth = getLinearDepth(v_Texcoord);\n#endif\n for (int i = 0; i < 5; i++) {\n vec2 coord = clamp(v_Texcoord + vec2(float(i) - 2.0) * off, vec2(0.0), vec2(1.0));\n float w = kernel[i];\n#ifdef NORMALTEX_ENABLED\n vec3 normal = texture2D(normalTex, coord).rgb * 2.0 - 1.0;\n w *= clamp(dot(normal, centerNormal), 0.0, 1.0);\n#endif\n#ifdef DEPTHTEX_ENABLED\n float d = getLinearDepth(coord);\n w *= (1.0 - smoothstep(abs(centerDepth - d) / depthRange, 0.0, 1.0));\n#endif\n weightAll += w;\n sum += texture2D(ssaoTexture, coord).r * w;\n }\n gl_FragColor = vec4(vec3(sum / weightAll), 1.0);\n}\n@end\n"; var Pass = claygl.compositor.Pass; claygl.Shader.import(SSAOGLSLCode); function generateNoiseData(size) { var data = new Uint8Array(size * size * 4); var n = 0; var v3 = new claygl.Vector3(); for (var i = 0; i < size; i++) { for (var j = 0; j < size; j++) { v3.set(Math.random() * 2 - 1, Math.random() * 2 - 1, 0).normalize(); data[n++] = (v3.x * 0.5 + 0.5) * 255; data[n++] = (v3.y * 0.5 + 0.5) * 255; data[n++] = 0; data[n++] = 255; } } return data; } function generateNoiseTexture(size) { return new claygl.Texture2D({ pixels: generateNoiseData(size), wrapS: claygl.Texture.REPEAT, wrapT: claygl.Texture.REPEAT, width: size, height: size }); } function generateKernel(size, offset, hemisphere) { var kernel = new Float32Array(size * 3); offset = offset || 0; for (var i = 0; i < size; i++) { var phi = halton(i + offset, 2) * (hemisphere ? 1 : 2) * Math.PI; var theta = halton(i + offset, 3) * Math.PI; var r = Math.random(); var x = Math.cos(phi) * Math.sin(theta) * r; var y = Math.cos(theta) * r; var z = Math.sin(phi) * Math.sin(theta) * r; kernel[i * 3] = x; kernel[i * 3 + 1] = y; kernel[i * 3 + 2] = z; } return kernel; } function SSAOPass(opt) { opt = opt || {}; this._ssaoPass = new Pass({ fragment: claygl.Shader.source('car.ssao.estimate') }); this._blendPass = new Pass({ fragment: claygl.Shader.source('car.temporalBlend') }); this._blurPass = new Pass({ fragment: claygl.Shader.source('car.ssao.blur') }); this._framebuffer = new claygl.FrameBuffer(); this._ssaoTexture = new claygl.Texture2D(); this._prevTexture = new claygl.Texture2D(); this._currTexture = new claygl.Texture2D(); this._blurTexture = new claygl.Texture2D(); this._depthTex = opt.depthTexture; this._normalTex = opt.normalTexture; this._velocityTex = opt.velocityTexture; this.setNoiseSize(4); this.setKernelSize(opt.kernelSize || 12); if (opt.radius != null) { this.setParameter('radius', opt.radius); } if (opt.power != null) { this.setParameter('power', opt.power); } if (!this._normalTex) { this._ssaoPass.material.disableTexture('normalTex'); this._blurPass.material.disableTexture('normalTex'); } if (!this._depthTex) { this._blurPass.material.disableTexture('depthTex'); } this._blurPass.material.setUniform('normalTex', this._normalTex); this._blurPass.material.setUniform('depthTex', this._depthTex); this._temporalFilter = true; this._frame = 0; } SSAOPass.prototype.setDepthTexture = function (depthTex) { this._depthTex = depthTex; }; SSAOPass.prototype.setNormalTexture = function (normalTex) { this._normalTex = normalTex; this._ssaoPass.material[normalTex ? 'enableTexture' : 'disableTexture']('normalTex'); // Switch between hemisphere and shere kernel. this.setKernelSize(this._kernelSize); }; SSAOPass.prototype.update = function (renderer, camera, frame) { var width = renderer.getWidth(); var height = renderer.getHeight(); var ssaoPass = this._ssaoPass; var blurPass = this._blurPass; var blendPass = this._blendPass; this._frame++; ssaoPass.setUniform('kernel', this._kernels[ (this._temporalFilter ? this._frame : frame) % this._kernels.length ]); ssaoPass.setUniform('depthTex', this._depthTex); if (this._normalTex != null) { ssaoPass.setUniform('normalTex', this._normalTex); } ssaoPass.setUniform('depthTexSize', [this._depthTex.width, this._depthTex.height]); var viewInverseTranspose = new claygl.Matrix4(); claygl.Matrix4.transpose(viewInverseTranspose, camera.worldTransform); ssaoPass.setUniform('projection', camera.projectionMatrix.array); ssaoPass.setUniform('projectionInv', camera.invProjectionMatrix.array); ssaoPass.setUniform('viewInverseTranspose', viewInverseTranspose.array); var ssaoTexture = this._ssaoTexture; var blurTexture = this._blurTexture; var prevTexture = this._prevTexture; var currTexture = this._currTexture; ssaoTexture.width = width; ssaoTexture.height = height; blurTexture.width = width; blurTexture.height = height; prevTexture.width = width; prevTexture.height = height; currTexture.width = width; currTexture.height = height; this._framebuffer.attach(ssaoTexture); this._framebuffer.bind(renderer); renderer.gl.clearColor(1, 1, 1, 1); renderer.gl.clear(renderer.gl.COLOR_BUFFER_BIT); ssaoPass.render(renderer); if (this._temporalFilter) { this._framebuffer.attach(currTexture); blendPass.setUniform('prevTex', prevTexture); blendPass.setUniform('currTex', ssaoTexture); blendPass.setUniform('velocityTex', this._velocityTex); blendPass.render(renderer); } blurPass.setUniform('textureSize', [width, height]); blurPass.setUniform('projection', camera.projectionMatrix.array); this._framebuffer.attach(blurTexture); blurPass.setUniform('direction', 0); blurPass.setUniform('ssaoTexture', this._temporalFilter ? currTexture : ssaoTexture); blurPass.render(renderer); this._framebuffer.attach(ssaoTexture); blurPass.setUniform('direction', 1); blurPass.setUniform('ssaoTexture', blurTexture); blurPass.render(renderer); this._framebuffer.unbind(renderer); // Restore clear var clearColor = renderer.clearColor; renderer.gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); // Swap texture var tmp = this._prevTexture; this._prevTexture = this._currTexture; this._currTexture = tmp; }; SSAOPass.prototype.getTargetTexture = function () { return this._ssaoTexture; }; SSAOPass.prototype.setParameter = function (name, val) { if (name === 'noiseTexSize') { this.setNoiseSize(val); } else if (name === 'kernelSize') { this.setKernelSize(val); } else if (name === 'intensity') { this._ssaoPass.material.set('intensity', val); } else if (name === 'temporalFilter') { this._temporalFilter = val; } else { this._ssaoPass.setUniform(name, val); } }; SSAOPass.prototype.setKernelSize = function (size) { this._kernelSize = size; this._ssaoPass.material.define('fragment', 'KERNEL_SIZE', size); this._kernels = this._kernels || []; for (var i = 0; i < 30; i++) { this._kernels[i] = generateKernel(size, i * size, !!this._normalTex); } }; SSAOPass.prototype.setNoiseSize = function (size) { var texture = this._ssaoPass.getUniform('noiseTex'); if (!texture) { texture = generateNoiseTexture(size); this._ssaoPass.setUniform('noiseTex', generateNoiseTexture(size)); } else { texture.data = generateNoiseData(size); texture.width = texture.height = size; texture.dirty(); } this._ssaoPass.setUniform('noiseTexSize', [size, size]); }; SSAOPass.prototype.dispose = function (renderer) { this._blurTexture.dispose(renderer); this._ssaoTexture.dispose(renderer); this._prevTexture.dispose(renderer); this._currTexture.dispose(renderer); }; SSAOPass.prototype.isFinished = function (frame) { return frame > 30; }; var SSRGLSLCode = "@export car.ssr.main\n#define SHADER_NAME SSR\n#define MAX_ITERATION 20;\n#define SAMPLE_PER_FRAME 5;\n#define TOTAL_SAMPLES 128;\nuniform sampler2D sourceTexture;\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture2;\nuniform sampler2D gBufferTexture3;\nuniform samplerCube specularCubemap;\nuniform sampler2D brdfLookup;\nuniform float specularIntensity: 1;\nuniform mat4 projection;\nuniform mat4 projectionInv;\nuniform mat4 toViewSpace;\nuniform mat4 toWorldSpace;\nuniform float maxRayDistance: 200;\nuniform float pixelStride: 16;\nuniform float pixelStrideZCutoff: 50;\nuniform float screenEdgeFadeStart: 0.9;\nuniform float eyeFadeStart : 0.2;uniform float eyeFadeEnd: 0.8;\nuniform float minGlossiness: 0.2;uniform float zThicknessThreshold: 1;\nuniform float nearZ;\nuniform vec2 viewportSize : VIEWPORT_SIZE;\nuniform float jitterOffset: 0;\nvarying vec2 v_Texcoord;\n#ifdef DEPTH_DECODE\n@import clay.util.decode_float\n#endif\n#ifdef PHYSICALLY_CORRECT\nuniform sampler2D normalDistribution;\nuniform float sampleOffset: 0;\nuniform vec2 normalDistributionSize;\nvec3 transformNormal(vec3 H, vec3 N) {\n vec3 upVector = N.y > 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nvec3 importanceSampleNormalGGX(float i, float roughness, vec3 N) {\n float p = fract((i + sampleOffset) / float(TOTAL_SAMPLES));\n vec3 H = texture2D(normalDistribution,vec2(roughness, p)).rgb;\n return transformNormal(H, N);\n}\nfloat G_Smith(float g, float ndv, float ndl) {\n float roughness = 1.0 - g;\n float k = roughness * roughness / 2.0;\n float G1V = ndv / (ndv * (1.0 - k) + k);\n float G1L = ndl / (ndl * (1.0 - k) + k);\n return G1L * G1V;\n}\nvec3 F_Schlick(float ndv, vec3 spec) {\n return spec + (1.0 - spec) * pow(1.0 - ndv, 5.0);\n}\n#endif\nfloat fetchDepth(sampler2D depthTexture, vec2 uv)\n{\n vec4 depthTexel = texture2D(depthTexture, uv);\n return depthTexel.r * 2.0 - 1.0;\n}\nfloat linearDepth(float depth)\n{\n if (projection[3][3] == 0.0) {\n return projection[3][2] / (depth * projection[2][3] - projection[2][2]);\n }\n else {\n return (depth - projection[3][2]) / projection[2][2];\n }\n}\nbool rayIntersectDepth(float rayZNear, float rayZFar, vec2 hitPixel)\n{\n if (rayZFar > rayZNear)\n {\n float t = rayZFar; rayZFar = rayZNear; rayZNear = t;\n }\n float cameraZ = linearDepth(fetchDepth(gBufferTexture2, hitPixel));\n return rayZFar <= cameraZ && rayZNear >= cameraZ - zThicknessThreshold;\n}\nbool traceScreenSpaceRay(\n vec3 rayOrigin, vec3 rayDir, float jitter,\n out vec2 hitPixel, out vec3 hitPoint, out float iterationCount\n)\n{\n float rayLength = ((rayOrigin.z + rayDir.z * maxRayDistance) > -nearZ)\n ? (-nearZ - rayOrigin.z) / rayDir.z : maxRayDistance;\n vec3 rayEnd = rayOrigin + rayDir * rayLength;\n vec4 H0 = projection * vec4(rayOrigin, 1.0);\n vec4 H1 = projection * vec4(rayEnd, 1.0);\n float k0 = 1.0 / H0.w, k1 = 1.0 / H1.w;\n vec3 Q0 = rayOrigin * k0, Q1 = rayEnd * k1;\n vec2 P0 = (H0.xy * k0 * 0.5 + 0.5) * viewportSize;\n vec2 P1 = (H1.xy * k1 * 0.5 + 0.5) * viewportSize;\n P1 += dot(P1 - P0, P1 - P0) < 0.0001 ? 0.01 : 0.0;\n vec2 delta = P1 - P0;\n bool permute = false;\n if (abs(delta.x) < abs(delta.y)) {\n permute = true;\n delta = delta.yx;\n P0 = P0.yx;\n P1 = P1.yx;\n }\n float stepDir = sign(delta.x);\n float invdx = stepDir / delta.x;\n vec3 dQ = (Q1 - Q0) * invdx;\n float dk = (k1 - k0) * invdx;\n vec2 dP = vec2(stepDir, delta.y * invdx);\n float strideScaler = 1.0 - min(1.0, -rayOrigin.z / pixelStrideZCutoff);\n float pixStride = 1.0 + strideScaler * pixelStride;\n dP *= pixStride; dQ *= pixStride; dk *= pixStride;\n vec4 pqk = vec4(P0, Q0.z, k0);\n vec4 dPQK = vec4(dP, dQ.z, dk);\n pqk += dPQK * jitter;\n float rayZFar = (dPQK.z * 0.5 + pqk.z) / (dPQK.w * 0.5 + pqk.w);\n float rayZNear;\n bool intersect = false;\n vec2 texelSize = 1.0 / viewportSize;\n iterationCount = 0.0;\n for (int i = 0; i < MAX_ITERATION; i++)\n {\n pqk += dPQK;\n rayZNear = rayZFar;\n rayZFar = (dPQK.z * 0.5 + pqk.z) / (dPQK.w * 0.5 + pqk.w);\n hitPixel = permute ? pqk.yx : pqk.xy;\n hitPixel *= texelSize;\n intersect = rayIntersectDepth(rayZNear, rayZFar, hitPixel);\n iterationCount += 1.0;\n dPQK *= 1.2;\n if (intersect) {\n break;\n }\n }\n Q0.xy += dQ.xy * iterationCount;\n Q0.z = pqk.z;\n hitPoint = Q0 / pqk.w;\n return intersect;\n}\nfloat calculateAlpha(\n float iterationCount, float reflectivity,\n vec2 hitPixel, vec3 hitPoint, float dist, vec3 rayDir\n)\n{\n float alpha = clamp(reflectivity, 0.0, 1.0);\n alpha *= 1.0 - (iterationCount / float(MAX_ITERATION));\n vec2 hitPixelNDC = hitPixel * 2.0 - 1.0;\n float maxDimension = min(1.0, max(abs(hitPixelNDC.x), abs(hitPixelNDC.y)));\n alpha *= 1.0 - max(0.0, maxDimension - screenEdgeFadeStart) / (1.0 - screenEdgeFadeStart);\n float _eyeFadeStart = eyeFadeStart;\n float _eyeFadeEnd = eyeFadeEnd;\n if (_eyeFadeStart > _eyeFadeEnd) {\n float tmp = _eyeFadeEnd;\n _eyeFadeEnd = _eyeFadeStart;\n _eyeFadeStart = tmp;\n }\n float eyeDir = clamp(rayDir.z, _eyeFadeStart, _eyeFadeEnd);\n alpha *= 1.0 - (eyeDir - _eyeFadeStart) / (_eyeFadeEnd - _eyeFadeStart);\n alpha *= 1.0 - clamp(dist / maxRayDistance, 0.0, 1.0);\n return alpha;\n}\n@import clay.util.rand\n@import clay.util.rgbm\nvoid main()\n{\n vec4 normalAndGloss = texture2D(gBufferTexture1, v_Texcoord);\n if (dot(normalAndGloss.rgb, vec3(1.0)) == 0.0) {\n discard;\n }\n float g = normalAndGloss.a;\n#if !defined(PHYSICALLY_CORRECT)\n if (g <= minGlossiness) {\n discard;\n }\n#endif\n float reflectivity = (g - minGlossiness) / (1.0 - minGlossiness);\n vec3 N = normalize(normalAndGloss.rgb * 2.0 - 1.0);\n N = normalize((toViewSpace * vec4(N, 0.0)).xyz);\n vec4 projectedPos = vec4(v_Texcoord * 2.0 - 1.0, fetchDepth(gBufferTexture2, v_Texcoord), 1.0);\n vec4 pos = projectionInv * projectedPos;\n vec3 rayOrigin = pos.xyz / pos.w;\n vec3 V = -normalize(rayOrigin);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n float iterationCount;\n float jitter = rand(fract(v_Texcoord + jitterOffset));\n vec4 albedoMetalness = texture2D(gBufferTexture3, v_Texcoord);\n vec3 albedo = albedoMetalness.rgb;\n float m = albedoMetalness.a;\n vec3 diffuseColor = albedo * (1.0 - m);\n vec3 spec = mix(vec3(0.04), albedo, m);\n#ifdef PHYSICALLY_CORRECT\n vec4 color = vec4(vec3(0.0), 1.0);\n float jitter2 = rand(fract(v_Texcoord)) * float(TOTAL_SAMPLES);\n for (int i = 0; i < SAMPLE_PER_FRAME; i++) {\n vec3 H = importanceSampleNormalGGX(float(i) + jitter2, 1.0 - g, N);\n vec3 rayDir = normalize(reflect(-V, H));\n#else\n vec3 rayDir = normalize(reflect(-V, N));\n#endif\n vec2 hitPixel;\n vec3 hitPoint;\n bool intersect = traceScreenSpaceRay(rayOrigin, rayDir, jitter, hitPixel, hitPoint, iterationCount);\n float dist = distance(rayOrigin, hitPoint);\n vec3 hitNormal = texture2D(gBufferTexture1, hitPixel).rgb * 2.0 - 1.0;\n hitNormal = normalize((toViewSpace * vec4(hitNormal, 0.0)).xyz);\n#ifdef PHYSICALLY_CORRECT\n float ndl = clamp(dot(N, rayDir), 0.0, 1.0);\n float vdh = clamp(dot(V, H), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n vec3 litTexel = vec3(0.0);\n if (dot(hitNormal, rayDir) < 0.0 && intersect) {\n litTexel = texture2D(sourceTexture, hitPixel).rgb;\n litTexel *= pow(clamp(1.0 - dist / 200.0, 0.0, 1.0), 3.0);\n }\n else {\n#ifdef SPECULARCUBEMAP_ENABLED\n vec3 rayDirW = normalize(toWorldSpace * vec4(rayDir, 0.0)).rgb;\n litTexel = RGBMDecode(textureCubeLodEXT(specularCubemap, rayDirW, 0.0), 8.12).rgb * specularIntensity;\n#endif\n }\n color.rgb += ndl * litTexel * (\n F_Schlick(ndl, spec) * G_Smith(g, ndv, ndl) * vdh / (ndh * ndv + 0.001)\n );\n }\n color.rgb /= float(SAMPLE_PER_FRAME);\n#else\n#if !defined(SPECULARCUBEMAP_ENABLED)\n if (dot(hitNormal, rayDir) >= 0.0) {\n discard;\n }\n if (!intersect) {\n discard;\n }\n#endif\n float alpha = clamp(calculateAlpha(iterationCount, reflectivity, hitPixel, hitPoint, dist, rayDir), 0.0, 1.0);\n vec4 color = texture2D(sourceTexture, hitPixel);\n color.rgb *= alpha;\n#ifdef SPECULARCUBEMAP_ENABLED\n vec3 rayDirW = normalize(toWorldSpace * vec4(rayDir, 0.0)).rgb;\n alpha = alpha * (intersect ? 1.0 : 0.0);\n float bias = (1.0 - g) * 5.0;\n vec2 brdfParam2 = texture2D(brdfLookup, vec2(1.0 - g, ndv)).xy;\n color.rgb += (1.0 - alpha)\n * RGBMDecode(textureCubeLodEXT(specularCubemap, rayDirW, bias), 8.12).rgb\n * (spec * brdfParam2.x + brdfParam2.y)\n * specularIntensity;\n#endif\n#endif\n gl_FragColor = encodeHDR(color);\n}\n@end\n@export car.ssr.blur\nuniform sampler2D texture;\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture2;\nuniform mat4 projection;\nuniform float depthRange : 0.05;\nvarying vec2 v_Texcoord;\nuniform vec2 textureSize;\nuniform float blurSize : 1.0;\n#ifdef BLEND\n #ifdef SSAOTEX_ENABLED\nuniform sampler2D ssaoTex;\n #endif\nuniform sampler2D sourceTexture;\n#endif\nfloat getLinearDepth(vec2 coord)\n{\n float depth = texture2D(gBufferTexture2, coord).r * 2.0 - 1.0;\n return projection[3][2] / (depth * projection[2][3] - projection[2][2]);\n}\n@import clay.util.rgbm\nvoid main()\n{\n @import clay.compositor.kernel.gaussian_9\n vec4 centerNTexel = texture2D(gBufferTexture1, v_Texcoord);\n float g = centerNTexel.a;\n float maxBlurSize = clamp(1.0 - g, 0.0, 1.0) * blurSize;\n#ifdef VERTICAL\n vec2 off = vec2(0.0, maxBlurSize / textureSize.y);\n#else\n vec2 off = vec2(maxBlurSize / textureSize.x, 0.0);\n#endif\n vec2 coord = v_Texcoord;\n vec4 sum = vec4(0.0);\n float weightAll = 0.0;\n vec3 cN = centerNTexel.rgb * 2.0 - 1.0;\n float cD = getLinearDepth(v_Texcoord);\n for (int i = 0; i < 9; i++) {\n vec2 coord = clamp((float(i) - 4.0) * off + v_Texcoord, vec2(0.0), vec2(1.0));\n float w = gaussianKernel[i]\n * clamp(dot(cN, texture2D(gBufferTexture1, coord).rgb * 2.0 - 1.0), 0.0, 1.0);\n float d = getLinearDepth(coord);\n w *= (1.0 - smoothstep(abs(cD - d) / depthRange, 0.0, 1.0));\n weightAll += w;\n sum += decodeHDR(texture2D(texture, coord)) * w;\n }\n#ifdef BLEND\n float aoFactor = 1.0;\n #ifdef SSAOTEX_ENABLED\n aoFactor = texture2D(ssaoTex, v_Texcoord).r;\n #endif\n gl_FragColor = encodeHDR(\n sum / weightAll * aoFactor + decodeHDR(texture2D(sourceTexture, v_Texcoord))\n );\n#else\n gl_FragColor = encodeHDR(sum / weightAll);\n#endif\n}\n@end"; var Pass$1 = claygl.compositor.Pass; var cubemapUtil = claygl.util.cubemap; // import halton from './halton'; claygl.Shader.import(SSRGLSLCode); // function generateNormals(size, offset, hemisphere) { // var kernel = new Float32Array(size * 3); // offset = offset || 0; // for (var i = 0; i < size; i++) { // var phi = halton(i + offset, 2) * (hemisphere ? 1 : 2) * Math.PI / 2; // var theta = halton(i + offset, 3) * 2 * Math.PI; // var x = Math.cos(theta) * Math.sin(phi); // var y = Math.sin(theta) * Math.sin(phi); // var z = Math.cos(phi); // kernel[i * 3] = x; // kernel[i * 3 + 1] = y; // kernel[i * 3 + 2] = z; // } // return kernel; // } function SSRPass(opt) { opt = opt || {}; this._ssrPass = new Pass$1({ fragment: claygl.Shader.source('car.ssr.main'), clearColor: [0, 0, 0, 0] }); this._blurPass1 = new Pass$1({ fragment: claygl.Shader.source('car.ssr.blur'), clearColor: [0, 0, 0, 0] }); this._blurPass2 = new Pass$1({ fragment: claygl.Shader.source('car.ssr.blur'), clearColor: [0, 0, 0, 0] }); this._blendPass = new Pass$1({ fragment: claygl.Shader.source('clay.compositor.blend') }); this._blendPass.material.disableTexturesAll(); this._blendPass.material.enableTexture(['texture1', 'texture2']); this._ssrPass.setUniform('gBufferTexture1', opt.normalTexture); this._ssrPass.setUniform('gBufferTexture2', opt.depthTexture); this._ssrPass.setUniform('gBufferTexture3', opt.albedoTexture); this._blurPass1.setUniform('gBufferTexture1', opt.normalTexture); this._blurPass1.setUniform('gBufferTexture2', opt.depthTexture); this._blurPass2.setUniform('gBufferTexture1', opt.normalTexture); this._blurPass2.setUniform('gBufferTexture2', opt.depthTexture); this._blurPass2.material.define('fragment', 'VERTICAL'); this._blurPass2.material.define('fragment', 'BLEND'); this._ssrTexture = new claygl.Texture2D({ type: claygl.Texture.HALF_FLOAT }); this._texture2 = new claygl.Texture2D({ type: claygl.Texture.HALF_FLOAT }); this._texture3 = new claygl.Texture2D({ type: claygl.Texture.HALF_FLOAT }); this._prevTexture = new claygl.Texture2D({ type: claygl.Texture.HALF_FLOAT }); this._currentTexture = new claygl.Texture2D({ type: claygl.Texture.HALF_FLOAT }); this._frameBuffer = new claygl.FrameBuffer({ depthBuffer: false }); this._normalDistribution = null; this._totalSamples = 256; this._samplePerFrame = 4; this._ssrPass.material.define('fragment', 'SAMPLE_PER_FRAME', this._samplePerFrame); this._ssrPass.material.define('fragment', 'TOTAL_SAMPLES', this._totalSamples); this._downScale = 1; } SSRPass.prototype.setAmbientCubemap = function (specularCubemap, brdfLookup, specularIntensity) { this._ssrPass.material.set('specularCubemap', specularCubemap); this._ssrPass.material.set('brdfLookup', brdfLookup); this._ssrPass.material.set('specularIntensity', specularIntensity); var enableSpecularMap = specularCubemap && specularIntensity; this._ssrPass.material[enableSpecularMap ? 'enableTexture' : 'disableTexture']('specularCubemap'); }; SSRPass.prototype.update = function (renderer, camera, sourceTexture, reflectionSourceTexture, frame) { var width = renderer.getWidth(); var height = renderer.getHeight(); var ssrTexture = this._ssrTexture; var texture2 = this._texture2; var texture3 = this._texture3; ssrTexture.width = this._prevTexture.width = this._currentTexture.width = width / this._downScale; ssrTexture.height = this._prevTexture.height = this._currentTexture.height = height / this._downScale; texture2.width = texture3.width = width; texture2.height = texture3.height = height; var frameBuffer = this._frameBuffer; var ssrPass = this._ssrPass; var blurPass1 = this._blurPass1; var blurPass2 = this._blurPass2; var blendPass = this._blendPass; var toViewSpace = new claygl.Matrix4(); var toWorldSpace = new claygl.Matrix4(); claygl.Matrix4.transpose(toViewSpace, camera.worldTransform); claygl.Matrix4.transpose(toWorldSpace, camera.viewMatrix); ssrPass.setUniform('sourceTexture', reflectionSourceTexture); ssrPass.setUniform('projection', camera.projectionMatrix.array); ssrPass.setUniform('projectionInv', camera.invProjectionMatrix.array); ssrPass.setUniform('toViewSpace', toViewSpace.array); ssrPass.setUniform('toWorldSpace', toWorldSpace.array); ssrPass.setUniform('nearZ', camera.near); var percent = frame / this._totalSamples * this._samplePerFrame; ssrPass.setUniform('jitterOffset', percent); ssrPass.setUniform('sampleOffset', frame * this._samplePerFrame); // ssrPass.setUniform('lambertNormals', this._diffuseSampleNormals[frame % this._totalSamples]); blurPass1.setUniform('textureSize', [ssrTexture.width, ssrTexture.height]); blurPass2.setUniform('textureSize', [width, height]); blurPass2.setUniform('sourceTexture', sourceTexture); blurPass1.setUniform('projection', camera.projectionMatrix.array); blurPass2.setUniform('projection', camera.projectionMatrix.array); frameBuffer.attach(ssrTexture); frameBuffer.bind(renderer); ssrPass.render(renderer); if (this._physicallyCorrect) { frameBuffer.attach(this._currentTexture); blendPass.setUniform('texture1', this._prevTexture); blendPass.setUniform('texture2', ssrTexture); blendPass.material.set({ 'weight1': frame >= 1 ? 0.95 : 0, 'weight2': frame >= 1 ? 0.05 : 1 // weight1: frame >= 1 ? 1 : 0, // weight2: 1 }); blendPass.render(renderer); } frameBuffer.attach(texture2); blurPass1.setUniform('texture', this._physicallyCorrect ? this._currentTexture : ssrTexture); blurPass1.render(renderer); frameBuffer.attach(texture3); blurPass2.setUniform('texture', texture2); blurPass2.render(renderer); frameBuffer.unbind(renderer); if (this._physicallyCorrect) { var tmp = this._prevTexture; this._prevTexture = this._currentTexture; this._currentTexture = tmp; } }; SSRPass.prototype.getTargetTexture = function () { return this._texture3; }; SSRPass.prototype.setParameter = function (name, val) { if (name === 'maxIteration') { this._ssrPass.material.define('fragment', 'MAX_ITERATION', val); } else { this._ssrPass.setUniform(name, val); } }; SSRPass.prototype.setPhysicallyCorrect = function (isPhysicallyCorrect) { if (isPhysicallyCorrect) { if (!this._normalDistribution) { this._normalDistribution = cubemapUtil.generateNormalDistribution(64, this._totalSamples); } this._ssrPass.material.define('fragment', 'PHYSICALLY_CORRECT'); this._ssrPass.material.set('normalDistribution', this._normalDistribution); this._ssrPass.material.set('normalDistributionSize', [64, this._totalSamples]); } else { this._ssrPass.material.undefine('fragment', 'PHYSICALLY_CORRECT'); } this._physicallyCorrect = isPhysicallyCorrect; }; SSRPass.prototype.setSSAOTexture = function (texture) { var blendPass = this._blurPass2; if (texture) { blendPass.material.enableTexture('ssaoTex'); blendPass.material.set('ssaoTex', texture); } else { blendPass.material.disableTexture('ssaoTex'); } }; SSRPass.prototype.isFinished = function (frame) { if (this._physicallyCorrect) { return frame > (this._totalSamples / this._samplePerFrame); } else { return true; } }; SSRPass.prototype.dispose = function (renderer) { this._ssrTexture.dispose(renderer); this._texture2.dispose(renderer); this._texture3.dispose(renderer); this._prevTexture.dispose(renderer); this._currentTexture.dispose(renderer); this._frameBuffer.dispose(renderer); }; var circularSeparateKernel = { component1: [ 0.014096,-0.022658, 0.055991,0.004413, -0.020612,-0.025574, 0.019188,0.000000, -0.038708,0.006957, 0.000000,0.049223, -0.021449,0.040468, 0.018301,0.099929, 0.013015,0.050223, 0.054845,0.114689, 0.042178,0.038585, 0.085769,0.097080, 0.057972,0.019812, 0.102517,0.068674, 0.063647,0.005252, 0.108535,0.046643, 0.064754,0.000000, 0.109709,0.038697, 0.063647,0.005252, 0.108535,0.046643, 0.057972,0.019812, 0.102517,0.068674, 0.042178,0.038585, 0.085769,0.097080, 0.013015,0.050223, 0.054845,0.114689, -0.021449,0.040468, 0.018301,0.099929, -0.038708,0.006957, 0.000000,0.049223, -0.020612,-0.025574, 0.019188,0.000000, 0.014096,-0.022658, 0.055991,0.00441 ], component2: [ 0.000115,0.009116, 0.000000,0.051147, 0.005324,0.013416, 0.009311,0.075276, 0.013753,0.016519, 0.024376,0.092685, 0.024700,0.017215, 0.043940,0.096591, 0.036693,0.015064, 0.065375,0.084521, 0.047976,0.010684, 0.085539,0.059948, 0.057015,0.005570, 0.101695,0.031254, 0.062782,0.001529, 0.112002,0.008578, 0.064754,0.000000, 0.115526,0.000000, 0.062782,0.001529, 0.112002,0.008578, 0.057015,0.005570, 0.101695,0.031254, 0.047976,0.010684, 0.085539,0.059948, 0.036693,0.015064, 0.065375,0.084521, 0.024700,0.017215, 0.043940,0.096591, 0.013753,0.016519, 0.024376,0.092685, 0.005324,0.013416, 0.009311,0.075276, 0.000115,0.009116, 0.000000,0.05114 ] }; var DOF_BLUR_OUTPUTS = { 'color': { 'parameters': { 'width': 'expr(width / 2.0 * 1.0)', 'height': 'expr(height / 2.0 * 1.0)', 'type': 'HALF_FLOAT' } } }; var DOF_BLUR_PARAMETERS = { 'textureSize': 'expr( [width / 2.0 * 1.0, height / 2.0 * 1.0] )' }; var effectJson = { 'type' : 'compositor', 'nodes' : [ { 'name': 'source', 'type': 'texture', 'outputs': { 'color': {} } }, { 'name': 'source_half', 'shader': '#source(clay.compositor.downsample)', 'inputs': { 'texture': 'source' }, 'outputs': { 'color': { 'parameters': { 'width': 'expr(width * 1.0 / 2)', 'height': 'expr(height * 1.0 / 2)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'textureSize': 'expr( [width * 1.0, height * 1.0] )' } }, { 'name' : 'bright', 'shader' : '#source(clay.compositor.bright)', 'inputs' : { 'texture' : 'source_half' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 2)', 'height' : 'expr(height * 1.0 / 2)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'threshold' : 2, 'scale': 4, 'textureSize': 'expr([width * 1.0 / 2, height / 2])' } }, { 'name': 'bright_downsample_4', 'shader' : '#source(clay.compositor.downsample)', 'inputs' : { 'texture' : 'bright' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 4)', 'height' : 'expr(height * 1.0 / 4)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'textureSize': 'expr( [width * 1.0 / 2, height / 2] )' } }, { 'name': 'bright_downsample_8', 'shader' : '#source(clay.compositor.downsample)', 'inputs' : { 'texture' : 'bright_downsample_4' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 8)', 'height' : 'expr(height * 1.0 / 8)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'textureSize': 'expr( [width * 1.0 / 4, height / 4] )' } }, { 'name': 'bright_downsample_16', 'shader' : '#source(clay.compositor.downsample)', 'inputs' : { 'texture' : 'bright_downsample_8' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 16)', 'height' : 'expr(height * 1.0 / 16)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'textureSize': 'expr( [width * 1.0 / 8, height / 8] )' } }, { 'name': 'bright_downsample_32', 'shader' : '#source(clay.compositor.downsample)', 'inputs' : { 'texture' : 'bright_downsample_16' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 32)', 'height' : 'expr(height * 1.0 / 32)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'textureSize': 'expr( [width * 1.0 / 16, height / 16] )' } }, { 'name' : 'bright_upsample_16_blur_h', 'shader' : '#source(clay.compositor.gaussian_blur)', 'inputs' : { 'texture' : 'bright_downsample_32' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 16)', 'height' : 'expr(height * 1.0 / 16)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'blurSize' : 1, 'blurDir': 0.0, 'textureSize': 'expr( [width * 1.0 / 32, height / 32] )' } }, { 'name' : 'bright_upsample_16_blur_v', 'shader' : '#source(clay.compositor.gaussian_blur)', 'inputs' : { 'texture' : 'bright_upsample_16_blur_h' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 16)', 'height' : 'expr(height * 1.0 / 16)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'blurSize' : 1, 'blurDir': 1.0, 'textureSize': 'expr( [width * 1.0 / 32, height * 1.0 / 32] )' } }, { 'name' : 'bright_upsample_8_blur_h', 'shader' : '#source(clay.compositor.gaussian_blur)', 'inputs' : { 'texture' : 'bright_downsample_16' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 8)', 'height' : 'expr(height * 1.0 / 8)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'blurSize' : 1, 'blurDir': 0.0, 'textureSize': 'expr( [width * 1.0 / 16, height * 1.0 / 16] )' } }, { 'name' : 'bright_upsample_8_blur_v', 'shader' : '#source(clay.compositor.gaussian_blur)', 'inputs' : { 'texture' : 'bright_upsample_8_blur_h' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 8)', 'height' : 'expr(height * 1.0 / 8)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'blurSize' : 1, 'blurDir': 1.0, 'textureSize': 'expr( [width * 1.0 / 16, height * 1.0 / 16] )' } }, { 'name' : 'bright_upsample_8_blend', 'shader' : '#source(clay.compositor.blend)', 'inputs' : { 'texture1' : 'bright_upsample_8_blur_v', 'texture2' : 'bright_upsample_16_blur_v' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 8)', 'height' : 'expr(height * 1.0 / 8)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'weight1' : 0.3, 'weight2' : 0.7 } }, { 'name' : 'bright_upsample_4_blur_h', 'shader' : '#source(clay.compositor.gaussian_blur)', 'inputs' : { 'texture' : 'bright_downsample_8' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 4)', 'height' : 'expr(height * 1.0 / 4)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'blurSize' : 1, 'blurDir': 0.0, 'textureSize': 'expr( [width * 1.0 / 8, height * 1.0 / 8] )' } }, { 'name' : 'bright_upsample_4_blur_v', 'shader' : '#source(clay.compositor.gaussian_blur)', 'inputs' : { 'texture' : 'bright_upsample_4_blur_h' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 4)', 'height' : 'expr(height * 1.0 / 4)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'blurSize' : 1, 'blurDir': 1.0, 'textureSize': 'expr( [width * 1.0 / 8, height * 1.0 / 8] )' } }, { 'name' : 'bright_upsample_4_blend', 'shader' : '#source(clay.compositor.blend)', 'inputs' : { 'texture1' : 'bright_upsample_4_blur_v', 'texture2' : 'bright_upsample_8_blend' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 4)', 'height' : 'expr(height * 1.0 / 4)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'weight1' : 0.3, 'weight2' : 0.7 } }, { 'name' : 'bright_upsample_2_blur_h', 'shader' : '#source(clay.compositor.gaussian_blur)', 'inputs' : { 'texture' : 'bright_downsample_4' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 2)', 'height' : 'expr(height * 1.0 / 2)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'blurSize' : 1, 'blurDir': 0.0, 'textureSize': 'expr( [width * 1.0 / 4, height * 1.0 / 4] )' } }, { 'name' : 'bright_upsample_2_blur_v', 'shader' : '#source(clay.compositor.gaussian_blur)', 'inputs' : { 'texture' : 'bright_upsample_2_blur_h' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 2)', 'height' : 'expr(height * 1.0 / 2)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'blurSize' : 1, 'blurDir': 1.0, 'textureSize': 'expr( [width * 1.0 / 4, height * 1.0 / 4] )' } }, { 'name' : 'bright_upsample_2_blend', 'shader' : '#source(clay.compositor.blend)', 'inputs' : { 'texture1' : 'bright_upsample_2_blur_v', 'texture2' : 'bright_upsample_4_blend' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0 / 2)', 'height' : 'expr(height * 1.0 / 2)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'weight1' : 0.3, 'weight2' : 0.7 } }, { 'name' : 'bright_upsample_full_blur_h', 'shader' : '#source(clay.compositor.gaussian_blur)', 'inputs' : { 'texture' : 'bright' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0)', 'height' : 'expr(height * 1.0)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'blurSize' : 1, 'blurDir': 0.0, 'textureSize': 'expr( [width * 1.0 / 2, height * 1.0 / 2] )' } }, { 'name' : 'bright_upsample_full_blur_v', 'shader' : '#source(clay.compositor.gaussian_blur)', 'inputs' : { 'texture' : 'bright_upsample_full_blur_h' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0)', 'height' : 'expr(height * 1.0)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'blurSize' : 1, 'blurDir': 1.0, 'textureSize': 'expr( [width * 1.0 / 2, height * 1.0 / 2] )' } }, { 'name' : 'bloom_composite', 'shader' : '#source(clay.compositor.blend)', 'inputs' : { 'texture1' : 'bright_upsample_full_blur_v', 'texture2' : 'bright_upsample_2_blend' }, 'outputs' : { 'color' : { 'parameters' : { 'width' : 'expr(width * 1.0)', 'height' : 'expr(height * 1.0)', 'type': 'HALF_FLOAT' } } }, 'parameters' : { 'weight1' : 0.3, 'weight2' : 0.7 } }, { 'name': 'coc', 'shader': '#source(car.dof.coc)', 'outputs': { 'color': { 'parameters': { 'width': 'expr(width * 1.0)', 'height': 'expr(height * 1.0)', 'type': 'HALF_FLOAT' } } } }, { 'name': 'coc_dilate_1', 'shader': '#source(car.dof.dilateCoc)', 'inputs': { 'cocTex': 'coc' }, 'outputs': { 'color': { 'parameters': { 'width': 'expr(width * 1.0)', 'height': 'expr(height * 1.0)', 'type': 'HALF_FLOAT' } } }, 'parameters': { 'textureSize': 'expr( [width / 1.0 * 1.0, height / 1.0 * 1.0] )' } }, { 'name': 'coc_dilate_2', 'shader': '#source(car.dof.dilateCoc)', 'inputs': { 'cocTex': 'coc_dilate_1' }, 'outputs': { 'color': { 'parameters': { 'width': 'expr(width * 1.0)', 'height': 'expr(height * 1.0)', 'type': 'HALF_FLOAT' } } }, 'parameters': { 'textureSize': 'expr( [width / 1.0 * 1.0, height / 1.0 * 1.0] )' }, 'defines': { 'VERTICAL': null } }, { 'name': 'dof_separate_far', 'shader': '#source(car.dof.separate)', 'inputs': { 'mainTex': 'source', 'cocTex': 'coc' }, 'outputs': DOF_BLUR_OUTPUTS, 'defines': { 'FARFIELD': null } }, { 'name': 'dof_separate_near', 'shader': '#source(car.dof.separate)', 'inputs': { 'mainTex': 'source', 'cocTex': 'coc' }, 'outputs': DOF_BLUR_OUTPUTS }, { 'name': 'dof_blur_far_1', 'shader': '#source(car.dof.blur)', 'inputs': { 'mainTex': 'dof_separate_far', 'cocTex': 'coc' }, 'outputs': DOF_BLUR_OUTPUTS, 'parameters': DOF_BLUR_PARAMETERS, 'defines': { 'R_PASS': null, 'FARFIELD': null } }, { 'name': 'dof_blur_far_2', 'shader': '#source(car.dof.blur)', 'inputs': { 'mainTex': 'dof_separate_far', 'cocTex': 'coc' }, 'outputs': DOF_BLUR_OUTPUTS, 'parameters': DOF_BLUR_PARAMETERS, 'defines': { 'G_PASS': null, 'FARFIELD': null } }, { 'name': 'dof_blur_far_3', 'shader': '#source(car.dof.blur)', 'inputs': { 'mainTex': 'dof_separate_far', 'cocTex': 'coc' }, 'outputs': DOF_BLUR_OUTPUTS, 'parameters': DOF_BLUR_PARAMETERS, 'defines': { 'B_PASS': null, 'FARFIELD': null } }, { 'name': 'dof_blur_far_4', 'shader': '#source(car.dof.blur)', 'inputs': { 'mainTex': 'dof_separate_far', 'cocTex': 'coc' }, 'outputs': DOF_BLUR_OUTPUTS, 'parameters': DOF_BLUR_PARAMETERS, 'defines': { 'A_PASS': null, 'FARFIELD': null } }, { 'name': 'dof_blur_far_final', 'shader': '#source(car.dof.blur)', 'inputs': { 'rTex': 'dof_blur_far_1', 'gTex': 'dof_blur_far_2', 'bTex': 'dof_blur_far_3', 'aTex': 'dof_blur_far_4', 'cocTex': 'coc' }, 'outputs': DOF_BLUR_OUTPUTS, 'parameters': DOF_BLUR_PARAMETERS, 'defines': { 'FINAL_PASS': null, 'FARFIELD': null } }, { 'name': 'dof_blur_near_1', 'shader': '#source(car.dof.blur)', 'inputs': { 'mainTex': 'dof_separate_near', 'cocTex': 'coc', 'dilateCocTex': 'coc_dilate_2' }, 'outputs': DOF_BLUR_OUTPUTS, 'parameters': DOF_BLUR_PARAMETERS, 'defines': { 'R_PASS': null } }, { 'name': 'dof_blur_near_2', 'shader': '#source(car.dof.blur)', 'inputs': { 'mainTex': 'dof_separate_near', 'cocTex': 'coc', 'dilateCocTex': 'coc_dilate_2' }, 'outputs': DOF_BLUR_OUTPUTS, 'parameters': DOF_BLUR_PARAMETERS, 'defines': { 'G_PASS': null } }, { 'name': 'dof_blur_near_3', 'shader': '#source(car.dof.blur)', 'inputs': { 'mainTex': 'dof_separate_near', 'cocTex': 'coc', 'dilateCocTex': 'coc_dilate_2' }, 'outputs': DOF_BLUR_OUTPUTS, 'parameters': DOF_BLUR_PARAMETERS, 'defines': { 'B_PASS': null } }, { 'name': 'dof_blur_near_4', 'shader': '#source(car.dof.blur)', 'inputs': { 'mainTex': 'dof_separate_near', 'cocTex': 'coc', 'dilateCocTex': 'coc_dilate_2' }, 'outputs': DOF_BLUR_OUTPUTS, 'parameters': DOF_BLUR_PARAMETERS, 'defines': { 'A_PASS': null } }, { 'name': 'dof_blur_near_final', 'shader': '#source(car.dof.blur)', 'inputs': { 'rTex': 'dof_blur_near_1', 'gTex': 'dof_blur_near_2', 'bTex': 'dof_blur_near_3', 'aTex': 'dof_blur_near_4', 'cocTex': 'coc', 'dilateCocTex': 'coc_dilate_2' }, 'outputs': DOF_BLUR_OUTPUTS, 'parameters': DOF_BLUR_PARAMETERS, 'defines': { 'FINAL_PASS': null } }, // { // 'name': 'dof_blur_near_alpha_h', // 'shader': '#source(car.dof.blurNearAlpha)', // 'inputs': { // 'mainTex': 'dof_blur_near_final', // 'cocTex': 'coc_dilate_2' // }, // 'outputs': DOF_BLUR_OUTPUTS, // 'parameters': { // 'textureSize': 'expr( [width / 2.0 * 1.0, height / 2.0 * 1.0] )', // 'blurDir': 0 // } // }, // { // 'name': 'dof_blur_near_alpha_v', // 'shader': '#source(car.dof.blurNearAlpha)', // 'inputs': { // 'mainTex': 'dof_blur_near_alpha_h', // 'cocTex': 'coc_dilate_2' // }, // 'outputs': DOF_BLUR_OUTPUTS, // 'parameters': { // 'textureSize': 'expr( [width / 2.0 * 1.0, height / 2.0 * 1.0] )', // 'blurDir': 1 // } // }, // { // 'name': 'dof_blur_upsample', // 'shader': '#source(car.dof.extraBlur)', // 'inputs': { // 'blur': 'dof_blur', // 'cocTex': 'coc' // }, // 'outputs': { // 'color': { // 'parameters': { // 'width': 'expr(width * 1.0)', // 'height': 'expr(height * 1.0)', // 'type': 'HALF_FLOAT' // } // } // }, // 'parameters': { // 'textureSize': 'expr( [width / 2.0 * 1.0, height / 2.0 * 1.0] )' // } // }, { 'name': 'dof_composite', 'shader': '#source(car.dof.composite)', 'inputs': { 'sharpTex': 'source', 'farTex': 'dof_blur_far_final', 'nearTex': 'dof_blur_near_final', 'cocTex': 'coc' }, 'outputs': { 'color': { 'parameters': { 'width': 'expr(width * 1.0)', 'height': 'expr(height * 1.0)', 'type': 'HALF_FLOAT' } } }, 'defines': { // DEBUG: 4 } }, { 'name' : 'composite', 'shader' : '#source(clay.compositor.hdr.composite)', 'inputs' : { 'texture': 'source', 'bloom' : 'bloom_composite' }, 'defines': { // Images are all premultiplied alpha before composite because of blending. // 'PREMULTIPLY_ALPHA': null, // 'DEBUG': 1 } }, { 'name' : 'FXAA', 'shader' : '#source(clay.compositor.fxaa)', 'inputs' : { 'texture' : 'composite' } } ] }; var dofCode = "@export car.dof.coc\nuniform sampler2D depth;\nuniform float zNear = 0.1;\nuniform float zFar = 2000;\nuniform float focalDistance = 10;\nuniform float focalLength = 50;\nuniform float aperture = 5.6;\nuniform float maxCoc;\nuniform float _filmHeight = 0.024;\nvarying vec2 v_Texcoord;\n@import clay.util.encode_float\nvoid main()\n{\n float z = texture2D(depth, v_Texcoord).r * 2.0 - 1.0;\n float dist = 2.0 * zNear * zFar / (zFar + zNear - z * (zFar - zNear));\n float f = focalLength / 1000.0;\n float s1 = max(f, focalDistance);\n float coeff = f * f / (aperture * (s1 - f) * _filmHeight * 2.0);\n float coc = (dist - focalDistance) * coeff / max(dist, 1e-5);\n coc /= maxCoc;\n gl_FragColor = vec4(clamp(coc * 0.5 + 0.5, 0.0, 1.0), 0.0, 0.0, 1.0);\n}\n@end\n@export car.dof.composite\n#define DEBUG 0\nuniform sampler2D sharpTex;\nuniform sampler2D nearTex;\nuniform sampler2D farTex;\nuniform sampler2D cocTex;\nuniform float maxCoc;\nuniform float minCoc;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nvoid main()\n{\n float coc = texture2D(cocTex, v_Texcoord).r * 2.0 - 1.0;\n vec4 nearTexel = decodeHDR(texture2D(nearTex, v_Texcoord));\n vec4 farTexel = decodeHDR(texture2D(farTex, v_Texcoord));\n vec4 sharpTexel = decodeHDR(texture2D(sharpTex, v_Texcoord));\n float nfa = clamp(nearTexel.a, 0.0, 1.0);\n float ffa = smoothstep(minCoc / maxCoc, 0.2, coc);\n ffa *= clamp(farTexel.a, 0.0, 1.0);\n gl_FragColor.rgb = mix(mix(sharpTexel.rgb, farTexel.rgb, ffa), nearTexel.rgb, nfa);\n gl_FragColor.a = max(max(sharpTexel.a, nfa), clamp(farTexel.a, 0.0, 1.0));\n}\n@end\n@export car.dof.separate\nuniform sampler2D mainTex;\nuniform sampler2D cocTex;\nuniform float minCoc;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 color = decodeHDR(texture2D(mainTex, v_Texcoord));\n float coc = texture2D(cocTex, v_Texcoord).r * 2.0 - 1.0;\n#ifdef FARFIELD\n color *= step(0.0, coc);\n#else\n color.a *= step(minCoc, -coc);\n#endif\n gl_FragColor = encodeHDR(color);\n}\n@end\n@export car.dof.dilateCoc\n#define SHADER_NAME dilateCoc\nuniform sampler2D cocTex;\nuniform vec2 textureSize;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n#ifdef VERTICAL\n vec2 offset = vec2(0.0, 1.0 / textureSize.y);\n#else\n vec2 offset = vec2(1.0 / textureSize.x, 0.0);\n#endif\n float coc0 = 1.0;\n for (int i = 0; i < 17; i++) {\n vec2 duv = (float(i) - 8.0) * offset * 1.5;\n float coc = texture2D(cocTex, v_Texcoord + duv).r * 2.0 - 1.0;\n coc *= pow(1.0 - abs(float(i) - 8.0) / 10.0, 2.0);\n coc0 = min(coc0, coc);\n }\n gl_FragColor = vec4(coc0 * 0.5 + 0.5, 0.0, 0.0, 1.0);\n}\n@end\n@export car.dof.blur\n#define KERNEL_SIZE 17\nconst vec2 kernel1Weight = vec2(0.411259,-0.548794);\nconst vec2 kernel2Weight = vec2(0.513282,4.561110);\nuniform vec4 kernel1[KERNEL_SIZE];\nuniform vec4 kernel2[KERNEL_SIZE];\n#ifdef FINAL_PASS\nuniform sampler2D rTex;\nuniform sampler2D gTex;\nuniform sampler2D bTex;\nuniform sampler2D aTex;\n#endif\nuniform sampler2D mainTex;\nuniform sampler2D cocTex;\nuniform sampler2D dilateCocTex;\nuniform float maxCoc;\nuniform float minCoc;\nuniform vec2 textureSize;\nvarying vec2 v_Texcoord;\nvec2 multComplex(vec2 p, vec2 q)\n{\n return vec2(p.x*q.x-p.y*q.y, p.x*q.y+p.y*q.x);\n}\nfloat GetSmallestCoc(vec2 uv)\n{\n vec2 k = 1.0 / textureSize;\n float coc = texture2D(cocTex, uv).r;\n vec4 around = vec4(\n texture2D(cocTex, uv - k).r,\n texture2D(cocTex, uv + vec2(k.x, -k.y)).r,\n texture2D(cocTex, uv + vec2(-k.x, k.y)).r,\n texture2D(cocTex, uv + k).r\n );\n return min(min(min(min(around.x, around.y), around.z), around.w), coc);\n}\n@import clay.util.rgbm\n@import clay.util.float\nvoid main()\n{\n float halfKernelSize = float(KERNEL_SIZE / 2);\n vec2 texelSize = 1.0 / textureSize;\n float weight = 0.0;\n#ifdef FARFIELD\n float coc0 = texture2D(cocTex, v_Texcoord).r * 2.0 - 1.0;\n#else\n float coc0 = -(texture2D(dilateCocTex, v_Texcoord).r * 2.0 - 1.0);\n#endif\n if (coc0 <= 0.0) {\n gl_FragColor = vec4(0.0);\n return;\n }\n coc0 *= maxCoc;\n#ifdef FINAL_PASS\n vec4 valR = vec4(0.0);\n vec4 valG = vec4(0.0);\n vec4 valB = vec4(0.0);\n vec4 valA = vec4(0.0);\n vec2 offset = vec2(0.0, abs(coc0) / halfKernelSize);\n#else\n vec4 val = vec4(0.0);\n vec2 offset = vec2(texelSize.x / texelSize.y * abs(coc0) / halfKernelSize, 0.0);\n#endif\n for (int i = 0; i < KERNEL_SIZE; i++) {\n vec2 duv = (float(i) - halfKernelSize) * offset;\n float dist = length(duv);\n vec2 uv = clamp(v_Texcoord + duv, vec2(0.0), vec2(1.0));\n#ifdef FARFIELD\n float coc = GetSmallestCoc(uv) * 2.0 - 1.0;\n#else\n float coc = texture2D(cocTex, uv).r * 2.0 - 1.0;\n#endif\n coc *= maxCoc;\n float w = 1.0;\n#ifdef FARFIELD\n w *= step(dist, coc);\n#endif\n weight += w;\n vec4 c0c1 = vec4(kernel1[i].xy, kernel2[i].xy);\n#ifdef FINAL_PASS\n vec4 rTexel = texture2D(rTex, uv) * w;\n vec4 gTexel = texture2D(gTex, uv) * w;\n vec4 bTexel = texture2D(bTex, uv) * w;\n vec4 aTexel = texture2D(aTex, uv) * w;\n valR.xy += multComplex(rTexel.xy,c0c1.xy);\n valR.zw += multComplex(rTexel.zw,c0c1.zw);\n valG.xy += multComplex(gTexel.xy,c0c1.xy);\n valG.zw += multComplex(gTexel.zw,c0c1.zw);\n valB.xy += multComplex(bTexel.xy,c0c1.xy);\n valB.zw += multComplex(bTexel.zw,c0c1.zw);\n valA.xy += multComplex(aTexel.xy,c0c1.xy);\n valA.zw += multComplex(aTexel.zw,c0c1.zw);\n#else\n vec4 color = texture2D(mainTex, uv);\n float tmp;\n #if defined(R_PASS)\n tmp = color.r;\n #elif defined(G_PASS)\n tmp = color.g;\n #elif defined(B_PASS)\n tmp = color.b;\n #elif defined(A_PASS)\n tmp = color.a;\n #endif\n val += tmp * c0c1 * w;\n#endif\n }\n weight /= float(KERNEL_SIZE);\n weight = max(weight, 0.0001);\n#ifdef FINAL_PASS\n valR /= weight;\n valG /= weight;\n valB /= weight;\n valA /= weight;\n float r = dot(valR.xy,kernel1Weight)+dot(valR.zw,kernel2Weight);\n float g = dot(valG.xy,kernel1Weight)+dot(valG.zw,kernel2Weight);\n float b = dot(valB.xy,kernel1Weight)+dot(valB.zw,kernel2Weight);\n float a = dot(valA.xy,kernel1Weight)+dot(valA.zw,kernel2Weight);\n gl_FragColor = vec4(r, g, b, a);\n#else\n val /= weight;\n gl_FragColor = val;\n#endif\n}\n@end\n// @end"; var temporalBlendCode = "@export car.temporalBlend\nuniform sampler2D prevTex;\nuniform sampler2D currTex;\nuniform sampler2D velocityTex;\nuniform float stillBlending = 0.95;\nuniform float motionBlending = 0.5;\nvarying vec2 v_Texcoord;\nvoid main() {\n vec4 vel = texture2D(velocityTex, v_Texcoord);\n vec2 motion = vel.rg - 0.5;\n vec4 curr = texture2D(currTex, v_Texcoord);\n vec4 prev = texture2D(prevTex, v_Texcoord - motion);\n if (vel.a < 0.01) {\n gl_FragColor = curr;\n }\n else {\n float motionLength = length(motion);\n float weight = clamp(\n mix(stillBlending, motionBlending, motionLength * 1000.0),\n motionBlending, stillBlending\n );\n gl_FragColor = mix(curr, prev, weight);\n }\n}\n@end"; var GBuffer = claygl.deferred.GBuffer; claygl.Shader.import(dofCode); claygl.Shader.import(temporalBlendCode); var commonOutputs = { color: { parameters: { width: function (renderer) { return renderer.getWidth(); }, height: function (renderer) { return renderer.getHeight(); } } } }; var FINAL_NODES_CHAIN = ['composite', 'FXAA']; function EffectCompositor() { this._gBufferPass = new GBuffer({ renderTransparent: true, enableTargetTexture3: false, enableTargetTexture4: true }); this._compositor = claygl.createCompositor(effectJson); var sourceNode = this._compositor.getNodeByName('source'); var cocNode = this._compositor.getNodeByName('coc'); this._sourceNode = sourceNode; this._cocNode = cocNode; this._compositeNode = this._compositor.getNodeByName('composite'); this._fxaaNode = this._compositor.getNodeByName('FXAA'); this._dofBlurNodes = [ 'dof_blur_far_1', 'dof_blur_far_2', 'dof_blur_far_3', 'dof_blur_far_4', 'dof_blur_far_final', 'dof_blur_near_1', 'dof_blur_near_2', 'dof_blur_near_3', 'dof_blur_near_4', 'dof_blur_near_final' ].map(function (name) { return this._compositor.getNodeByName(name); }, this); this._dofFarFieldNode = this._compositor.getNodeByName('dof_separate_far'); this._dofNearFieldNode = this._compositor.getNodeByName('dof_separate_near'); this._dofCompositeNode = this._compositor.getNodeByName('dof_composite'); this._dofBlurKernel = null; this._dofBlurKernelSize = new Float32Array(0); this._finalNodesChain = FINAL_NODES_CHAIN.map(function (name) { return this._compositor.getNodeByName(name); }, this); var gBufferObj = { normalTexture: this._gBufferPass.getTargetTexture1(), depthTexture: this._gBufferPass.getTargetTexture2(), albedoTexture: this._gBufferPass.getTargetTexture3(), velocityTexture: this._gBufferPass.getTargetTexture4() }; this._ssaoPass = new SSAOPass(gBufferObj); this._ssrPass = new SSRPass(gBufferObj); } EffectCompositor.prototype.resize = function (width, height, dpr) { dpr = dpr || 1; width = width * dpr; height = height * dpr; this._gBufferPass.resize(width, height); }; EffectCompositor.prototype._ifRenderNormalPass = function () { // return this._enableSSAO || this._enableEdge || this._enableSSR; return true; }; EffectCompositor.prototype._getPrevNode = function (node) { var idx = FINAL_NODES_CHAIN.indexOf(node.name) - 1; var prevNode = this._finalNodesChain[idx]; while (prevNode && !this._compositor.getNodeByName(prevNode.name)) { idx -= 1; prevNode = this._finalNodesChain[idx]; } return prevNode; }; EffectCompositor.prototype._getNextNode = function (node) { var idx = FINAL_NODES_CHAIN.indexOf(node.name) + 1; var nextNode = this._finalNodesChain[idx]; while (nextNode && !this._compositor.getNodeByName(nextNode.name)) { idx += 1; nextNode = this._finalNodesChain[idx]; } return nextNode; }; EffectCompositor.prototype._addChainNode = function (node) { var prevNode = this._getPrevNode(node); var nextNode = this._getNextNode(node); if (!prevNode) { return; } prevNode.outputs = commonOutputs; node.inputs.texture = prevNode.name; if (nextNode) { node.outputs = commonOutputs; nextNode.inputs.texture = node.name; } else { node.outputs = null; } this._compositor.addNode(node); }; EffectCompositor.prototype._removeChainNode = function (node) { var prevNode = this._getPrevNode(node); var nextNode = this._getNextNode(node); if (!prevNode) { return; } if (nextNode) { prevNode.outputs = commonOutputs; nextNode.inputs.texture = prevNode.name; } else { prevNode.outputs = null; } this._compositor.removeNode(node); }; /** * Update normal */ EffectCompositor.prototype.updateGBuffer = function (renderer, scene, camera, frame) { if (this._ifRenderNormalPass()) { this._gBufferPass.update(renderer, scene, camera); } }; /** * Render SSAO after render the scene, before compositing */ EffectCompositor.prototype.updateSSAO = function (renderer, scene, camera, frame) { this._ssaoPass.update(renderer, camera, frame); }; EffectCompositor.prototype.updateSSR = function (renderer, scene, camera, sourceTexture, reflectionSourceTexture, frame) { this._ssrPass.setSSAOTexture( this._enableSSAO ? this._ssaoPass.getTargetTexture() : null ); var lights = scene.getLights(); for (var i = 0; i < lights.length; i++) { if (lights[i].cubemap) { this._ssrPass.setAmbientCubemap( lights[i].cubemap, // lights[i].getBRDFLookup(), lights[i]._brdfLookup, lights[i].intensity ); } } this._ssrPass.update(renderer, camera, sourceTexture, reflectionSourceTexture, frame); }; /** * Enable SSAO effect */ EffectCompositor.prototype.enableSSAO = function () { this._enableSSAO = true; }; /** * Disable SSAO effect */ EffectCompositor.prototype.disableSSAO = function () { this._enableSSAO = false; }; EffectCompositor.prototype.enableVelocityBuffer = function () { this._gBufferPass.enableTargetTexture4 = true; }; EffectCompositor.prototype.disableVelocityBuffer = function () { this._gBufferPass.enableTargetTexture4 = false; }; /** * Enable SSR effect */ EffectCompositor.prototype.enableSSR = function () { this._enableSSR = true; this._gBufferPass.enableTargetTexture3 = true; }; /** * Disable SSR effect */ EffectCompositor.prototype.disableSSR = function () { this._enableSSR = false; this._gBufferPass.enableTargetTexture3 = false; }; /** * Render SSAO after render the scene, before compositing */ EffectCompositor.prototype.getSSAOTexture = function () { return this._ssaoPass.getTargetTexture(); }; EffectCompositor.prototype.getSSRTexture = function () { return this._ssrPass.getTargetTexture(); }; EffectCompositor.prototype.getVelocityTexture = function () { return this._gBufferPass.getTargetTexture4(); }; EffectCompositor.prototype.getDepthTexture = function () { return this._gBufferPass.getTargetTexture2(); }; /** * Disable fxaa effect */ EffectCompositor.prototype.disableFXAA = function () { this._removeChainNode(this._fxaaNode); }; /** * Enable fxaa effect */ EffectCompositor.prototype.enableFXAA = function () { this._addChainNode(this._fxaaNode); }; /** * Enable bloom effect */ EffectCompositor.prototype.enableBloom = function () { this._compositeNode.inputs.bloom = 'bloom_composite'; this._compositor.dirty(); }; /** * Disable bloom effect */ EffectCompositor.prototype.disableBloom = function () { this._compositeNode.inputs.bloom = null; this._compositor.dirty(); }; /** * Enable depth of field effect */ EffectCompositor.prototype.enableDOF = function () { this._compositeNode.inputs.texture = 'dof_composite'; this._compositor.dirty(); }; /** * Disable depth of field effect */ EffectCompositor.prototype.disableDOF = function () { this._compositeNode.inputs.texture = 'source'; this._compositor.dirty(); }; /** * Enable color correction */ EffectCompositor.prototype.enableColorCorrection = function () { this._compositeNode.define('COLOR_CORRECTION'); this._enableColorCorrection = true; }; /** * Disable color correction */ EffectCompositor.prototype.disableColorCorrection = function () { this._compositeNode.undefine('COLOR_CORRECTION'); this._enableColorCorrection = false; }; /** * Enable edge detection */ EffectCompositor.prototype.enableEdge = function () { this._enableEdge = true; }; /** * Disable edge detection */ EffectCompositor.prototype.disableEdge = function () { this._enableEdge = false; }; /** * Set bloom intensity * @param {number} value */ EffectCompositor.prototype.setBloomIntensity = function (value) { if (value == null) { return; } this._compositeNode.setParameter('bloomIntensity', value); }; EffectCompositor.prototype.setSSAOParameter = function (name, value) { if (value == null) { return; } switch (name) { case 'quality': // PENDING var kernelSize = ({ low: 6, medium: 12, high: 32, ultra: 62 })[value] || 12; this._ssaoPass.setParameter('kernelSize', kernelSize); break; case 'radius': this._ssaoPass.setParameter(name, value); this._ssaoPass.setParameter('bias', value / 50); break; case 'intensity': case 'temporalFilter': this._ssaoPass.setParameter(name, value); break; } }; EffectCompositor.prototype.setDOFParameter = function (name, value) { if (value == null) { return; } switch (name) { case 'focalDistance': case 'focalRange': case 'aperture': this._cocNode.setParameter(name, value); break; case 'blurRadius': this._dofBlurRadius = value; break; // case 'quality': // this._dofBlurKernel = poissonKernel[value] || poissonKernel.medium; // var kernelSize = this._dofBlurKernel.length / 2; // for (var i = 0; i < this._dofBlurNodes.length; i++) { // this._dofBlurNodes[i].define('POISSON_KERNEL_SIZE', kernelSize); // } // break; } }; EffectCompositor.prototype.setSSRParameter = function (name, value) { if (value == null) { return; } switch (name) { case 'quality': // PENDING var maxIteration = ({ low: 10, medium: 15, high: 30, ultra: 80 })[value] || 20; var pixelStride = ({ low: 32, medium: 16, high: 8, ultra: 4 })[value] || 16; this._ssrPass.setParameter('maxIteration', maxIteration); this._ssrPass.setParameter('pixelStride', pixelStride); break; case 'maxRoughness': this._ssrPass.setParameter('minGlossiness', Math.max(Math.min(1.0 - value, 1.0), 0.0)); break; case 'physical': this.setPhysicallyCorrectSSR(value); break; default: console.warn('Unkown SSR parameter ' + name); } }; EffectCompositor.prototype.setPhysicallyCorrectSSR = function (physical) { this._ssrPass.setPhysicallyCorrect(physical); }; /** * Set color of edge */ EffectCompositor.prototype.setEdgeColor = function (value) { // if (value == null) { // return; // } // this._edgePass.setParameter('edgeColor', value); }; EffectCompositor.prototype.setExposure = function (value) { if (value == null) { return; } this._compositeNode.setParameter('exposure', Math.pow(2, value)); }; EffectCompositor.prototype.setColorLookupTexture = function (image, api) { // this._compositeNode.pass.material.setTextureImage('lut', this._enableColorCorrection ? image : 'none', api, { // minFilter: Texture.NEAREST, // magFilter: Texture.NEAREST, // flipY: false // }); }; EffectCompositor.prototype.setColorCorrection = function (type, value) { this._compositeNode.setParameter(type, value); }; EffectCompositor.prototype.composite = function (renderer, scene, camera, sourceTexture, depthTexture, frame) { this._sourceNode.texture = sourceTexture; this._cocNode.setParameter('depth', depthTexture); // var blurKernel = this._dofBlurKernel; var maxCoc = this._dofBlurRadius || 10; maxCoc /= renderer.getHeight(); // var minCoc = 1 / renderer.getHeight(); var minCoc = 0; // var jitter = Math.random(); for (var i = 0; i < this._dofBlurNodes.length; i++) { var blurNode = this._dofBlurNodes[i]; blurNode.setParameter('kernel1', circularSeparateKernel.component1); blurNode.setParameter('kernel2', circularSeparateKernel.component2); blurNode.setParameter('maxCoc', maxCoc); blurNode.setParameter('minCoc', minCoc); } this._cocNode.setParameter('maxCoc', maxCoc); this._dofCompositeNode.setParameter('maxCoc', maxCoc); this._dofCompositeNode.setParameter('minCoc', minCoc); this._dofFarFieldNode.setParameter('minCoc', minCoc / maxCoc); this._dofNearFieldNode.setParameter('minCoc', minCoc / maxCoc); this._cocNode.setParameter('zNear', camera.near); this._cocNode.setParameter('zFar', camera.far); this._compositor.render(renderer); }; EffectCompositor.prototype.isSSRFinished = function (frame) { return this._ssrPass ? this._ssrPass.isFinished(frame) : true; }; EffectCompositor.prototype.isSSAOFinished = function (frame) { return this._ssaoPass ? this._ssaoPass.isFinished(frame) : true; }; EffectCompositor.prototype.isSSREnabled = function () { return this._enableSSR; }; EffectCompositor.prototype.dispose = function (renderer) { this._compositor.dispose(renderer); this._gBufferPass.dispose(renderer); this._ssaoPass.dispose(renderer); }; var TAAGLSLCode = "@export car.taa\n#define SHADER_NAME TAA3\nuniform sampler2D prevTex;\nuniform sampler2D currTex;\nuniform sampler2D velocityTex;\nuniform sampler2D depthTex;\nuniform vec2 texelSize;\nuniform vec2 velocityTexelSize;\nuniform vec2 jitterOffset;\nuniform bool still;\nuniform float stillBlending = 0.95;\nuniform float motionBlending = 0.85;\nuniform float sharpness = 0.25;\nuniform float motionAmplification = 6000;\nvarying vec2 v_Texcoord;\nfloat Luminance(vec4 color)\n{\n return dot(color.rgb, vec3(0.2125, 0.7154, 0.0721));\n}\nfloat compareDepth(float a, float b)\n{\n return step(a, b);\n}\nvec2 GetClosestFragment(vec2 uv)\n{\n vec2 k = velocityTexelSize.xy;\n vec4 neighborhood = vec4(\n texture2D(depthTex, uv - k).r,\n texture2D(depthTex, uv + vec2(k.x, -k.y)).r,\n texture2D(depthTex, uv + vec2(-k.x, k.y)).r,\n texture2D(depthTex, uv + k).r\n );\n vec3 result = vec3(0.0, 0.0, texture2D(depthTex, uv));\n result = mix(result, vec3(-1.0, -1.0, neighborhood.x), compareDepth(neighborhood.x, result.z));\n result = mix(result, vec3( 1.0, -1.0, neighborhood.y), compareDepth(neighborhood.y, result.z));\n result = mix(result, vec3(-1.0, 1.0, neighborhood.z), compareDepth(neighborhood.z, result.z));\n result = mix(result, vec3( 1.0, 1.0, neighborhood.w), compareDepth(neighborhood.w, result.z));\n return (uv + result.xy * k);\n}\nvec4 ClipToAABB(vec4 color, vec3 minimum, vec3 maximum)\n{\n vec3 center = 0.5 * (maximum + minimum);\n vec3 extents = 0.5 * (maximum - minimum);\n vec3 offset = color.rgb - center;\n vec3 ts = abs(extents / (offset + 0.0001));\n float t = clamp(min(min(ts.x, ts.y), ts.z), 0.0, 1.0);\n color.rgb = center + offset * t;\n return color;\n}\nvec4 Tonemap(vec4 color)\n{\n return vec4(color.rgb / (Luminance(color) + 1.0), color.a);\n}\nvec4 Untonemap(vec4 color)\n{\n return vec4(color.rgb / max(1.0 - Luminance(color), 0.0001), color.a);\n}\nvoid main()\n{\n vec2 closest = GetClosestFragment(v_Texcoord);\n vec4 motionTexel = texture2D(velocityTex, closest);\n if (still) {\n gl_FragColor = Untonemap(\n mix(\n Tonemap(texture2D(currTex, v_Texcoord)),\n Tonemap(texture2D(prevTex, v_Texcoord)),\n stillBlending\n )\n );\n return;\n }\n if (motionTexel.a < 0.1) {\n gl_FragColor = texture2D(currTex, v_Texcoord);\n return;\n }\n vec2 motion = motionTexel.rg - 0.5;\n vec2 k = texelSize.xy;\n vec2 uv = v_Texcoord;\n vec4 color = texture2D(currTex, uv);\n vec4 topLeft = texture2D(currTex, uv - k * 0.5);\n vec4 bottomRight = texture2D(currTex, uv + k * 0.5);\n vec4 corners = 4.0 * (topLeft + bottomRight) - 2.0 * color;\n vec4 average = (corners + color) * 0.142857;\n vec4 history = texture2D(prevTex, v_Texcoord - motion);\n float motionLength = length(motion);\n vec2 luma = vec2(Luminance(average), Luminance(color));\n float nudge = mix(4.0, 0.25, clamp(motionLength * 100.0, 0.0, 1.0)) * abs(luma.x - luma.y);\n vec4 minimum = min(bottomRight, topLeft) - nudge;\n vec4 maximum = max(topLeft, bottomRight) + nudge;\n history = ClipToAABB(history, minimum.xyz, maximum.xyz);\n float weight = clamp(\n mix(stillBlending, motionBlending, motionLength * motionAmplification),\n motionBlending, stillBlending\n );\n color = mix(Tonemap(color), Tonemap(history), weight);\n color = Untonemap(clamp(color, 0.0, 1.0));\n gl_FragColor = color;\n}\n@end"; // Temporal Super Sample for static Scene var Pass$2 = claygl.compositor.Pass; claygl.Shader.import(TAAGLSLCode); function TemporalSuperSampling (opt) { opt = opt || {}; var haltonSequence = []; for (var i = 0; i < 30; i++) { haltonSequence.push([ halton(i, 2), halton(i, 3) ]); } this._haltonSequence = haltonSequence; this._frame = 0; // Frame texture before temporal supersampling this._prevFrameTex = new claygl.Texture2D({ type: claygl.Texture.HALF_FLOAT }); this._outputTex = new claygl.Texture2D({ type: claygl.Texture.HALF_FLOAT }); this._taaPass = new Pass$2({ fragment: claygl.Shader.source('car.taa') }); this._velocityTex = opt.velocityTexture; this._depthTex = opt.depthTexture; this._taaFb = new claygl.FrameBuffer({ depthBuffer: false }); this._outputPass = new Pass$2({ fragment: claygl.Shader.source('clay.compositor.output'), // TODO, alpha is premultiplied? blendWithPrevious: true }); this._outputPass.material.define('fragment', 'OUTPUT_ALPHA'); this._outputPass.material.blend = function (_gl) { // FIXME. // Output is premultiplied alpha when BLEND is enabled ? // http://stackoverflow.com/questions/2171085/opengl-blending-with-previous-contents-of-framebuffer _gl.blendEquationSeparate(_gl.FUNC_ADD, _gl.FUNC_ADD); _gl.blendFuncSeparate(_gl.ONE, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA); }; } TemporalSuperSampling.prototype = { constructor: TemporalSuperSampling, /** * Jitter camera projectionMatrix * @parma {clay.Renderer} renderer * @param {clay.Camera} camera */ jitterProjection: function (renderer, camera) { var offset = this._haltonSequence[this._frame % this._haltonSequence.length]; var viewport = renderer.viewport; var dpr = viewport.devicePixelRatio || renderer.getDevicePixelRatio(); var width = viewport.width * dpr; var height = viewport.height * dpr; var translationMat = new claygl.Matrix4(); translationMat.array[12] = (offset[0] * 2.0 - 1.0) / width; translationMat.array[13] = (offset[1] * 2.0 - 1.0) / height; claygl.Matrix4.mul(camera.projectionMatrix, translationMat, camera.projectionMatrix); claygl.Matrix4.invert(camera.invProjectionMatrix, camera.projectionMatrix); }, getJitterOffset: function (renderer) { var offset = this._haltonSequence[this._frame % this._haltonSequence.length]; var viewport = renderer.viewport; var dpr = viewport.devicePixelRatio || renderer.getDevicePixelRatio(); var width = viewport.width * dpr; var height = viewport.height * dpr; return [ offset[0] / width, offset[1] / height ]; }, /** * Reset accumulating frame */ resetFrame: function () { this._frame = 0; }, /** * Return current frame */ getFrame: function () { return this._frame; }, getTargetTexture: function () { return this._prevFrameTex; }, // getPrevFrameTexture: function () { // return this._outputTex; // }, resize: function (width, height) { this._prevFrameTex.width = width; this._prevFrameTex.height = height; this._outputTex.width = width; this._outputTex.height = height; }, isFinished: function () { return this._frame >= this._haltonSequence.length; }, render: function (renderer, camera, sourceTex, still, output) { var taaPass = this._taaPass; taaPass.setUniform('jitterOffset', this.getJitterOffset(renderer)); taaPass.setUniform('velocityTex', this._velocityTex); taaPass.setUniform('prevTex', this._prevFrameTex); taaPass.setUniform('currTex', sourceTex); taaPass.setUniform('depthTex', this._depthTex); taaPass.setUniform('texelSize', [1 / sourceTex.width, 1 / sourceTex.height]); taaPass.setUniform('velocityTexelSize', [1 / this._depthTex.width, 1 / this._depthTex.height]); taaPass.setUniform('still', !!still); if (still) { taaPass.setUniform('stillBlending', this._frame === 0 ? 0 : 0.95); } this._taaFb.attach(this._outputTex); this._taaFb.bind(renderer); taaPass.render(renderer); this._taaFb.unbind(renderer); if (output) { this._outputPass.setUniform('texture', this._outputTex); this._outputPass.render(renderer); } // Swap texture var tmp = this._prevFrameTex; this._prevFrameTex = this._outputTex; this._outputTex = tmp; this._frame++; }, dispose: function (renderer) { this._taaFb.dispose(renderer); this._prevFrameTex.dispose(renderer); this._outputTex.dispose(renderer); this._outputPass.dispose(renderer); this._taaPass.dispose(renderer); } }; var ShadowMapPass = claygl.prePass.ShadowMap; function RenderMain(renderer, scene, enableShadow) { this.renderer = renderer; this.scene = scene; this.preZ = true; this._compositor = new EffectCompositor(); this._temporalSS = new TemporalSuperSampling({ velocityTexture: this._compositor.getVelocityTexture(), depthTexture: this._compositor.getDepthTexture() }); if (enableShadow) { this._shadowMapPass = new ShadowMapPass({ lightFrustumBias: 20 }); } this._enableTemporalSS = 'auto'; scene.on('beforerender', function (renderer, scene, camera) { if (this.needsTemporalSS()) { this._temporalSS.jitterProjection(renderer, camera); } }, this); this._framebuffer = new claygl.FrameBuffer(); this._sourceTex = new claygl.Texture2D({ type: claygl.Texture.HALF_FLOAT }); this._depthTex = new claygl.Texture2D({ format: claygl.Texture.DEPTH_COMPONENT, type: claygl.Texture.UNSIGNED_INT }); } /** * Cast a ray * @param {number} x offsetX * @param {number} y offsetY * @param {clay.math.Ray} out * @return {clay.math.Ray} */ var ndc = new claygl.Vector2(); RenderMain.prototype.castRay = function (x, y, out) { var renderer = this.layer.renderer; var oldViewport = renderer.viewport; renderer.viewport = this.viewport; renderer.screenToNDC(x, y, ndc); this.camera.castRay(ndc, out); renderer.viewport = oldViewport; return out; }; /** * Prepare and update scene before render */ RenderMain.prototype.prepareRender = function () { var scene = this.scene; var camera = scene.getMainCamera(); var renderer = this.renderer; camera.aspect = renderer.getViewportAspect(); scene.update(); scene.updateLights(); var renderList = scene.updateRenderList(camera); this._updateSRGBOfList(renderList.opaque); this._updateSRGBOfList(renderList.transparent); this._frame = 0; if (!this._temporalSupportDynamic) { this._temporalSS.resetFrame(); } var lights = scene.getLights(); for (var i = 0; i < lights.length; i++) { if (lights[i].cubemap) { if (this._compositor && this._compositor.isSSREnabled()) { lights[i].invisible = true; } else { lights[i].invisible = false; } } } if (this._enablePostEffect) { this._compositor.resize(renderer.getWidth(), renderer.getHeight(), renderer.getDevicePixelRatio()); } if (this._temporalSS) { this._temporalSS.resize(renderer.getWidth(), renderer.getHeight()); } }; RenderMain.prototype.render = function (accumulating) { var scene = this.scene; var camera = scene.getMainCamera(); this._doRender(scene, camera, accumulating, this._frame); this._frame++; }; RenderMain.prototype.needsAccumulate = function () { return this.needsTemporalSS(); }; RenderMain.prototype.needsTemporalSS = function () { var enableTemporalSS = this._enableTemporalSS; if (enableTemporalSS === 'auto') { enableTemporalSS = this._enablePostEffect; } return enableTemporalSS; }; RenderMain.prototype.hasDOF = function () { return this._enableDOF; }; RenderMain.prototype.isAccumulateFinished = function () { var frame = this._frame; return !(this.needsTemporalSS() && !this._temporalSS.isFinished(frame)) && !(this._compositor && !this._compositor.isSSAOFinished(frame)) && !(this._compositor && !this._compositor.isSSRFinished(frame)) && !(this._compositor && frame < 30); }; RenderMain.prototype._doRender = function (scene, camera, accumulating, accumFrame) { var renderer = this.renderer; accumFrame = accumFrame || 0; if (!accumulating && this._shadowMapPass) { this._shadowMapPass.kernelPCF = this._pcfKernels[0]; // Not render shadowmap pass in accumulating frame. this._shadowMapPass.render(renderer, scene, camera, true); } this._updateShadowPCFKernel(scene, camera, accumFrame); // Shadowmap will set clearColor. renderer.gl.clearColor(0.0, 0.0, 0.0, 0.0); if (this._enablePostEffect) { // normal render also needs to be jittered when have edge pass. if (this.needsTemporalSS()) { this._temporalSS.jitterProjection(renderer, camera); } this._compositor.updateGBuffer(renderer, scene, camera, this._temporalSS.getFrame()); } // Always update SSAO to make sure have correct ssaoMap status // TODO TRANSPARENT OBJECTS. this._updateSSAO(renderer, scene, camera, accumulating ? this._temporalSS.getFrame() : 0); var frameBuffer; var needTemporalPass = this.needsTemporalSS() && (this._temporalSupportDynamic || accumulating); var needPostEffect = this._enablePostEffect; if (!needTemporalPass && !needPostEffect) { renderer.render(scene, camera, true, this.preZ); this.afterRenderScene(renderer, scene, camera); } else { var isSSREnabled = this._compositor.isSSREnabled(); var sourceTex = this._sourceTex; var depthTex = this._depthTex; var frameBuffer = this._framebuffer; depthTex.width = sourceTex.width = renderer.getWidth(); depthTex.height = sourceTex.height = renderer.getHeight(); frameBuffer.attach(sourceTex); frameBuffer.attach(depthTex, claygl.FrameBuffer.DEPTH_ATTACHMENT); frameBuffer.bind(renderer); renderer.gl.clear(renderer.gl.DEPTH_BUFFER_BIT | renderer.gl.COLOR_BUFFER_BIT); renderer.render(scene, camera, true, this.preZ); this.afterRenderScene(renderer, scene, camera); frameBuffer.unbind(renderer); if (isSSREnabled && needPostEffect) { this._compositor.updateSSR( renderer, scene, camera, sourceTex, // TODO reprojection needTemporalPass ? this._temporalSS.getTargetTexture() : sourceTex, this._temporalSS.getFrame() ); sourceTex = this._compositor.getSSRTexture(); } if (needTemporalPass) { var directOutput = !needPostEffect; this._temporalSS.render(renderer, camera, sourceTex, accumulating, directOutput); sourceTex = this._temporalSS.getTargetTexture(); } if (needPostEffect) { this._compositor.composite( renderer, scene, camera, sourceTex, depthTex, needTemporalPass ? this._temporalSS.getFrame() : 0, accumulating ); } } this.afterRenderAll(renderer, scene, camera); }; RenderMain.prototype._updateSRGBOfList = function (list) { var isLinearSpace = this.isLinearSpace(); for (var i = 0; i < list.length; i++) { list[i].material[isLinearSpace ? 'define' : 'undefine']('fragment', 'SRGB_DECODE'); } }; RenderMain.prototype.afterRenderScene = function (renderer, scene, camera) {}; RenderMain.prototype.afterRenderAll = function (renderer, scene, camera) {}; RenderMain.prototype._updateSSAO = function (renderer, scene, camera, frame) { var ifEnableSSAO = this._enableSSAO && this._enablePostEffect; var compositor$$1 = this._compositor; if (ifEnableSSAO) { this._compositor.updateSSAO(renderer, scene, camera, this._temporalSS.getFrame()); } function updateQueue(queue) { for (var i = 0; i < queue.length; i++) { var renderable = queue[i]; renderable.material[ifEnableSSAO ? 'enableTexture' : 'disableTexture']('ssaoMap'); if (ifEnableSSAO) { renderable.material.set('ssaoMap', compositor$$1.getSSAOTexture()); } } } updateQueue(scene.getRenderList(camera).opaque); updateQueue(scene.getRenderList(camera).transparent); }; RenderMain.prototype._updateShadowPCFKernel = function (scene, camera, frame) { var pcfKernel = this._pcfKernels[frame % this._pcfKernels.length]; function updateQueue(queue) { for (var i = 0; i < queue.length; i++) { if (queue[i].receiveShadow) { queue[i].material.set('pcfKernel', pcfKernel); if (queue[i].material) { queue[i].material.define('fragment', 'PCF_KERNEL_SIZE', pcfKernel.length / 2); } } } } updateQueue(scene.getRenderList(camera).opaque); updateQueue(scene.getRenderList(camera).transparent); }; RenderMain.prototype.dispose = function () { var renderer = this.renderer; this._compositor.dispose(renderer); this._temporalSS.dispose(renderer); if (this._shadowMapPass) { this._shadowMapPass.dispose(renderer); } renderer.dispose(); }; RenderMain.prototype.setPostEffect = function (opts, api) { var compositor$$1 = this._compositor; opts = opts || {}; this._enablePostEffect = !!opts.enable; var bloomOpts = opts.bloom || {}; var edgeOpts = opts.edge || {}; var dofOpts = opts.depthOfField || {}; var ssaoOpts = opts.screenSpaceAmbientOcclusion || {}; var ssrOpts = opts.screenSpaceReflection || {}; var fxaaOpts = opts.FXAA || {}; var colorCorrOpts = opts.colorCorrection || {}; bloomOpts.enable ? compositor$$1.enableBloom() : compositor$$1.disableBloom(); dofOpts.enable ? compositor$$1.enableDOF() : compositor$$1.disableDOF(); ssrOpts.enable ? compositor$$1.enableSSR() : compositor$$1.disableSSR(); colorCorrOpts.enable ? compositor$$1.enableColorCorrection() : compositor$$1.disableColorCorrection(); edgeOpts.enable ? compositor$$1.enableEdge() : compositor$$1.disableEdge(); fxaaOpts.enable ? compositor$$1.enableFXAA() : compositor$$1.disableFXAA(); this._enableDOF = dofOpts.enable; this._enableSSAO = ssaoOpts.enable; this._enableSSAO ? compositor$$1.enableSSAO() : compositor$$1.disableSSAO(); compositor$$1.setBloomIntensity(bloomOpts.intensity); compositor$$1.setEdgeColor(edgeOpts.color); compositor$$1.setColorLookupTexture(colorCorrOpts.lookupTexture, api); compositor$$1.setExposure(colorCorrOpts.exposure); ['radius', 'quality', 'intensity', 'temporalFilter'].forEach(function (name) { compositor$$1.setSSAOParameter(name, ssaoOpts[name]); }); ['quality', 'maxRoughness', 'physical'].forEach(function (name) { compositor$$1.setSSRParameter(name, ssrOpts[name]); }); ['quality', 'focalDistance', 'focalRange', 'blurRadius', 'aperture'].forEach(function (name) { compositor$$1.setDOFParameter(name, dofOpts[name]); }); ['brightness', 'contrast', 'saturation'].forEach(function (name) { compositor$$1.setColorCorrection(name, colorCorrOpts[name]); }); }; RenderMain.prototype.setShadow = function (opts) { var pcfKernels = []; var off = 0; for (var i = 0; i < 30; i++) { var pcfKernel = []; for (var k = 0; k < opts.kernelSize; k++) { pcfKernel.push((halton(off, 2) * 2.0 - 1.0) * opts.blurSize); pcfKernel.push((halton(off, 3) * 2.0 - 1.0) * opts.blurSize); off++; } pcfKernels.push(pcfKernel); } this._pcfKernels = pcfKernels; }; RenderMain.prototype.isDOFEnabled = function () { return this._enablePostEffect && this._enableDOF; }; RenderMain.prototype.setDOFFocusOnPoint = function (depth) { if (this._enablePostEffect) { if (depth > this.camera.far || depth < this.camera.near) { return; } this._compositor.setDOFParameter('focalDistance', depth); return true; } }; RenderMain.prototype.setTemporalSuperSampling = function (temporalSuperSamplingOpt) { temporalSuperSamplingOpt = temporalSuperSamplingOpt || {}; this._enableTemporalSS = temporalSuperSamplingOpt.enable; this._temporalSupportDynamic = temporalSuperSamplingOpt.dynamic; if (this._enableTemporalSS && this._temporalSupportDynamic) { this._compositor.enableVelocityBuffer(); } else { this._compositor.disableVelocityBuffer(); } }; RenderMain.prototype.isLinearSpace = function () { return this._enablePostEffect; }; var defaultGraphicConfig = { // If enable shadow shadow: { enable: true, kernelSize: 6, blurSize: 2 }, temporalSuperSampling: { // If support dynamic scene dynamic: true, enable: 'auto' }, // Configuration about post effects. postEffect: { // If enable post effects. enable: true, // Configuration about bloom post effect bloom: { // If enable bloom enable: true, // Intensity of bloom intensity: 0.1 }, // Configuration about depth of field depthOfField: { enable: false, // Focal distance of camera in word space. focalDistance: 5, // Focal range of camera in word space. in this range image will be absolutely sharp. focalRange: 1, // Max out of focus blur radius. blurRadius: 20, // fstop of camera. Smaller fstop will have shallow depth of field aperture: 5.6, // Blur quality. 'low'|'medium'|'high'|'ultra' quality: 'medium' }, // Configuration about screen space ambient occulusion screenSpaceAmbientOcclusion: { // If enable SSAO enable: false, // Sampling radius in work space. // Larger will produce more soft concat shadow. // But also needs higher quality or it will have more obvious artifacts radius: 0.2, // Quality of SSAO. 'low'|'medium'|'high'|'ultra' quality: 'medium', // Intensity of SSAO intensity: 1, temporalFilter: false }, // Configuration about screen space reflection screenSpaceReflection: { enable: false, // If physically corrected. physical: false, // Quality of SSR. 'low'|'medium'|'high'|'ultra' quality: 'medium', // Surface with less roughness will have reflection. maxRoughness: 0.8 }, // Configuration about color correction colorCorrection: { // If enable color correction enable: true, exposure: 0, brightness: 0, contrast: 1, saturation: 1, // Lookup texture for color correction. // See https://ecomfe.github.io/echarts-doc/public/cn/option-gl.html#globe.postEffect.colorCorrection.lookupTexture lookupTexture: '' }, FXAA: { // If enable FXAA enable: false } } }; /** * @module zrender/core/util */ // 用于处理merge时无法遍历Date等对象的问题 var BUILTIN_OBJECT = { '[object Function]': 1, '[object RegExp]': 1, '[object Date]': 1, '[object Error]': 1, '[object CanvasGradient]': 1, '[object CanvasPattern]': 1, // For node-canvas '[object Image]': 1, '[object Canvas]': 1 }; var TYPED_ARRAY = { '[object Int8Array]': 1, '[object Uint8Array]': 1, '[object Uint8ClampedArray]': 1, '[object Int16Array]': 1, '[object Uint16Array]': 1, '[object Int32Array]': 1, '[object Uint32Array]': 1, '[object Float32Array]': 1, '[object Float64Array]': 1 }; var objToString = Object.prototype.toString; /** * Those data types can be cloned: * Plain object, Array, TypedArray, number, string, null, undefined. * Those data types will be assgined using the orginal data: * BUILTIN_OBJECT * Instance of user defined class will be cloned to a plain object, without * properties in prototype. * Other data types is not supported (not sure what will happen). * * Caution: do not support clone Date, for performance consideration. * (There might be a large number of date in `series.data`). * So date should not be modified in and out of echarts. * * @param {*} source * @return {*} new */ function clone(source) { if (source == null || typeof source != 'object') { return source; } var result = source; var typeStr = objToString.call(source); if (typeStr === '[object Array]') { if (!isPrimitive(source)) { result = []; for (var i = 0, len = source.length; i < len; i++) { result[i] = clone(source[i]); } } } else if (TYPED_ARRAY[typeStr]) { if (!isPrimitive(source)) { var Ctor = source.constructor; if (source.constructor.from) { result = Ctor.from(source); } else { result = new Ctor(source.length); for (var i = 0, len = source.length; i < len; i++) { result[i] = clone(source[i]); } } } } else if (!BUILTIN_OBJECT[typeStr] && !isPrimitive(source) && !isDom(source)) { result = {}; for (var key in source) { if (source.hasOwnProperty(key)) { result[key] = clone(source[key]); } } } return result; } /** * @memberOf module:zrender/core/util * @param {*} target * @param {*} source * @param {boolean} [overwrite=false] */ function merge(target, source, overwrite) { // We should escapse that source is string // and enter for ... in ... if (!isObject(source) || !isObject(target)) { return overwrite ? clone(source) : target; } for (var key in source) { if (source.hasOwnProperty(key)) { var targetProp = target[key]; var sourceProp = source[key]; if (isObject(sourceProp) && isObject(targetProp) && !isArray(sourceProp) && !isArray(targetProp) && !isDom(sourceProp) && !isDom(targetProp) && !isBuiltInObject(sourceProp) && !isBuiltInObject(targetProp) && !isPrimitive(sourceProp) && !isPrimitive(targetProp) ) { // 如果需要递归覆盖,就递归调用merge merge(targetProp, sourceProp, overwrite); } else if (overwrite || !(key in target)) { // 否则只处理overwrite为true,或者在目标对象中没有此属性的情况 // NOTE,在 target[key] 不存在的时候也是直接覆盖 target[key] = clone(source[key], true); } } } return target; } /** * @param {Array} targetAndSources The first item is target, and the rests are source. * @param {boolean} [overwrite=false] * @return {*} target */ /** * @param {*} target * @param {*} source * @memberOf module:zrender/core/util */ /** * @param {*} target * @param {*} source * @param {boolean} [overlay=false] * @memberOf module:zrender/core/util */ /** * 查询数组中元素的index * @memberOf module:zrender/core/util */ /** * 构造类继承关系 * * @memberOf module:zrender/core/util * @param {Function} clazz 源类 * @param {Function} baseClazz 基类 */ /** * @memberOf module:zrender/core/util * @param {Object|Function} target * @param {Object|Function} sorce * @param {boolean} overlay */ /** * Consider typed array. * @param {Array|TypedArray} data */ /** * 数组或对象遍历 * @memberOf module:zrender/core/util * @param {Object|Array} obj * @param {Function} cb * @param {*} [context] */ /** * 数组映射 * @memberOf module:zrender/core/util * @param {Array} obj * @param {Function} cb * @param {*} [context] * @return {Array} */ /** * @memberOf module:zrender/core/util * @param {Array} obj * @param {Function} cb * @param {Object} [memo] * @param {*} [context] * @return {Array} */ /** * 数组过滤 * @memberOf module:zrender/core/util * @param {Array} obj * @param {Function} cb * @param {*} [context] * @return {Array} */ /** * 数组项查找 * @memberOf module:zrender/core/util * @param {Array} obj * @param {Function} cb * @param {*} [context] * @return {*} */ /** * @memberOf module:zrender/core/util * @param {Function} func * @param {*} context * @return {Function} */ /** * @memberOf module:zrender/core/util * @param {Function} func * @return {Function} */ /** * @memberOf module:zrender/core/util * @param {*} value * @return {boolean} */ function isArray(value) { return objToString.call(value) === '[object Array]'; } /** * @memberOf module:zrender/core/util * @param {*} value * @return {boolean} */ /** * @memberOf module:zrender/core/util * @param {*} value * @return {boolean} */ /** * @memberOf module:zrender/core/util * @param {*} value * @return {boolean} */ function isObject(value) { // Avoid a V8 JIT bug in Chrome 19-20. // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. var type = typeof value; return type === 'function' || (!!value && type == 'object'); } /** * @memberOf module:zrender/core/util * @param {*} value * @return {boolean} */ function isBuiltInObject(value) { return !!BUILTIN_OBJECT[objToString.call(value)]; } /** * @memberOf module:zrender/core/util * @param {*} value * @return {boolean} */ /** * @memberOf module:zrender/core/util * @param {*} value * @return {boolean} */ function isDom(value) { return typeof value === 'object' && typeof value.nodeType === 'number' && typeof value.ownerDocument === 'object'; } /** * Whether is exactly NaN. Notice isNaN('a') returns true. * @param {*} value * @return {boolean} */ /** * If value1 is not null, then return value1, otherwise judget rest of values. * Low performance. * @memberOf module:zrender/core/util * @return {*} Final value */ /** * @memberOf module:zrender/core/util * @param {Array} arr * @param {number} startIndex * @param {number} endIndex * @return {Array} */ /** * Normalize css liked array configuration * e.g. * 3 => [3, 3, 3, 3] * [4, 2] => [4, 2, 4, 2] * [4, 3, 2] => [4, 3, 2, 3] * @param {number|Array.} val * @return {Array.} */ /** * @memberOf module:zrender/core/util * @param {boolean} condition * @param {string} message */ /** * @memberOf module:zrender/core/util * @param {string} str string to be trimed * @return {string} trimed string */ var primitiveKey = '__ec_primitive__'; /** * Set an object as primitive to be ignored traversing children in clone or merge */ function isPrimitive(obj) { return obj[primitiveKey]; } /** * @constructor * @param {Object} obj Only apply `ownProperty`. */ function ClayAdvancedRenderer(renderer, scene, timeline, graphicOpts) { graphicOpts = merge({}, graphicOpts); if (typeof graphicOpts.shadow === 'boolean') { graphicOpts.shadow = { enable: graphicOpts.shadow }; } graphicOpts = merge(graphicOpts, defaultGraphicConfig); this._renderMain = new RenderMain(renderer, scene, graphicOpts.shadow); this._renderMain.setShadow(graphicOpts.shadow); this._renderMain.setPostEffect(graphicOpts.postEffect); this._renderMain.setTemporalSuperSampling(graphicOpts.temporalSuperSampling); this._needsRefresh = false; this._graphicOpts = graphicOpts; timeline.on('frame', this._loop, this); scene.on('click', function (e) { this.setPostEffect({ depthOfField: { focalDistance: e.distance } }); this.render(); }, this); } ClayAdvancedRenderer.prototype.render = function (renderImmediately) { this._needsRefresh = true; }; ClayAdvancedRenderer.prototype.setPostEffect = function (opts) { merge(this._graphicOpts.postEffect, opts, true); this._renderMain.setPostEffect(this._graphicOpts.postEffect); }; ClayAdvancedRenderer.prototype.setShadow = function (opts) { merge(this._graphicOpts.shadow, opts, true); this._renderMain.setShadow(this._graphicOpts.shadow); }; ClayAdvancedRenderer.prototype._loop = function (frameTime) { if (this._disposed) { return; } if (!this._needsRefresh) { return; } this._needsRefresh = false; this._renderMain.prepareRender(); this._renderMain.render(); this._startAccumulating(); }; var accumulatingId = 1; ClayAdvancedRenderer.prototype._stopAccumulating = function () { this._accumulatingId = 0; clearTimeout(this._accumulatingTimeout); }; ClayAdvancedRenderer.prototype._startAccumulating = function (immediate) { var self = this; this._stopAccumulating(); var needsAccumulate = self._renderMain.needsAccumulate(); if (!needsAccumulate) { return; } function accumulate(id) { if (!self._accumulatingId || id !== self._accumulatingId || self._disposed) { return; } var isFinished = self._renderMain.isAccumulateFinished() && needsAccumulate; if (!isFinished) { self._renderMain.render(true); if (immediate) { accumulate(id); } else { requestAnimationFrame(function () { accumulate(id); }); } } } this._accumulatingId = accumulatingId++; if (immediate) { accumulate(self._accumulatingId); } else { this._accumulatingTimeout = setTimeout(function () { accumulate(self._accumulatingId); }, 50); } }; ClayAdvancedRenderer.prototype.dispose = function () { this._disposed = true; this._renderMain.dispose(); }; ClayAdvancedRenderer.version = '0.1.1'; return ClayAdvancedRenderer; }))); ================================================ FILE: test/lib/claygl.js ================================================ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.clay = {}))); }(this, (function (exports) { 'use strict'; // 缓动函数来自 https://github.com/sole/tween.js/blob/master/src/Tween.js /** * @namespace clay.animation.easing */ var easing = { /** * @alias clay.animation.easing.linear * @param {number} k * @return {number} */ linear: function(k) { return k; }, /** * @alias clay.animation.easing.quadraticIn * @param {number} k * @return {number} */ quadraticIn: function(k) { return k * k; }, /** * @alias clay.animation.easing.quadraticOut * @param {number} k * @return {number} */ quadraticOut: function(k) { return k * (2 - k); }, /** * @alias clay.animation.easing.quadraticInOut * @param {number} k * @return {number} */ quadraticInOut: function(k) { if ((k *= 2) < 1) { return 0.5 * k * k; } return - 0.5 * (--k * (k - 2) - 1); }, /** * @alias clay.animation.easing.cubicIn * @param {number} k * @return {number} */ cubicIn: function(k) { return k * k * k; }, /** * @alias clay.animation.easing.cubicOut * @param {number} k * @return {number} */ cubicOut: function(k) { return --k * k * k + 1; }, /** * @alias clay.animation.easing.cubicInOut * @param {number} k * @return {number} */ cubicInOut: function(k) { if ((k *= 2) < 1) { return 0.5 * k * k * k; } return 0.5 * ((k -= 2) * k * k + 2); }, /** * @alias clay.animation.easing.quarticIn * @param {number} k * @return {number} */ quarticIn: function(k) { return k * k * k * k; }, /** * @alias clay.animation.easing.quarticOut * @param {number} k * @return {number} */ quarticOut: function(k) { return 1 - (--k * k * k * k); }, /** * @alias clay.animation.easing.quarticInOut * @param {number} k * @return {number} */ quarticInOut: function(k) { if ((k *= 2) < 1) { return 0.5 * k * k * k * k; } return - 0.5 * ((k -= 2) * k * k * k - 2); }, /** * @alias clay.animation.easing.quinticIn * @param {number} k * @return {number} */ quinticIn: function(k) { return k * k * k * k * k; }, /** * @alias clay.animation.easing.quinticOut * @param {number} k * @return {number} */ quinticOut: function(k) { return --k * k * k * k * k + 1; }, /** * @alias clay.animation.easing.quinticInOut * @param {number} k * @return {number} */ quinticInOut: function(k) { if ((k *= 2) < 1) { return 0.5 * k * k * k * k * k; } return 0.5 * ((k -= 2) * k * k * k * k + 2); }, /** * @alias clay.animation.easing.sinusoidalIn * @param {number} k * @return {number} */ sinusoidalIn: function(k) { return 1 - Math.cos(k * Math.PI / 2); }, /** * @alias clay.animation.easing.sinusoidalOut * @param {number} k * @return {number} */ sinusoidalOut: function(k) { return Math.sin(k * Math.PI / 2); }, /** * @alias clay.animation.easing.sinusoidalInOut * @param {number} k * @return {number} */ sinusoidalInOut: function(k) { return 0.5 * (1 - Math.cos(Math.PI * k)); }, /** * @alias clay.animation.easing.exponentialIn * @param {number} k * @return {number} */ exponentialIn: function(k) { return k === 0 ? 0 : Math.pow(1024, k - 1); }, /** * @alias clay.animation.easing.exponentialOut * @param {number} k * @return {number} */ exponentialOut: function(k) { return k === 1 ? 1 : 1 - Math.pow(2, - 10 * k); }, /** * @alias clay.animation.easing.exponentialInOut * @param {number} k * @return {number} */ exponentialInOut: function(k) { if (k === 0) { return 0; } if (k === 1) { return 1; } if ((k *= 2) < 1) { return 0.5 * Math.pow(1024, k - 1); } return 0.5 * (- Math.pow(2, - 10 * (k - 1)) + 2); }, /** * @alias clay.animation.easing.circularIn * @param {number} k * @return {number} */ circularIn: function(k) { return 1 - Math.sqrt(1 - k * k); }, /** * @alias clay.animation.easing.circularOut * @param {number} k * @return {number} */ circularOut: function(k) { return Math.sqrt(1 - (--k * k)); }, /** * @alias clay.animation.easing.circularInOut * @param {number} k * @return {number} */ circularInOut: function(k) { if ((k *= 2) < 1) { return - 0.5 * (Math.sqrt(1 - k * k) - 1); } return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1); }, /** * @alias clay.animation.easing.elasticIn * @param {number} k * @return {number} */ elasticIn: function(k) { var s, a = 0.1, p = 0.4; if (k === 0) { return 0; } if (k === 1) { return 1; } if (!a || a < 1) { a = 1; s = p / 4; }else{ s = p * Math.asin(1 / a) / (2 * Math.PI); } return - (a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p)); }, /** * @alias clay.animation.easing.elasticOut * @param {number} k * @return {number} */ elasticOut: function(k) { var s, a = 0.1, p = 0.4; if (k === 0) { return 0; } if (k === 1) { return 1; } if (!a || a < 1) { a = 1; s = p / 4; } else{ s = p * Math.asin(1 / a) / (2 * Math.PI); } return (a * Math.pow(2, - 10 * k) * Math.sin((k - s) * (2 * Math.PI) / p) + 1); }, /** * @alias clay.animation.easing.elasticInOut * @param {number} k * @return {number} */ elasticInOut: function(k) { var s, a = 0.1, p = 0.4; if (k === 0) { return 0; } if (k === 1) { return 1; } if (!a || a < 1) { a = 1; s = p / 4; } else{ s = p * Math.asin(1 / a) / (2 * Math.PI); } if ((k *= 2) < 1) { return - 0.5 * (a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p)); } return a * Math.pow(2, -10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1; }, /** * @alias clay.animation.easing.backIn * @param {number} k * @return {number} */ backIn: function(k) { var s = 1.70158; return k * k * ((s + 1) * k - s); }, /** * @alias clay.animation.easing.backOut * @param {number} k * @return {number} */ backOut: function(k) { var s = 1.70158; return --k * k * ((s + 1) * k + s) + 1; }, /** * @alias clay.animation.easing.backInOut * @param {number} k * @return {number} */ backInOut: function(k) { var s = 1.70158 * 1.525; if ((k *= 2) < 1) { return 0.5 * (k * k * ((s + 1) * k - s)); } return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2); }, /** * @alias clay.animation.easing.bounceIn * @param {number} k * @return {number} */ bounceIn: function(k) { return 1 - easing.bounceOut(1 - k); }, /** * @alias clay.animation.easing.bounceOut * @param {number} k * @return {number} */ bounceOut: function(k) { if (k < (1 / 2.75)) { return 7.5625 * k * k; } else if (k < (2 / 2.75)) { return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75; } else if (k < (2.5 / 2.75)) { return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375; } else { return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375; } }, /** * @alias clay.animation.easing.bounceInOut * @param {number} k * @return {number} */ bounceInOut: function(k) { if (k < 0.5) { return easing.bounceIn(k * 2) * 0.5; } return easing.bounceOut(k * 2 - 1) * 0.5 + 0.5; } }; function noop () {} /** * @constructor * @alias clay.animation.Clip * @param {Object} [opts] * @param {Object} [opts.target] * @param {number} [opts.life] * @param {number} [opts.delay] * @param {number} [opts.gap] * @param {number} [opts.playbackRate] * @param {boolean|number} [opts.loop] If loop is a number, it indicate the loop count of animation * @param {string|Function} [opts.easing] * @param {Function} [opts.onframe] * @param {Function} [opts.onfinish] * @param {Function} [opts.onrestart] */ var Clip = function (opts) { opts = opts || {}; /** * @type {string} */ this.name = opts.name || ''; /** * @type {Object} */ this.target = opts.target; /** * @type {number} */ this.life = opts.life || 1000; /** * @type {number} */ this.delay = opts.delay || 0; /** * @type {number} */ this.gap = opts.gap || 0; /** * @type {number} */ this.playbackRate = opts.playbackRate || 1; this._initialized = false; this._elapsedTime = 0; this._loop = opts.loop == null ? false : opts.loop; this.setLoop(this._loop); if (opts.easing != null) { this.setEasing(opts.easing); } /** * @type {Function} */ this.onframe = opts.onframe || noop; /** * @type {Function} */ this.onfinish = opts.onfinish || noop; /** * @type {Function} */ this.onrestart = opts.onrestart || noop; this._paused = false; }; Clip.prototype = { gap: 0, life: 0, delay: 0, /** * @param {number|boolean} loop */ setLoop: function (loop) { this._loop = loop; if (loop) { if (typeof loop === 'number') { this._loopRemained = loop; } else { this._loopRemained = Infinity; } } }, /** * @param {string|Function} easing */ setEasing: function (easing$$1) { if (typeof(easing$$1) === 'string') { easing$$1 = easing[easing$$1]; } this.easing = easing$$1; }, /** * @param {number} time * @return {string} */ step: function (time, deltaTime, silent) { if (!this._initialized) { this._startTime = time + this.delay; this._initialized = true; } if (this._currentTime != null) { deltaTime = time - this._currentTime; } this._currentTime = time; if (this._paused) { return 'paused'; } if (time < this._startTime) { return; } // PENDIGN Sync ? this._elapse(time, deltaTime); var percent = Math.min(this._elapsedTime / this.life, 1); if (percent < 0) { return; } var schedule; if (this.easing) { schedule = this.easing(percent); } else { schedule = percent; } if (!silent) { this.fire('frame', schedule); } if (percent === 1) { if (this._loop && this._loopRemained > 0) { this._restartInLoop(time); this._loopRemained--; return 'restart'; } else { // Mark this clip to be deleted // In the animation.update this._needsRemove = true; return 'finish'; } } else { return null; } }, /** * @param {number} time * @return {string} */ setTime: function (time) { return this.step(time + this._startTime); }, restart: function (time) { // If user leave the page for a while, when he gets back // All clips may be expired and all start from the beginning value(position) // It is clearly wrong, so we use remainder to add a offset var remainder = 0; // Remainder ignored if restart is invoked manually if (time) { this._elapse(time); remainder = this._elapsedTime % this.life; } time = time || Date.now(); this._startTime = time - remainder + this.delay; this._elapsedTime = 0; this._needsRemove = false; this._paused = false; }, getElapsedTime: function () { return this._elapsedTime; }, _restartInLoop: function (time) { this._startTime = time + this.gap; this._elapsedTime = 0; }, _elapse: function (time, deltaTime) { this._elapsedTime += deltaTime * this.playbackRate; }, fire: function (eventType, arg) { var eventName = 'on' + eventType; if (this[eventName]) { this[eventName](this.target, arg); } }, clone: function () { var clip = new this.constructor(); clip.name = this.name; clip._loop = this._loop; clip._loopRemained = this._loopRemained; clip.life = this.life; clip.gap = this.gap; clip.delay = this.delay; return clip; }, /** * Pause the clip. */ pause: function () { this._paused = true; }, /** * Resume the clip. */ resume: function () { this._paused = false; } }; Clip.prototype.constructor = Clip; var arraySlice = Array.prototype.slice; function defaultGetter(target, key) { return target[key]; } function defaultSetter(target, key, value) { target[key] = value; } function interpolateNumber(p0, p1, percent) { return (p1 - p0) * percent + p0; } function interpolateArray(p0, p1, percent, out, arrDim) { var len = p0.length; if (arrDim == 1) { for (var i = 0; i < len; i++) { out[i] = interpolateNumber(p0[i], p1[i], percent); } } else { var len2 = p0[0].length; for (var i = 0; i < len; i++) { for (var j = 0; j < len2; j++) { out[i][j] = interpolateNumber( p0[i][j], p1[i][j], percent ); } } } } function isArrayLike(data) { if (typeof(data) == 'undefined') { return false; } else if (typeof(data) == 'string') { return false; } else { return typeof(data.length) == 'number'; } } function cloneValue(value) { if (isArrayLike(value)) { var len = value.length; if (isArrayLike(value[0])) { var ret = []; for (var i = 0; i < len; i++) { ret.push(arraySlice.call(value[i])); } return ret; } else { return arraySlice.call(value); } } else { return value; } } function catmullRomInterpolateArray( p0, p1, p2, p3, t, t2, t3, out, arrDim ) { var len = p0.length; if (arrDim == 1) { for (var i = 0; i < len; i++) { out[i] = catmullRomInterpolate( p0[i], p1[i], p2[i], p3[i], t, t2, t3 ); } } else { var len2 = p0[0].length; for (var i = 0; i < len; i++) { for (var j = 0; j < len2; j++) { out[i][j] = catmullRomInterpolate( p0[i][j], p1[i][j], p2[i][j], p3[i][j], t, t2, t3 ); } } } } function catmullRomInterpolate(p0, p1, p2, p3, t, t2, t3) { var v0 = (p2 - p0) * 0.5; var v1 = (p3 - p1) * 0.5; return (2 * (p1 - p2) + v0 + v1) * t3 + (- 3 * (p1 - p2) - 2 * v0 - v1) * t2 + v0 * t + p1; } // arr0 is source array, arr1 is target array. // Do some preprocess to avoid error happened when interpolating from arr0 to arr1 function fillArr(arr0, arr1, arrDim) { var arr0Len = arr0.length; var arr1Len = arr1.length; if (arr0Len !== arr1Len) { // FIXME Not work for TypedArray var isPreviousLarger = arr0Len > arr1Len; if (isPreviousLarger) { // Cut the previous arr0.length = arr1Len; } else { // Fill the previous for (var i = arr0Len; i < arr1Len; i++) { arr0.push( arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i]) ); } } } // Handling NaN value var len2 = arr0[0] && arr0[0].length; for (var i = 0; i < arr0.length; i++) { if (arrDim === 1) { if (isNaN(arr0[i])) { arr0[i] = arr1[i]; } } else { for (var j = 0; j < len2; j++) { if (isNaN(arr0[i][j])) { arr0[i][j] = arr1[i][j]; } } } } } function isArraySame(arr0, arr1, arrDim) { if (arr0 === arr1) { return true; } var len = arr0.length; if (len !== arr1.length) { return false; } if (arrDim === 1) { for (var i = 0; i < len; i++) { if (arr0[i] !== arr1[i]) { return false; } } } else { var len2 = arr0[0].length; for (var i = 0; i < len; i++) { for (var j = 0; j < len2; j++) { if (arr0[i][j] !== arr1[i][j]) { return false; } } } } return true; } function createTrackClip(animator, globalEasing, oneTrackDone, keyframes, propName, interpolater, maxTime) { var getter = animator._getter; var setter = animator._setter; var useSpline = globalEasing === 'spline'; var trackLen = keyframes.length; if (!trackLen) { return; } // Guess data type var firstVal = keyframes[0].value; var isValueArray = isArrayLike(firstVal); // For vertices morphing var arrDim = ( isValueArray && isArrayLike(firstVal[0]) ) ? 2 : 1; // Sort keyframe as ascending keyframes.sort(function(a, b) { return a.time - b.time; }); // Percents of each keyframe var kfPercents = []; // Value of each keyframe var kfValues = []; // Easing funcs of each keyframe. var kfEasings = []; var prevValue = keyframes[0].value; var isAllValueEqual = true; for (var i = 0; i < trackLen; i++) { kfPercents.push(keyframes[i].time / maxTime); // Assume value is a color when it is a string var value = keyframes[i].value; // Check if value is equal, deep check if value is array if (!((isValueArray && isArraySame(value, prevValue, arrDim)) || (!isValueArray && value === prevValue))) { isAllValueEqual = false; } prevValue = value; kfValues.push(value); kfEasings.push(keyframes[i].easing); } if (isAllValueEqual) { return; } var lastValue = kfValues[trackLen - 1]; // Polyfill array and NaN value for (var i = 0; i < trackLen - 1; i++) { if (isValueArray) { fillArr(kfValues[i], lastValue, arrDim); } else { if (isNaN(kfValues[i]) && !isNaN(lastValue)) { kfValues[i] = lastValue; } } } isValueArray && fillArr(getter(animator._target, propName), lastValue, arrDim); // Cache the key of last frame to speed up when // animation playback is sequency var cacheKey = 0; var cachePercent = 0; var start; var i, w; var p0, p1, p2, p3; var onframe = function(target, percent) { // Find the range keyframes // kf1-----kf2---------current--------kf3 // find kf2(i) and kf3(i + 1) and do interpolation if (percent < cachePercent) { // Start from next key start = Math.min(cacheKey + 1, trackLen - 1); for (i = start; i >= 0; i--) { if (kfPercents[i] <= percent) { break; } } i = Math.min(i, trackLen - 2); } else { for (i = cacheKey; i < trackLen; i++) { if (kfPercents[i] > percent) { break; } } i = Math.min(i - 1, trackLen - 2); } cacheKey = i; cachePercent = percent; var range = (kfPercents[i + 1] - kfPercents[i]); if (range === 0) { return; } else { w = (percent - kfPercents[i]) / range; // Clamp 0 - 1 w = Math.max(Math.min(1, w), 0); } w = kfEasings[i + 1](w); if (useSpline) { p1 = kfValues[i]; p0 = kfValues[i === 0 ? i : i - 1]; p2 = kfValues[i > trackLen - 2 ? trackLen - 1 : i + 1]; p3 = kfValues[i > trackLen - 3 ? trackLen - 1 : i + 2]; if (interpolater) { setter( target, propName, interpolater( getter(target, propName), p0, p1, p2, p3, w ) ); } else if (isValueArray) { catmullRomInterpolateArray( p0, p1, p2, p3, w, w*w, w*w*w, getter(target, propName), arrDim ); } else { setter( target, propName, catmullRomInterpolate(p0, p1, p2, p3, w, w*w, w*w*w) ); } } else { if (interpolater) { setter( target, propName, interpolater( getter(target, propName), kfValues[i], kfValues[i + 1], w ) ); } else if (isValueArray) { interpolateArray( kfValues[i], kfValues[i+1], w, getter(target, propName), arrDim ); } else { setter( target, propName, interpolateNumber(kfValues[i], kfValues[i+1], w) ); } } }; var clip = new Clip({ target: animator._target, life: maxTime, loop: animator._loop, delay: animator._delay, onframe: onframe, onfinish: oneTrackDone }); if (globalEasing && globalEasing !== 'spline') { clip.setEasing(globalEasing); } return clip; } /** * @description Animator object can only be created by Animation.prototype.animate method. * After created, we can use {@link clay.animation.Animator#when} to add all keyframes and {@link clay.animation.Animator#start} it. * Clips will be automatically created and added to the animation instance which created this deferred object. * * @constructor clay.animation.Animator * * @param {Object} target * @param {boolean} loop * @param {Function} getter * @param {Function} setter * @param {Function} interpolater */ function Animator(target, loop, getter, setter, interpolater) { this._tracks = {}; this._target = target; this._loop = loop || false; this._getter = getter || defaultGetter; this._setter = setter || defaultSetter; this._interpolater = interpolater || null; this._delay = 0; this._doneList = []; this._onframeList = []; this._clipList = []; this._maxTime = 0; this._lastKFTime = 0; } function noopEasing(w) { return w; } Animator.prototype = { constructor: Animator, /** * @param {number} time Keyframe time using millisecond * @param {Object} props A key-value object. Value can be number, 1d and 2d array * @param {string|Function} [easing] * @return {clay.animation.Animator} * @memberOf clay.animation.Animator.prototype */ when: function (time, props, easing$$1) { this._maxTime = Math.max(time, this._maxTime); easing$$1 = (typeof easing$$1 === 'function' ? easing$$1 : easing[easing$$1]) || noopEasing; for (var propName in props) { if (!this._tracks[propName]) { this._tracks[propName] = []; // If time is 0 // Then props is given initialize value // Else // Initialize value from current prop value if (time !== 0) { this._tracks[propName].push({ time: 0, value: cloneValue( this._getter(this._target, propName) ), easing: easing$$1 }); } } this._tracks[propName].push({ time: parseInt(time), value: props[propName], easing: easing$$1 }); } return this; }, /** * @param {number} time During time since last keyframe * @param {Object} props A key-value object. Value can be number, 1d and 2d array * @param {string|Function} [easing] * @return {clay.animation.Animator} * @memberOf clay.animation.Animator.prototype */ then: function (duringTime, props, easing$$1) { this.when(duringTime + this._lastKFTime, props, easing$$1); this._lastKFTime += duringTime; return this; }, /** * callback when running animation * @param {Function} callback callback have two args, animating target and current percent * @return {clay.animation.Animator} * @memberOf clay.animation.Animator.prototype */ during: function (callback) { this._onframeList.push(callback); return this; }, _doneCallback: function () { // Clear all tracks this._tracks = {}; // Clear all clips this._clipList.length = 0; var doneList = this._doneList; var len = doneList.length; for (var i = 0; i < len; i++) { doneList[i].call(this); } }, /** * Start the animation * @param {string|Function} easing * @return {clay.animation.Animator} * @memberOf clay.animation.Animator.prototype */ start: function (globalEasing) { var self = this; var clipCount = 0; var oneTrackDone = function() { clipCount--; if (clipCount === 0) { self._doneCallback(); } }; var lastClip; for (var propName in this._tracks) { var clip = createTrackClip( this, globalEasing, oneTrackDone, this._tracks[propName], propName, self._interpolater, self._maxTime ); if (clip) { this._clipList.push(clip); clipCount++; // If start after added to animation if (this.animation) { this.animation.addClip(clip); } lastClip = clip; } } // Add during callback on the last clip if (lastClip) { var oldOnFrame = lastClip.onframe; lastClip.onframe = function (target, percent) { oldOnFrame(target, percent); for (var i = 0; i < self._onframeList.length; i++) { self._onframeList[i](target, percent); } }; } if (!clipCount) { this._doneCallback(); } return this; }, /** * Stop the animation * @memberOf clay.animation.Animator.prototype */ stop: function () { for (var i = 0; i < this._clipList.length; i++) { var clip = this._clipList[i]; this.animation.removeClip(clip); } this._clipList = []; }, /** * Delay given milliseconds * @param {number} time * @return {clay.animation.Animator} * @memberOf clay.animation.Animator.prototype */ delay: function (time){ this._delay = time; return this; }, /** * Callback after animation finished * @param {Function} func * @return {clay.animation.Animator} * @memberOf clay.animation.Animator.prototype */ done: function (func) { if (func) { this._doneList.push(func); } return this; }, /** * Get all clips created in start method. * @return {clay.animation.Clip[]} * @memberOf clay.animation.Animator.prototype */ getClips: function () { return this._clipList; } }; // 1D Blend clip of blend tree // http://docs.unity3d.com/Documentation/Manual/1DBlending.html var clipSortFunc = function (a, b) { return a.position < b.position; }; /** * @typedef {Object} clay.animation.Blend1DClip.IClipInput * @property {number} position * @property {clay.animation.Clip} clip * @property {number} offset */ /** * 1d blending node in animation blend tree. * output clip must have blend1D and copy method * @constructor * @alias clay.animation.Blend1DClip * @extends clay.animation.Clip * * @param {Object} [opts] * @param {string} [opts.name] * @param {Object} [opts.target] * @param {number} [opts.life] * @param {number} [opts.delay] * @param {number} [opts.gap] * @param {number} [opts.playbackRatio] * @param {boolean|number} [opts.loop] If loop is a number, it indicate the loop count of animation * @param {string|Function} [opts.easing] * @param {Function} [opts.onframe] * @param {Function} [opts.onfinish] * @param {Function} [opts.onrestart] * @param {object[]} [opts.inputs] * @param {number} [opts.position] * @param {clay.animation.Clip} [opts.output] */ var Blend1DClip = function (opts) { opts = opts || {}; Clip.call(this, opts); /** * Output clip must have blend1D and copy method * @type {clay.animation.Clip} */ this.output = opts.output || null; /** * @type {clay.animation.Blend1DClip.IClipInput[]} */ this.inputs = opts.inputs || []; /** * @type {number} */ this.position = 0; this._cacheKey = 0; this._cachePosition = -Infinity; this.inputs.sort(clipSortFunc); }; Blend1DClip.prototype = new Clip(); Blend1DClip.prototype.constructor = Blend1DClip; /** * @param {number} position * @param {clay.animation.Clip} inputClip * @param {number} [offset] * @return {clay.animation.Blend1DClip.IClipInput} */ Blend1DClip.prototype.addInput = function (position, inputClip, offset) { var obj = { position: position, clip: inputClip, offset: offset || 0 }; this.life = Math.max(inputClip.life, this.life); if (!this.inputs.length) { this.inputs.push(obj); return obj; } var len = this.inputs.length; if (this.inputs[0].position > position) { this.inputs.unshift(obj); } else if (this.inputs[len - 1].position <= position) { this.inputs.push(obj); } else { var key = this._findKey(position); this.inputs.splice(key, obj); } return obj; }; Blend1DClip.prototype.step = function (time, dTime, silent) { var ret = Clip.prototype.step.call(this, time); if (ret !== 'finish') { this.setTime(this.getElapsedTime()); } // PENDING Schedule if (!silent && ret !== 'paused') { this.fire('frame'); } return ret; }; Blend1DClip.prototype.setTime = function (time) { var position = this.position; var inputs = this.inputs; var len = inputs.length; var min = inputs[0].position; var max = inputs[len-1].position; if (position <= min || position >= max) { var in0 = position <= min ? inputs[0] : inputs[len-1]; var clip = in0.clip; var offset = in0.offset; clip.setTime((time + offset) % clip.life); // Input clip is a blend clip // PENDING if (clip.output instanceof Clip) { this.output.copy(clip.output); } else { this.output.copy(clip); } } else { var key = this._findKey(position); var in1 = inputs[key]; var in2 = inputs[key + 1]; var clip1 = in1.clip; var clip2 = in2.clip; // Set time on input clips clip1.setTime((time + in1.offset) % clip1.life); clip2.setTime((time + in2.offset) % clip2.life); var w = (this.position - in1.position) / (in2.position - in1.position); var c1 = clip1.output instanceof Clip ? clip1.output : clip1; var c2 = clip2.output instanceof Clip ? clip2.output : clip2; this.output.blend1D(c1, c2, w); } }; /** * Clone a new Blend1D clip * @param {boolean} cloneInputs True if clone the input clips * @return {clay.animation.Blend1DClip} */ Blend1DClip.prototype.clone = function (cloneInputs) { var clip = Clip.prototype.clone.call(this); clip.output = this.output.clone(); for (var i = 0; i < this.inputs.length; i++) { var inputClip = cloneInputs ? this.inputs[i].clip.clone(true) : this.inputs[i].clip; clip.addInput(this.inputs[i].position, inputClip, this.inputs[i].offset); } return clip; }; // Find the key where position in range [inputs[key].position, inputs[key+1].position) Blend1DClip.prototype._findKey = function (position) { var key = -1; var inputs = this.inputs; var len = inputs.length; if (this._cachePosition < position) { for (var i = this._cacheKey; i < len-1; i++) { if (position >= inputs[i].position && position < inputs[i+1].position) { key = i; } } } else { var s = Math.min(len-2, this._cacheKey); for (var i = s; i >= 0; i--) { if (position >= inputs[i].position && position < inputs[i+1].position) { key = i; } } } if (key >= 0) { this._cacheKey = key; this._cachePosition = position; } return key; }; // Delaunay Triangulation // Modified from https://github.com/ironwallaby/delaunay var EPSILON = 1.0 / 1048576.0; function supertriangle(vertices) { var xmin = Number.POSITIVE_INFINITY; var ymin = Number.POSITIVE_INFINITY; var xmax = Number.NEGATIVE_INFINITY; var ymax = Number.NEGATIVE_INFINITY; var i, dx, dy, dmax, xmid, ymid; for (i = vertices.length; i--; ) { if (vertices[i][0] < xmin) { xmin = vertices[i][0]; } if (vertices[i][0] > xmax) { xmax = vertices[i][0]; } if (vertices[i][1] < ymin) { ymin = vertices[i][1]; } if (vertices[i][1] > ymax) { ymax = vertices[i][1]; } } dx = xmax - xmin; dy = ymax - ymin; dmax = Math.max(dx, dy); xmid = xmin + dx * 0.5; ymid = ymin + dy * 0.5; return [ [xmid - 20 * dmax, ymid - dmax], [xmid , ymid + 20 * dmax], [xmid + 20 * dmax, ymid - dmax] ]; } function circumcircle(vertices, i, j, k) { var x1 = vertices[i][0], y1 = vertices[i][1], x2 = vertices[j][0], y2 = vertices[j][1], x3 = vertices[k][0], y3 = vertices[k][1], fabsy1y2 = Math.abs(y1 - y2), fabsy2y3 = Math.abs(y2 - y3), xc, yc, m1, m2, mx1, mx2, my1, my2, dx, dy; /* Check for coincident points */ if (fabsy1y2 < EPSILON && fabsy2y3 < EPSILON) { throw new Error('Eek! Coincident points!'); } if (fabsy1y2 < EPSILON) { m2 = -((x3 - x2) / (y3 - y2)); mx2 = (x2 + x3) / 2.0; my2 = (y2 + y3) / 2.0; xc = (x2 + x1) / 2.0; yc = m2 * (xc - mx2) + my2; } else if (fabsy2y3 < EPSILON) { m1 = -((x2 - x1) / (y2 - y1)); mx1 = (x1 + x2) / 2.0; my1 = (y1 + y2) / 2.0; xc = (x3 + x2) / 2.0; yc = m1 * (xc - mx1) + my1; } else { m1 = -((x2 - x1) / (y2 - y1)); m2 = -((x3 - x2) / (y3 - y2)); mx1 = (x1 + x2) / 2.0; mx2 = (x2 + x3) / 2.0; my1 = (y1 + y2) / 2.0; my2 = (y2 + y3) / 2.0; xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2); yc = (fabsy1y2 > fabsy2y3) ? m1 * (xc - mx1) + my1 : m2 * (xc - mx2) + my2; } dx = x2 - xc; dy = y2 - yc; return {i: i, j: j, k: k, x: xc, y: yc, r: dx * dx + dy * dy}; } function dedup(edges) { var i, j, a, b, m, n; for (j = edges.length; j; ) { b = edges[--j]; a = edges[--j]; for (i = j; i; ) { n = edges[--i]; m = edges[--i]; if ((a === m && b === n) || (a === n && b === m)) { edges.splice(j, 2); edges.splice(i, 2); break; } } } } var delaunay = { triangulate: function(vertices, key) { var n = vertices.length; var i, j, indices, st, open, closed, edges, dx, dy, a, b, c; /* Bail if there aren't enough vertices to form any triangles. */ if (n < 3) { return []; } /* Slice out the actual vertices from the passed objects. (Duplicate the * array even if we don't, though, since we need to make a supertriangle * later on!) */ vertices = vertices.slice(0); if (key) { for (i = n; i--; ) { vertices[i] = vertices[i][key]; } } /* Make an array of indices into the vertex array, sorted by the * vertices' x-position. Force stable sorting by comparing indices if * the x-positions are equal. */ indices = new Array(n); for (i = n; i--; ) { indices[i] = i; } indices.sort(function(i, j) { var diff = vertices[j][0] - vertices[i][0]; return diff !== 0 ? diff : i - j; }); /* Next, find the vertices of the supertriangle (which contains all other * triangles), and append them onto the end of a (copy of) the vertex * array. */ st = supertriangle(vertices); vertices.push(st[0], st[1], st[2]); /* Initialize the open list (containing the supertriangle and nothing * else) and the closed list (which is empty since we havn't processed * any triangles yet). */ open = [circumcircle(vertices, n + 0, n + 1, n + 2)]; closed = []; edges = []; /* Incrementally add each vertex to the mesh. */ for (i = indices.length; i--; edges.length = 0) { c = indices[i]; /* For each open triangle, check to see if the current point is * inside it's circumcircle. If it is, remove the triangle and add * it's edges to an edge list. */ for (j = open.length; j--; ) { /* If this point is to the right of this triangle's circumcircle, * then this triangle should never get checked again. Remove it * from the open list, add it to the closed list, and skip. */ dx = vertices[c][0] - open[j].x; if (dx > 0.0 && dx * dx > open[j].r) { closed.push(open[j]); open.splice(j, 1); continue; } /* If we're outside the circumcircle, skip this triangle. */ dy = vertices[c][1] - open[j].y; if (dx * dx + dy * dy - open[j].r > EPSILON) { continue; } /* Remove the triangle and add it's edges to the edge list. */ edges.push( open[j].i, open[j].j, open[j].j, open[j].k, open[j].k, open[j].i ); open.splice(j, 1); } /* Remove any doubled edges. */ dedup(edges); /* Add a new triangle for each edge. */ for (j = edges.length; j; ) { b = edges[--j]; a = edges[--j]; open.push(circumcircle(vertices, a, b, c)); } } /* Copy any remaining open triangles to the closed list, and then * remove any triangles that share a vertex with the supertriangle, * building a list of triplets that represent triangles. */ for (i = open.length; i--; ) { closed.push(open[i]); } open.length = 0; for (i = closed.length; i--; ) { if (closed[i].i < n && closed[i].j < n && closed[i].k < n) { open.push(closed[i].i, closed[i].j, closed[i].k); } } /* Yay, we're done! */ return open; }, contains: function(tri, p) { /* Bounding box test first, for quick rejections. */ if ((p[0] < tri[0][0] && p[0] < tri[1][0] && p[0] < tri[2][0]) || (p[0] > tri[0][0] && p[0] > tri[1][0] && p[0] > tri[2][0]) || (p[1] < tri[0][1] && p[1] < tri[1][1] && p[1] < tri[2][1]) || (p[1] > tri[0][1] && p[1] > tri[1][1] && p[1] > tri[2][1])) { return null; } var a = tri[1][0] - tri[0][0]; var b = tri[2][0] - tri[0][0]; var c = tri[1][1] - tri[0][1]; var d = tri[2][1] - tri[0][1]; var i = a * d - b * c; /* Degenerate tri. */ if (i === 0.0) { return null; } var u = (d * (p[0] - tri[0][0]) - b * (p[1] - tri[0][1])) / i, v = (a * (p[1] - tri[0][1]) - c * (p[0] - tri[0][0])) / i; /* If we're outside the tri, fail. */ if (u < 0.0 || v < 0.0 || (u + v) > 1.0) { return null; } return [u, v]; } }; var GLMAT_EPSILON = 0.000001; // Use Array instead of Float32Array. It seems to be much faster and higher precision. var GLMAT_ARRAY_TYPE = Array; // if(!GLMAT_ARRAY_TYPE) { // GLMAT_ARRAY_TYPE = (typeof Float32Array !== 'undefined') ? Float32Array : Array; // } var GLMAT_RANDOM$1 = Math.random; /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 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. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ /** * @class 2 Dimensional Vector * @name vec2 */ var vec2 = {}; /** * Creates a new, empty vec2 * * @returns {vec2} a new 2D vector */ vec2.create = function() { var out = new GLMAT_ARRAY_TYPE(2); out[0] = 0; out[1] = 0; return out; }; /** * Creates a new vec2 initialized with values from an existing vector * * @param {vec2} a vector to clone * @returns {vec2} a new 2D vector */ vec2.clone = function(a) { var out = new GLMAT_ARRAY_TYPE(2); out[0] = a[0]; out[1] = a[1]; return out; }; /** * Creates a new vec2 initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @returns {vec2} a new 2D vector */ vec2.fromValues = function(x, y) { var out = new GLMAT_ARRAY_TYPE(2); out[0] = x; out[1] = y; return out; }; /** * Copy the values from one vec2 to another * * @param {vec2} out the receiving vector * @param {vec2} a the source vector * @returns {vec2} out */ vec2.copy = function(out, a) { out[0] = a[0]; out[1] = a[1]; return out; }; /** * Set the components of a vec2 to the given values * * @param {vec2} out the receiving vector * @param {Number} x X component * @param {Number} y Y component * @returns {vec2} out */ vec2.set = function(out, x, y) { out[0] = x; out[1] = y; return out; }; /** * Adds two vec2's * * @param {vec2} out the receiving vector * @param {vec2} a the first operand * @param {vec2} b the second operand * @returns {vec2} out */ vec2.add = function(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; return out; }; /** * Subtracts vector b from vector a * * @param {vec2} out the receiving vector * @param {vec2} a the first operand * @param {vec2} b the second operand * @returns {vec2} out */ vec2.subtract = function(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; return out; }; /** * Alias for {@link vec2.subtract} * @function */ vec2.sub = vec2.subtract; /** * Multiplies two vec2's * * @param {vec2} out the receiving vector * @param {vec2} a the first operand * @param {vec2} b the second operand * @returns {vec2} out */ vec2.multiply = function(out, a, b) { out[0] = a[0] * b[0]; out[1] = a[1] * b[1]; return out; }; /** * Alias for {@link vec2.multiply} * @function */ vec2.mul = vec2.multiply; /** * Divides two vec2's * * @param {vec2} out the receiving vector * @param {vec2} a the first operand * @param {vec2} b the second operand * @returns {vec2} out */ vec2.divide = function(out, a, b) { out[0] = a[0] / b[0]; out[1] = a[1] / b[1]; return out; }; /** * Alias for {@link vec2.divide} * @function */ vec2.div = vec2.divide; /** * Returns the minimum of two vec2's * * @param {vec2} out the receiving vector * @param {vec2} a the first operand * @param {vec2} b the second operand * @returns {vec2} out */ vec2.min = function(out, a, b) { out[0] = Math.min(a[0], b[0]); out[1] = Math.min(a[1], b[1]); return out; }; /** * Returns the maximum of two vec2's * * @param {vec2} out the receiving vector * @param {vec2} a the first operand * @param {vec2} b the second operand * @returns {vec2} out */ vec2.max = function(out, a, b) { out[0] = Math.max(a[0], b[0]); out[1] = Math.max(a[1], b[1]); return out; }; /** * Scales a vec2 by a scalar number * * @param {vec2} out the receiving vector * @param {vec2} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {vec2} out */ vec2.scale = function(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; return out; }; /** * Adds two vec2's after scaling the second operand by a scalar value * * @param {vec2} out the receiving vector * @param {vec2} a the first operand * @param {vec2} b the second operand * @param {Number} scale the amount to scale b by before adding * @returns {vec2} out */ vec2.scaleAndAdd = function(out, a, b, scale) { out[0] = a[0] + (b[0] * scale); out[1] = a[1] + (b[1] * scale); return out; }; /** * Calculates the euclidian distance between two vec2's * * @param {vec2} a the first operand * @param {vec2} b the second operand * @returns {Number} distance between a and b */ vec2.distance = function(a, b) { var x = b[0] - a[0], y = b[1] - a[1]; return Math.sqrt(x*x + y*y); }; /** * Alias for {@link vec2.distance} * @function */ vec2.dist = vec2.distance; /** * Calculates the squared euclidian distance between two vec2's * * @param {vec2} a the first operand * @param {vec2} b the second operand * @returns {Number} squared distance between a and b */ vec2.squaredDistance = function(a, b) { var x = b[0] - a[0], y = b[1] - a[1]; return x*x + y*y; }; /** * Alias for {@link vec2.squaredDistance} * @function */ vec2.sqrDist = vec2.squaredDistance; /** * Calculates the length of a vec2 * * @param {vec2} a vector to calculate length of * @returns {Number} length of a */ vec2.length = function (a) { var x = a[0], y = a[1]; return Math.sqrt(x*x + y*y); }; /** * Alias for {@link vec2.length} * @function */ vec2.len = vec2.length; /** * Calculates the squared length of a vec2 * * @param {vec2} a vector to calculate squared length of * @returns {Number} squared length of a */ vec2.squaredLength = function (a) { var x = a[0], y = a[1]; return x*x + y*y; }; /** * Alias for {@link vec2.squaredLength} * @function */ vec2.sqrLen = vec2.squaredLength; /** * Negates the components of a vec2 * * @param {vec2} out the receiving vector * @param {vec2} a vector to negate * @returns {vec2} out */ vec2.negate = function(out, a) { out[0] = -a[0]; out[1] = -a[1]; return out; }; /** * Returns the inverse of the components of a vec2 * * @param {vec2} out the receiving vector * @param {vec2} a vector to invert * @returns {vec2} out */ vec2.inverse = function(out, a) { out[0] = 1.0 / a[0]; out[1] = 1.0 / a[1]; return out; }; /** * Normalize a vec2 * * @param {vec2} out the receiving vector * @param {vec2} a vector to normalize * @returns {vec2} out */ vec2.normalize = function(out, a) { var x = a[0], y = a[1]; var len = x*x + y*y; if (len > 0) { //TODO: evaluate use of glm_invsqrt here? len = 1 / Math.sqrt(len); out[0] = a[0] * len; out[1] = a[1] * len; } return out; }; /** * Calculates the dot product of two vec2's * * @param {vec2} a the first operand * @param {vec2} b the second operand * @returns {Number} dot product of a and b */ vec2.dot = function (a, b) { return a[0] * b[0] + a[1] * b[1]; }; /** * Computes the cross product of two vec2's * Note that the cross product must by definition produce a 3D vector * * @param {vec3} out the receiving vector * @param {vec2} a the first operand * @param {vec2} b the second operand * @returns {vec3} out */ vec2.cross = function(out, a, b) { var z = a[0] * b[1] - a[1] * b[0]; out[0] = out[1] = 0; out[2] = z; return out; }; /** * Performs a linear interpolation between two vec2's * * @param {vec2} out the receiving vector * @param {vec2} a the first operand * @param {vec2} b the second operand * @param {Number} t interpolation amount between the two inputs * @returns {vec2} out */ vec2.lerp = function (out, a, b, t) { var ax = a[0], ay = a[1]; out[0] = ax + t * (b[0] - ax); out[1] = ay + t * (b[1] - ay); return out; }; /** * Generates a random vector with the given scale * * @param {vec2} out the receiving vector * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned * @returns {vec2} out */ vec2.random = function (out, scale) { scale = scale || 1.0; var r = GLMAT_RANDOM() * 2.0 * Math.PI; out[0] = Math.cos(r) * scale; out[1] = Math.sin(r) * scale; return out; }; /** * Transforms the vec2 with a mat2 * * @param {vec2} out the receiving vector * @param {vec2} a the vector to transform * @param {mat2} m matrix to transform with * @returns {vec2} out */ vec2.transformMat2 = function(out, a, m) { var x = a[0], y = a[1]; out[0] = m[0] * x + m[2] * y; out[1] = m[1] * x + m[3] * y; return out; }; /** * Transforms the vec2 with a mat2d * * @param {vec2} out the receiving vector * @param {vec2} a the vector to transform * @param {mat2d} m matrix to transform with * @returns {vec2} out */ vec2.transformMat2d = function(out, a, m) { var x = a[0], y = a[1]; out[0] = m[0] * x + m[2] * y + m[4]; out[1] = m[1] * x + m[3] * y + m[5]; return out; }; /** * Transforms the vec2 with a mat3 * 3rd vector component is implicitly '1' * * @param {vec2} out the receiving vector * @param {vec2} a the vector to transform * @param {mat3} m matrix to transform with * @returns {vec2} out */ vec2.transformMat3 = function(out, a, m) { var x = a[0], y = a[1]; out[0] = m[0] * x + m[3] * y + m[6]; out[1] = m[1] * x + m[4] * y + m[7]; return out; }; /** * Transforms the vec2 with a mat4 * 3rd vector component is implicitly '0' * 4th vector component is implicitly '1' * * @param {vec2} out the receiving vector * @param {vec2} a the vector to transform * @param {mat4} m matrix to transform with * @returns {vec2} out */ vec2.transformMat4 = function(out, a, m) { var x = a[0], y = a[1]; out[0] = m[0] * x + m[4] * y + m[12]; out[1] = m[1] * x + m[5] * y + m[13]; return out; }; /** * Perform some operation over an array of vec2s. * * @param {Array} a the array of vectors to iterate over * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed * @param {Number} offset Number of elements to skip at the beginning of the array * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array * @param {Function} fn Function to call for each vector in the array * @param {Object} [arg] additional argument to pass to fn * @returns {Array} a * @function */ vec2.forEach = (function() { var vec = vec2.create(); return function(a, stride, offset, count, fn, arg) { var i, l; if(!stride) { stride = 2; } if(!offset) { offset = 0; } if(count) { l = Math.min((count * stride) + offset, a.length); } else { l = a.length; } for(i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i+1]; fn(vec, vec, arg); a[i] = vec[0]; a[i+1] = vec[1]; } return a; }; })(); /** * @constructor * @alias clay.Vector2 * @param {number} x * @param {number} y */ var Vector2 = function(x, y) { x = x || 0; y = y || 0; /** * Storage of Vector2, read and write of x, y will change the values in array * All methods also operate on the array instead of x, y components * @name array * @type {Float32Array} * @memberOf clay.Vector2# */ this.array = vec2.fromValues(x, y); /** * Dirty flag is used by the Node to determine * if the matrix is updated to latest * @name _dirty * @type {boolean} * @memberOf clay.Vector2# */ this._dirty = true; }; Vector2.prototype = { constructor: Vector2, /** * Add b to self * @param {clay.Vector2} b * @return {clay.Vector2} */ add: function(b) { vec2.add(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Set x and y components * @param {number} x * @param {number} y * @return {clay.Vector2} */ set: function(x, y) { this.array[0] = x; this.array[1] = y; this._dirty = true; return this; }, /** * Set x and y components from array * @param {Float32Array|number[]} arr * @return {clay.Vector2} */ setArray: function(arr) { this.array[0] = arr[0]; this.array[1] = arr[1]; this._dirty = true; return this; }, /** * Clone a new Vector2 * @return {clay.Vector2} */ clone: function() { return new Vector2(this.x, this.y); }, /** * Copy x, y from b * @param {clay.Vector2} b * @return {clay.Vector2} */ copy: function(b) { vec2.copy(this.array, b.array); this._dirty = true; return this; }, /** * Cross product of self and b, written to a Vector3 out * @param {clay.Vector3} out * @param {clay.Vector2} b * @return {clay.Vector2} */ cross: function(out, b) { vec2.cross(out.array, this.array, b.array); out._dirty = true; return this; }, /** * Alias for distance * @param {clay.Vector2} b * @return {number} */ dist: function(b) { return vec2.dist(this.array, b.array); }, /** * Distance between self and b * @param {clay.Vector2} b * @return {number} */ distance: function(b) { return vec2.distance(this.array, b.array); }, /** * Alias for divide * @param {clay.Vector2} b * @return {clay.Vector2} */ div: function(b) { vec2.div(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Divide self by b * @param {clay.Vector2} b * @return {clay.Vector2} */ divide: function(b) { vec2.divide(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Dot product of self and b * @param {clay.Vector2} b * @return {number} */ dot: function(b) { return vec2.dot(this.array, b.array); }, /** * Alias of length * @return {number} */ len: function() { return vec2.len(this.array); }, /** * Calculate the length * @return {number} */ length: function() { return vec2.length(this.array); }, /** * Linear interpolation between a and b * @param {clay.Vector2} a * @param {clay.Vector2} b * @param {number} t * @return {clay.Vector2} */ lerp: function(a, b, t) { vec2.lerp(this.array, a.array, b.array, t); this._dirty = true; return this; }, /** * Minimum of self and b * @param {clay.Vector2} b * @return {clay.Vector2} */ min: function(b) { vec2.min(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Maximum of self and b * @param {clay.Vector2} b * @return {clay.Vector2} */ max: function(b) { vec2.max(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Alias for multiply * @param {clay.Vector2} b * @return {clay.Vector2} */ mul: function(b) { vec2.mul(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Mutiply self and b * @param {clay.Vector2} b * @return {clay.Vector2} */ multiply: function(b) { vec2.multiply(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Negate self * @return {clay.Vector2} */ negate: function() { vec2.negate(this.array, this.array); this._dirty = true; return this; }, /** * Normalize self * @return {clay.Vector2} */ normalize: function() { vec2.normalize(this.array, this.array); this._dirty = true; return this; }, /** * Generate random x, y components with a given scale * @param {number} scale * @return {clay.Vector2} */ random: function(scale) { vec2.random(this.array, scale); this._dirty = true; return this; }, /** * Scale self * @param {number} scale * @return {clay.Vector2} */ scale: function(s) { vec2.scale(this.array, this.array, s); this._dirty = true; return this; }, /** * Scale b and add to self * @param {clay.Vector2} b * @param {number} scale * @return {clay.Vector2} */ scaleAndAdd: function(b, s) { vec2.scaleAndAdd(this.array, this.array, b.array, s); this._dirty = true; return this; }, /** * Alias for squaredDistance * @param {clay.Vector2} b * @return {number} */ sqrDist: function(b) { return vec2.sqrDist(this.array, b.array); }, /** * Squared distance between self and b * @param {clay.Vector2} b * @return {number} */ squaredDistance: function(b) { return vec2.squaredDistance(this.array, b.array); }, /** * Alias for squaredLength * @return {number} */ sqrLen: function() { return vec2.sqrLen(this.array); }, /** * Squared length of self * @return {number} */ squaredLength: function() { return vec2.squaredLength(this.array); }, /** * Alias for subtract * @param {clay.Vector2} b * @return {clay.Vector2} */ sub: function(b) { vec2.sub(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Subtract b from self * @param {clay.Vector2} b * @return {clay.Vector2} */ subtract: function(b) { vec2.subtract(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Transform self with a Matrix2 m * @param {clay.Matrix2} m * @return {clay.Vector2} */ transformMat2: function(m) { vec2.transformMat2(this.array, this.array, m.array); this._dirty = true; return this; }, /** * Transform self with a Matrix2d m * @param {clay.Matrix2d} m * @return {clay.Vector2} */ transformMat2d: function(m) { vec2.transformMat2d(this.array, this.array, m.array); this._dirty = true; return this; }, /** * Transform self with a Matrix3 m * @param {clay.Matrix3} m * @return {clay.Vector2} */ transformMat3: function(m) { vec2.transformMat3(this.array, this.array, m.array); this._dirty = true; return this; }, /** * Transform self with a Matrix4 m * @param {clay.Matrix4} m * @return {clay.Vector2} */ transformMat4: function(m) { vec2.transformMat4(this.array, this.array, m.array); this._dirty = true; return this; }, toString: function() { return '[' + Array.prototype.join.call(this.array, ',') + ']'; }, toArray: function () { return Array.prototype.slice.call(this.array); } }; // Getter and Setter if (Object.defineProperty) { var proto = Vector2.prototype; /** * @name x * @type {number} * @memberOf clay.Vector2 * @instance */ Object.defineProperty(proto, 'x', { get: function () { return this.array[0]; }, set: function (value) { this.array[0] = value; this._dirty = true; } }); /** * @name y * @type {number} * @memberOf clay.Vector2 * @instance */ Object.defineProperty(proto, 'y', { get: function () { return this.array[1]; }, set: function (value) { this.array[1] = value; this._dirty = true; } }); } // Supply methods that are not in place /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.add = function(out, a, b) { vec2.add(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {number} x * @param {number} y * @return {clay.Vector2} */ Vector2.set = function(out, x, y) { vec2.set(out.array, x, y); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.copy = function(out, b) { vec2.copy(out.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector3} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.cross = function(out, a, b) { vec2.cross(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {number} */ Vector2.dist = function(a, b) { return vec2.distance(a.array, b.array); }; /** * @function * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {number} */ Vector2.distance = Vector2.dist; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.div = function(out, a, b) { vec2.divide(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.divide = Vector2.div; /** * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {number} */ Vector2.dot = function(a, b) { return vec2.dot(a.array, b.array); }; /** * @param {clay.Vector2} a * @return {number} */ Vector2.len = function(b) { return vec2.length(b.array); }; // Vector2.length = Vector2.len; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @param {number} t * @return {clay.Vector2} */ Vector2.lerp = function(out, a, b, t) { vec2.lerp(out.array, a.array, b.array, t); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.min = function(out, a, b) { vec2.min(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.max = function(out, a, b) { vec2.max(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.mul = function(out, a, b) { vec2.multiply(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.multiply = Vector2.mul; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @return {clay.Vector2} */ Vector2.negate = function(out, a) { vec2.negate(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @return {clay.Vector2} */ Vector2.normalize = function(out, a) { vec2.normalize(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {number} scale * @return {clay.Vector2} */ Vector2.random = function(out, scale) { vec2.random(out.array, scale); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {number} scale * @return {clay.Vector2} */ Vector2.scale = function(out, a, scale) { vec2.scale(out.array, a.array, scale); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @param {number} scale * @return {clay.Vector2} */ Vector2.scaleAndAdd = function(out, a, b, scale) { vec2.scaleAndAdd(out.array, a.array, b.array, scale); out._dirty = true; return out; }; /** * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {number} */ Vector2.sqrDist = function(a, b) { return vec2.sqrDist(a.array, b.array); }; /** * @function * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {number} */ Vector2.squaredDistance = Vector2.sqrDist; /** * @param {clay.Vector2} a * @return {number} */ Vector2.sqrLen = function(a) { return vec2.sqrLen(a.array); }; /** * @function * @param {clay.Vector2} a * @return {number} */ Vector2.squaredLength = Vector2.sqrLen; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.sub = function(out, a, b) { vec2.subtract(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.subtract = Vector2.sub; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Matrix2} m * @return {clay.Vector2} */ Vector2.transformMat2 = function(out, a, m) { vec2.transformMat2(out.array, a.array, m.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Matrix2d} m * @return {clay.Vector2} */ Vector2.transformMat2d = function(out, a, m) { vec2.transformMat2d(out.array, a.array, m.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {Matrix3} m * @return {clay.Vector2} */ Vector2.transformMat3 = function(out, a, m) { vec2.transformMat3(out.array, a.array, m.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Matrix4} m * @return {clay.Vector2} */ Vector2.transformMat4 = function(out, a, m) { vec2.transformMat4(out.array, a.array, m.array); out._dirty = true; return out; }; // 2D Blend clip of blend tree // http://docs.unity3d.com/Documentation/Manual/2DBlending.html /** * @typedef {Object} clay.animation.Blend2DClip.IClipInput * @property {clay.Vector2} position * @property {clay.animation.Clip} clip * @property {number} offset */ /** * 2d blending node in animation blend tree. * output clip must have blend2D method * @constructor * @alias clay.animation.Blend2DClip * @extends clay.animation.Clip * * @param {Object} [opts] * @param {string} [opts.name] * @param {Object} [opts.target] * @param {number} [opts.life] * @param {number} [opts.delay] * @param {number} [opts.gap] * @param {number} [opts.playbackRatio] * @param {boolean|number} [opts.loop] If loop is a number, it indicate the loop count of animation * @param {string|Function} [opts.easing] * @param {Function} [opts.onframe] * @param {Function} [opts.onfinish] * @param {Function} [opts.onrestart] * @param {object[]} [opts.inputs] * @param {clay.Vector2} [opts.position] * @param {clay.animation.Clip} [opts.output] */ var Blend2DClip = function (opts) { opts = opts || {}; Clip.call(this, opts); /** * Output clip must have blend2D method * @type {clay.animation.Clip} */ this.output = opts.output || null; /** * @type {clay.animation.Blend2DClip.IClipInput[]} */ this.inputs = opts.inputs || []; /** * @type {clay.Vector2} */ this.position = new Vector2(); this._cacheTriangle = null; this._triangles = []; this._updateTriangles(); }; Blend2DClip.prototype = new Clip(); Blend2DClip.prototype.constructor = Blend2DClip; /** * @param {clay.Vector2} position * @param {clay.animation.Clip} inputClip * @param {number} [offset] * @return {clay.animation.Blend2DClip.IClipInput} */ Blend2DClip.prototype.addInput = function (position, inputClip, offset) { var obj = { position : position, clip : inputClip, offset : offset || 0 }; this.inputs.push(obj); this.life = Math.max(inputClip.life, this.life); // TODO Change to incrementally adding this._updateTriangles(); return obj; }; // Delaunay triangulate Blend2DClip.prototype._updateTriangles = function () { var inputs = this.inputs.map(function (a) { return a.position; }); this._triangles = delaunay.triangulate(inputs, 'array'); }; Blend2DClip.prototype.step = function (time, dTime, silent) { var ret = Clip.prototype.step.call(this, time); if (ret !== 'finish') { this.setTime(this.getElapsedTime()); } // PENDING Schedule if (!silent && ret !== 'paused') { this.fire('frame'); } return ret; }; Blend2DClip.prototype.setTime = function (time) { var res = this._findTriangle(this.position); if (!res) { return; } // In Barycentric var a = res[1]; // Percent of clip2 var b = res[2]; // Percent of clip3 var tri = res[0]; var in1 = this.inputs[tri.indices[0]]; var in2 = this.inputs[tri.indices[1]]; var in3 = this.inputs[tri.indices[2]]; var clip1 = in1.clip; var clip2 = in2.clip; var clip3 = in3.clip; clip1.setTime((time + in1.offset) % clip1.life); clip2.setTime((time + in2.offset) % clip2.life); clip3.setTime((time + in3.offset) % clip3.life); var c1 = clip1.output instanceof Clip ? clip1.output : clip1; var c2 = clip2.output instanceof Clip ? clip2.output : clip2; var c3 = clip3.output instanceof Clip ? clip3.output : clip3; this.output.blend2D(c1, c2, c3, a, b); }; /** * Clone a new Blend2D clip * @param {boolean} cloneInputs True if clone the input clips * @return {clay.animation.Blend2DClip} */ Blend2DClip.prototype.clone = function (cloneInputs) { var clip = Clip.prototype.clone.call(this); clip.output = this.output.clone(); for (var i = 0; i < this.inputs.length; i++) { var inputClip = cloneInputs ? this.inputs[i].clip.clone(true) : this.inputs[i].clip; clip.addInput(this.inputs[i].position, inputClip, this.inputs[i].offset); } return clip; }; Blend2DClip.prototype._findTriangle = function (position) { if (this._cacheTriangle) { var res = delaunay.contains(this._cacheTriangle.vertices, position.array); if (res) { return [this._cacheTriangle, res[0], res[1]]; } } for (var i = 0; i < this._triangles.length; i++) { var tri = this._triangles[i]; var res = delaunay.contains(tri.vertices, this.position.array); if (res) { this._cacheTriangle = tri; return [tri, res[0], res[1]]; } } }; /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 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. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ /** * @class 3 Dimensional Vector * @name vec3 */ var vec3 = {}; /** * Creates a new, empty vec3 * * @returns {vec3} a new 3D vector */ vec3.create = function() { var out = new GLMAT_ARRAY_TYPE(3); out[0] = 0; out[1] = 0; out[2] = 0; return out; }; /** * Creates a new vec3 initialized with values from an existing vector * * @param {vec3} a vector to clone * @returns {vec3} a new 3D vector */ vec3.clone = function(a) { var out = new GLMAT_ARRAY_TYPE(3); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; return out; }; /** * Creates a new vec3 initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @returns {vec3} a new 3D vector */ vec3.fromValues = function(x, y, z) { var out = new GLMAT_ARRAY_TYPE(3); out[0] = x; out[1] = y; out[2] = z; return out; }; /** * Copy the values from one vec3 to another * * @param {vec3} out the receiving vector * @param {vec3} a the source vector * @returns {vec3} out */ vec3.copy = function(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; return out; }; /** * Set the components of a vec3 to the given values * * @param {vec3} out the receiving vector * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @returns {vec3} out */ vec3.set = function(out, x, y, z) { out[0] = x; out[1] = y; out[2] = z; return out; }; /** * Adds two vec3's * * @param {vec3} out the receiving vector * @param {vec3} a the first operand * @param {vec3} b the second operand * @returns {vec3} out */ vec3.add = function(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; return out; }; /** * Subtracts vector b from vector a * * @param {vec3} out the receiving vector * @param {vec3} a the first operand * @param {vec3} b the second operand * @returns {vec3} out */ vec3.subtract = function(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; return out; }; /** * Alias for {@link vec3.subtract} * @function */ vec3.sub = vec3.subtract; /** * Multiplies two vec3's * * @param {vec3} out the receiving vector * @param {vec3} a the first operand * @param {vec3} b the second operand * @returns {vec3} out */ vec3.multiply = function(out, a, b) { out[0] = a[0] * b[0]; out[1] = a[1] * b[1]; out[2] = a[2] * b[2]; return out; }; /** * Alias for {@link vec3.multiply} * @function */ vec3.mul = vec3.multiply; /** * Divides two vec3's * * @param {vec3} out the receiving vector * @param {vec3} a the first operand * @param {vec3} b the second operand * @returns {vec3} out */ vec3.divide = function(out, a, b) { out[0] = a[0] / b[0]; out[1] = a[1] / b[1]; out[2] = a[2] / b[2]; return out; }; /** * Alias for {@link vec3.divide} * @function */ vec3.div = vec3.divide; /** * Returns the minimum of two vec3's * * @param {vec3} out the receiving vector * @param {vec3} a the first operand * @param {vec3} b the second operand * @returns {vec3} out */ vec3.min = function(out, a, b) { out[0] = Math.min(a[0], b[0]); out[1] = Math.min(a[1], b[1]); out[2] = Math.min(a[2], b[2]); return out; }; /** * Returns the maximum of two vec3's * * @param {vec3} out the receiving vector * @param {vec3} a the first operand * @param {vec3} b the second operand * @returns {vec3} out */ vec3.max = function(out, a, b) { out[0] = Math.max(a[0], b[0]); out[1] = Math.max(a[1], b[1]); out[2] = Math.max(a[2], b[2]); return out; }; /** * Scales a vec3 by a scalar number * * @param {vec3} out the receiving vector * @param {vec3} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {vec3} out */ vec3.scale = function(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; return out; }; /** * Adds two vec3's after scaling the second operand by a scalar value * * @param {vec3} out the receiving vector * @param {vec3} a the first operand * @param {vec3} b the second operand * @param {Number} scale the amount to scale b by before adding * @returns {vec3} out */ vec3.scaleAndAdd = function(out, a, b, scale) { out[0] = a[0] + (b[0] * scale); out[1] = a[1] + (b[1] * scale); out[2] = a[2] + (b[2] * scale); return out; }; /** * Calculates the euclidian distance between two vec3's * * @param {vec3} a the first operand * @param {vec3} b the second operand * @returns {Number} distance between a and b */ vec3.distance = function(a, b) { var x = b[0] - a[0], y = b[1] - a[1], z = b[2] - a[2]; return Math.sqrt(x*x + y*y + z*z); }; /** * Alias for {@link vec3.distance} * @function */ vec3.dist = vec3.distance; /** * Calculates the squared euclidian distance between two vec3's * * @param {vec3} a the first operand * @param {vec3} b the second operand * @returns {Number} squared distance between a and b */ vec3.squaredDistance = function(a, b) { var x = b[0] - a[0], y = b[1] - a[1], z = b[2] - a[2]; return x*x + y*y + z*z; }; /** * Alias for {@link vec3.squaredDistance} * @function */ vec3.sqrDist = vec3.squaredDistance; /** * Calculates the length of a vec3 * * @param {vec3} a vector to calculate length of * @returns {Number} length of a */ vec3.length = function (a) { var x = a[0], y = a[1], z = a[2]; return Math.sqrt(x*x + y*y + z*z); }; /** * Alias for {@link vec3.length} * @function */ vec3.len = vec3.length; /** * Calculates the squared length of a vec3 * * @param {vec3} a vector to calculate squared length of * @returns {Number} squared length of a */ vec3.squaredLength = function (a) { var x = a[0], y = a[1], z = a[2]; return x*x + y*y + z*z; }; /** * Alias for {@link vec3.squaredLength} * @function */ vec3.sqrLen = vec3.squaredLength; /** * Negates the components of a vec3 * * @param {vec3} out the receiving vector * @param {vec3} a vector to negate * @returns {vec3} out */ vec3.negate = function(out, a) { out[0] = -a[0]; out[1] = -a[1]; out[2] = -a[2]; return out; }; /** * Returns the inverse of the components of a vec3 * * @param {vec3} out the receiving vector * @param {vec3} a vector to invert * @returns {vec3} out */ vec3.inverse = function(out, a) { out[0] = 1.0 / a[0]; out[1] = 1.0 / a[1]; out[2] = 1.0 / a[2]; return out; }; /** * Normalize a vec3 * * @param {vec3} out the receiving vector * @param {vec3} a vector to normalize * @returns {vec3} out */ vec3.normalize = function(out, a) { var x = a[0], y = a[1], z = a[2]; var len = x*x + y*y + z*z; if (len > 0) { //TODO: evaluate use of glm_invsqrt here? len = 1 / Math.sqrt(len); out[0] = a[0] * len; out[1] = a[1] * len; out[2] = a[2] * len; } return out; }; /** * Calculates the dot product of two vec3's * * @param {vec3} a the first operand * @param {vec3} b the second operand * @returns {Number} dot product of a and b */ vec3.dot = function (a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; }; /** * Computes the cross product of two vec3's * * @param {vec3} out the receiving vector * @param {vec3} a the first operand * @param {vec3} b the second operand * @returns {vec3} out */ vec3.cross = function(out, a, b) { var ax = a[0], ay = a[1], az = a[2], bx = b[0], by = b[1], bz = b[2]; out[0] = ay * bz - az * by; out[1] = az * bx - ax * bz; out[2] = ax * by - ay * bx; return out; }; /** * Performs a linear interpolation between two vec3's * * @param {vec3} out the receiving vector * @param {vec3} a the first operand * @param {vec3} b the second operand * @param {Number} t interpolation amount between the two inputs * @returns {vec3} out */ vec3.lerp = function (out, a, b, t) { var ax = a[0], ay = a[1], az = a[2]; out[0] = ax + t * (b[0] - ax); out[1] = ay + t * (b[1] - ay); out[2] = az + t * (b[2] - az); return out; }; /** * Generates a random vector with the given scale * * @param {vec3} out the receiving vector * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned * @returns {vec3} out */ vec3.random = function (out, scale) { scale = scale || 1.0; var r = GLMAT_RANDOM$1() * 2.0 * Math.PI; var z = (GLMAT_RANDOM$1() * 2.0) - 1.0; var zScale = Math.sqrt(1.0-z*z) * scale; out[0] = Math.cos(r) * zScale; out[1] = Math.sin(r) * zScale; out[2] = z * scale; return out; }; /** * Transforms the vec3 with a mat4. * 4th vector component is implicitly '1' * * @param {vec3} out the receiving vector * @param {vec3} a the vector to transform * @param {mat4} m matrix to transform with * @returns {vec3} out */ vec3.transformMat4 = function(out, a, m) { var x = a[0], y = a[1], z = a[2], w = m[3] * x + m[7] * y + m[11] * z + m[15]; w = w || 1.0; out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w; out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w; out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w; return out; }; /** * Transforms the vec3 with a mat3. * * @param {vec3} out the receiving vector * @param {vec3} a the vector to transform * @param {mat4} m the 3x3 matrix to transform with * @returns {vec3} out */ vec3.transformMat3 = function(out, a, m) { var x = a[0], y = a[1], z = a[2]; out[0] = x * m[0] + y * m[3] + z * m[6]; out[1] = x * m[1] + y * m[4] + z * m[7]; out[2] = x * m[2] + y * m[5] + z * m[8]; return out; }; /** * Transforms the vec3 with a quat * * @param {vec3} out the receiving vector * @param {vec3} a the vector to transform * @param {quat} q quaternion to transform with * @returns {vec3} out */ vec3.transformQuat = function(out, a, q) { // benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations var x = a[0], y = a[1], z = a[2], qx = q[0], qy = q[1], qz = q[2], qw = q[3], // calculate quat * vec ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; return out; }; /** * Rotate a 3D vector around the x-axis * @param {vec3} out The receiving vec3 * @param {vec3} a The vec3 point to rotate * @param {vec3} b The origin of the rotation * @param {Number} c The angle of rotation * @returns {vec3} out */ vec3.rotateX = function(out, a, b, c){ var p = [], r=[]; //Translate point to the origin p[0] = a[0] - b[0]; p[1] = a[1] - b[1]; p[2] = a[2] - b[2]; //perform rotation r[0] = p[0]; r[1] = p[1]*Math.cos(c) - p[2]*Math.sin(c); r[2] = p[1]*Math.sin(c) + p[2]*Math.cos(c); //translate to correct position out[0] = r[0] + b[0]; out[1] = r[1] + b[1]; out[2] = r[2] + b[2]; return out; }; /** * Rotate a 3D vector around the y-axis * @param {vec3} out The receiving vec3 * @param {vec3} a The vec3 point to rotate * @param {vec3} b The origin of the rotation * @param {Number} c The angle of rotation * @returns {vec3} out */ vec3.rotateY = function(out, a, b, c){ var p = [], r=[]; //Translate point to the origin p[0] = a[0] - b[0]; p[1] = a[1] - b[1]; p[2] = a[2] - b[2]; //perform rotation r[0] = p[2]*Math.sin(c) + p[0]*Math.cos(c); r[1] = p[1]; r[2] = p[2]*Math.cos(c) - p[0]*Math.sin(c); //translate to correct position out[0] = r[0] + b[0]; out[1] = r[1] + b[1]; out[2] = r[2] + b[2]; return out; }; /** * Rotate a 3D vector around the z-axis * @param {vec3} out The receiving vec3 * @param {vec3} a The vec3 point to rotate * @param {vec3} b The origin of the rotation * @param {Number} c The angle of rotation * @returns {vec3} out */ vec3.rotateZ = function(out, a, b, c){ var p = [], r=[]; //Translate point to the origin p[0] = a[0] - b[0]; p[1] = a[1] - b[1]; p[2] = a[2] - b[2]; //perform rotation r[0] = p[0]*Math.cos(c) - p[1]*Math.sin(c); r[1] = p[0]*Math.sin(c) + p[1]*Math.cos(c); r[2] = p[2]; //translate to correct position out[0] = r[0] + b[0]; out[1] = r[1] + b[1]; out[2] = r[2] + b[2]; return out; }; /** * Perform some operation over an array of vec3s. * * @param {Array} a the array of vectors to iterate over * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed * @param {Number} offset Number of elements to skip at the beginning of the array * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array * @param {Function} fn Function to call for each vector in the array * @param {Object} [arg] additional argument to pass to fn * @returns {Array} a * @function */ vec3.forEach = (function() { var vec = vec3.create(); return function(a, stride, offset, count, fn, arg) { var i, l; if(!stride) { stride = 3; } if(!offset) { offset = 0; } if(count) { l = Math.min((count * stride) + offset, a.length); } else { l = a.length; } for(i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2]; fn(vec, vec, arg); a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2]; } return a; }; })(); /** * Get the angle between two 3D vectors * @param {vec3} a The first operand * @param {vec3} b The second operand * @returns {Number} The angle in radians */ vec3.angle = function(a, b) { var tempA = vec3.fromValues(a[0], a[1], a[2]); var tempB = vec3.fromValues(b[0], b[1], b[2]); vec3.normalize(tempA, tempA); vec3.normalize(tempB, tempB); var cosine = vec3.dot(tempA, tempB); if(cosine > 1.0){ return 0; } else { return Math.acos(cosine); } }; /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 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. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ /** * @class 4 Dimensional Vector * @name vec4 */ var vec4 = {}; /** * Creates a new, empty vec4 * * @returns {vec4} a new 4D vector */ vec4.create = function() { var out = new GLMAT_ARRAY_TYPE(4); out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 0; return out; }; /** * Creates a new vec4 initialized with values from an existing vector * * @param {vec4} a vector to clone * @returns {vec4} a new 4D vector */ vec4.clone = function(a) { var out = new GLMAT_ARRAY_TYPE(4); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; }; /** * Creates a new vec4 initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @param {Number} w W component * @returns {vec4} a new 4D vector */ vec4.fromValues = function(x, y, z, w) { var out = new GLMAT_ARRAY_TYPE(4); out[0] = x; out[1] = y; out[2] = z; out[3] = w; return out; }; /** * Copy the values from one vec4 to another * * @param {vec4} out the receiving vector * @param {vec4} a the source vector * @returns {vec4} out */ vec4.copy = function(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; }; /** * Set the components of a vec4 to the given values * * @param {vec4} out the receiving vector * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @param {Number} w W component * @returns {vec4} out */ vec4.set = function(out, x, y, z, w) { out[0] = x; out[1] = y; out[2] = z; out[3] = w; return out; }; /** * Adds two vec4's * * @param {vec4} out the receiving vector * @param {vec4} a the first operand * @param {vec4} b the second operand * @returns {vec4} out */ vec4.add = function(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; return out; }; /** * Subtracts vector b from vector a * * @param {vec4} out the receiving vector * @param {vec4} a the first operand * @param {vec4} b the second operand * @returns {vec4} out */ vec4.subtract = function(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; out[3] = a[3] - b[3]; return out; }; /** * Alias for {@link vec4.subtract} * @function */ vec4.sub = vec4.subtract; /** * Multiplies two vec4's * * @param {vec4} out the receiving vector * @param {vec4} a the first operand * @param {vec4} b the second operand * @returns {vec4} out */ vec4.multiply = function(out, a, b) { out[0] = a[0] * b[0]; out[1] = a[1] * b[1]; out[2] = a[2] * b[2]; out[3] = a[3] * b[3]; return out; }; /** * Alias for {@link vec4.multiply} * @function */ vec4.mul = vec4.multiply; /** * Divides two vec4's * * @param {vec4} out the receiving vector * @param {vec4} a the first operand * @param {vec4} b the second operand * @returns {vec4} out */ vec4.divide = function(out, a, b) { out[0] = a[0] / b[0]; out[1] = a[1] / b[1]; out[2] = a[2] / b[2]; out[3] = a[3] / b[3]; return out; }; /** * Alias for {@link vec4.divide} * @function */ vec4.div = vec4.divide; /** * Returns the minimum of two vec4's * * @param {vec4} out the receiving vector * @param {vec4} a the first operand * @param {vec4} b the second operand * @returns {vec4} out */ vec4.min = function(out, a, b) { out[0] = Math.min(a[0], b[0]); out[1] = Math.min(a[1], b[1]); out[2] = Math.min(a[2], b[2]); out[3] = Math.min(a[3], b[3]); return out; }; /** * Returns the maximum of two vec4's * * @param {vec4} out the receiving vector * @param {vec4} a the first operand * @param {vec4} b the second operand * @returns {vec4} out */ vec4.max = function(out, a, b) { out[0] = Math.max(a[0], b[0]); out[1] = Math.max(a[1], b[1]); out[2] = Math.max(a[2], b[2]); out[3] = Math.max(a[3], b[3]); return out; }; /** * Scales a vec4 by a scalar number * * @param {vec4} out the receiving vector * @param {vec4} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {vec4} out */ vec4.scale = function(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; out[3] = a[3] * b; return out; }; /** * Adds two vec4's after scaling the second operand by a scalar value * * @param {vec4} out the receiving vector * @param {vec4} a the first operand * @param {vec4} b the second operand * @param {Number} scale the amount to scale b by before adding * @returns {vec4} out */ vec4.scaleAndAdd = function(out, a, b, scale) { out[0] = a[0] + (b[0] * scale); out[1] = a[1] + (b[1] * scale); out[2] = a[2] + (b[2] * scale); out[3] = a[3] + (b[3] * scale); return out; }; /** * Calculates the euclidian distance between two vec4's * * @param {vec4} a the first operand * @param {vec4} b the second operand * @returns {Number} distance between a and b */ vec4.distance = function(a, b) { var x = b[0] - a[0], y = b[1] - a[1], z = b[2] - a[2], w = b[3] - a[3]; return Math.sqrt(x*x + y*y + z*z + w*w); }; /** * Alias for {@link vec4.distance} * @function */ vec4.dist = vec4.distance; /** * Calculates the squared euclidian distance between two vec4's * * @param {vec4} a the first operand * @param {vec4} b the second operand * @returns {Number} squared distance between a and b */ vec4.squaredDistance = function(a, b) { var x = b[0] - a[0], y = b[1] - a[1], z = b[2] - a[2], w = b[3] - a[3]; return x*x + y*y + z*z + w*w; }; /** * Alias for {@link vec4.squaredDistance} * @function */ vec4.sqrDist = vec4.squaredDistance; /** * Calculates the length of a vec4 * * @param {vec4} a vector to calculate length of * @returns {Number} length of a */ vec4.length = function (a) { var x = a[0], y = a[1], z = a[2], w = a[3]; return Math.sqrt(x*x + y*y + z*z + w*w); }; /** * Alias for {@link vec4.length} * @function */ vec4.len = vec4.length; /** * Calculates the squared length of a vec4 * * @param {vec4} a vector to calculate squared length of * @returns {Number} squared length of a */ vec4.squaredLength = function (a) { var x = a[0], y = a[1], z = a[2], w = a[3]; return x*x + y*y + z*z + w*w; }; /** * Alias for {@link vec4.squaredLength} * @function */ vec4.sqrLen = vec4.squaredLength; /** * Negates the components of a vec4 * * @param {vec4} out the receiving vector * @param {vec4} a vector to negate * @returns {vec4} out */ vec4.negate = function(out, a) { out[0] = -a[0]; out[1] = -a[1]; out[2] = -a[2]; out[3] = -a[3]; return out; }; /** * Returns the inverse of the components of a vec4 * * @param {vec4} out the receiving vector * @param {vec4} a vector to invert * @returns {vec4} out */ vec4.inverse = function(out, a) { out[0] = 1.0 / a[0]; out[1] = 1.0 / a[1]; out[2] = 1.0 / a[2]; out[3] = 1.0 / a[3]; return out; }; /** * Normalize a vec4 * * @param {vec4} out the receiving vector * @param {vec4} a vector to normalize * @returns {vec4} out */ vec4.normalize = function(out, a) { var x = a[0], y = a[1], z = a[2], w = a[3]; var len = x*x + y*y + z*z + w*w; if (len > 0) { len = 1 / Math.sqrt(len); out[0] = a[0] * len; out[1] = a[1] * len; out[2] = a[2] * len; out[3] = a[3] * len; } return out; }; /** * Calculates the dot product of two vec4's * * @param {vec4} a the first operand * @param {vec4} b the second operand * @returns {Number} dot product of a and b */ vec4.dot = function (a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; }; /** * Performs a linear interpolation between two vec4's * * @param {vec4} out the receiving vector * @param {vec4} a the first operand * @param {vec4} b the second operand * @param {Number} t interpolation amount between the two inputs * @returns {vec4} out */ vec4.lerp = function (out, a, b, t) { var ax = a[0], ay = a[1], az = a[2], aw = a[3]; out[0] = ax + t * (b[0] - ax); out[1] = ay + t * (b[1] - ay); out[2] = az + t * (b[2] - az); out[3] = aw + t * (b[3] - aw); return out; }; /** * Generates a random vector with the given scale * * @param {vec4} out the receiving vector * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned * @returns {vec4} out */ vec4.random = function (out, scale) { scale = scale || 1.0; //TODO: This is a pretty awful way of doing this. Find something better. out[0] = GLMAT_RANDOM$1(); out[1] = GLMAT_RANDOM$1(); out[2] = GLMAT_RANDOM$1(); out[3] = GLMAT_RANDOM$1(); vec4.normalize(out, out); vec4.scale(out, out, scale); return out; }; /** * Transforms the vec4 with a mat4. * * @param {vec4} out the receiving vector * @param {vec4} a the vector to transform * @param {mat4} m matrix to transform with * @returns {vec4} out */ vec4.transformMat4 = function(out, a, m) { var x = a[0], y = a[1], z = a[2], w = a[3]; out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w; out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w; out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w; out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w; return out; }; /** * Transforms the vec4 with a quat * * @param {vec4} out the receiving vector * @param {vec4} a the vector to transform * @param {quat} q quaternion to transform with * @returns {vec4} out */ vec4.transformQuat = function(out, a, q) { var x = a[0], y = a[1], z = a[2], qx = q[0], qy = q[1], qz = q[2], qw = q[3], // calculate quat * vec ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; return out; }; /** * Perform some operation over an array of vec4s. * * @param {Array} a the array of vectors to iterate over * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed * @param {Number} offset Number of elements to skip at the beginning of the array * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array * @param {Function} fn Function to call for each vector in the array * @param {Object} [arg] additional argument to pass to fn * @returns {Array} a * @function */ vec4.forEach = (function() { var vec = vec4.create(); return function(a, stride, offset, count, fn, arg) { var i, l; if(!stride) { stride = 4; } if(!offset) { offset = 0; } if(count) { l = Math.min((count * stride) + offset, a.length); } else { l = a.length; } for(i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2]; vec[3] = a[i+3]; fn(vec, vec, arg); a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2]; a[i+3] = vec[3]; } return a; }; })(); /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 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. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ /** * @class 3x3 Matrix * @name mat3 */ var mat3 = {}; /** * Creates a new identity mat3 * * @returns {mat3} a new 3x3 matrix */ mat3.create = function() { var out = new GLMAT_ARRAY_TYPE(9); out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 1; out[5] = 0; out[6] = 0; out[7] = 0; out[8] = 1; return out; }; /** * Copies the upper-left 3x3 values into the given mat3. * * @param {mat3} out the receiving 3x3 matrix * @param {mat4} a the source 4x4 matrix * @returns {mat3} out */ mat3.fromMat4 = function(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[4]; out[4] = a[5]; out[5] = a[6]; out[6] = a[8]; out[7] = a[9]; out[8] = a[10]; return out; }; /** * Creates a new mat3 initialized with values from an existing matrix * * @param {mat3} a matrix to clone * @returns {mat3} a new 3x3 matrix */ mat3.clone = function(a) { var out = new GLMAT_ARRAY_TYPE(9); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; return out; }; /** * Copy the values from one mat3 to another * * @param {mat3} out the receiving matrix * @param {mat3} a the source matrix * @returns {mat3} out */ mat3.copy = function(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; return out; }; /** * Set a mat3 to the identity matrix * * @param {mat3} out the receiving matrix * @returns {mat3} out */ mat3.identity = function(out) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 1; out[5] = 0; out[6] = 0; out[7] = 0; out[8] = 1; return out; }; /** * Transpose the values of a mat3 * * @param {mat3} out the receiving matrix * @param {mat3} a the source matrix * @returns {mat3} out */ mat3.transpose = function(out, a) { // If we are transposing ourselves we can skip a few steps but have to cache some values if (out === a) { var a01 = a[1], a02 = a[2], a12 = a[5]; out[1] = a[3]; out[2] = a[6]; out[3] = a01; out[5] = a[7]; out[6] = a02; out[7] = a12; } else { out[0] = a[0]; out[1] = a[3]; out[2] = a[6]; out[3] = a[1]; out[4] = a[4]; out[5] = a[7]; out[6] = a[2]; out[7] = a[5]; out[8] = a[8]; } return out; }; /** * Inverts a mat3 * * @param {mat3} out the receiving matrix * @param {mat3} a the source matrix * @returns {mat3} out */ mat3.invert = function(out, a) { var a00 = a[0], a01 = a[1], a02 = a[2], a10 = a[3], a11 = a[4], a12 = a[5], a20 = a[6], a21 = a[7], a22 = a[8], b01 = a22 * a11 - a12 * a21, b11 = -a22 * a10 + a12 * a20, b21 = a21 * a10 - a11 * a20, // Calculate the determinant det = a00 * b01 + a01 * b11 + a02 * b21; if (!det) { return null; } det = 1.0 / det; out[0] = b01 * det; out[1] = (-a22 * a01 + a02 * a21) * det; out[2] = (a12 * a01 - a02 * a11) * det; out[3] = b11 * det; out[4] = (a22 * a00 - a02 * a20) * det; out[5] = (-a12 * a00 + a02 * a10) * det; out[6] = b21 * det; out[7] = (-a21 * a00 + a01 * a20) * det; out[8] = (a11 * a00 - a01 * a10) * det; return out; }; /** * Calculates the adjugate of a mat3 * * @param {mat3} out the receiving matrix * @param {mat3} a the source matrix * @returns {mat3} out */ mat3.adjoint = function(out, a) { var a00 = a[0], a01 = a[1], a02 = a[2], a10 = a[3], a11 = a[4], a12 = a[5], a20 = a[6], a21 = a[7], a22 = a[8]; out[0] = (a11 * a22 - a12 * a21); out[1] = (a02 * a21 - a01 * a22); out[2] = (a01 * a12 - a02 * a11); out[3] = (a12 * a20 - a10 * a22); out[4] = (a00 * a22 - a02 * a20); out[5] = (a02 * a10 - a00 * a12); out[6] = (a10 * a21 - a11 * a20); out[7] = (a01 * a20 - a00 * a21); out[8] = (a00 * a11 - a01 * a10); return out; }; /** * Calculates the determinant of a mat3 * * @param {mat3} a the source matrix * @returns {Number} determinant of a */ mat3.determinant = function (a) { var a00 = a[0], a01 = a[1], a02 = a[2], a10 = a[3], a11 = a[4], a12 = a[5], a20 = a[6], a21 = a[7], a22 = a[8]; return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20); }; /** * Multiplies two mat3's * * @param {mat3} out the receiving matrix * @param {mat3} a the first operand * @param {mat3} b the second operand * @returns {mat3} out */ mat3.multiply = function (out, a, b) { var a00 = a[0], a01 = a[1], a02 = a[2], a10 = a[3], a11 = a[4], a12 = a[5], a20 = a[6], a21 = a[7], a22 = a[8], b00 = b[0], b01 = b[1], b02 = b[2], b10 = b[3], b11 = b[4], b12 = b[5], b20 = b[6], b21 = b[7], b22 = b[8]; out[0] = b00 * a00 + b01 * a10 + b02 * a20; out[1] = b00 * a01 + b01 * a11 + b02 * a21; out[2] = b00 * a02 + b01 * a12 + b02 * a22; out[3] = b10 * a00 + b11 * a10 + b12 * a20; out[4] = b10 * a01 + b11 * a11 + b12 * a21; out[5] = b10 * a02 + b11 * a12 + b12 * a22; out[6] = b20 * a00 + b21 * a10 + b22 * a20; out[7] = b20 * a01 + b21 * a11 + b22 * a21; out[8] = b20 * a02 + b21 * a12 + b22 * a22; return out; }; /** * Alias for {@link mat3.multiply} * @function */ mat3.mul = mat3.multiply; /** * Translate a mat3 by the given vector * * @param {mat3} out the receiving matrix * @param {mat3} a the matrix to translate * @param {vec2} v vector to translate by * @returns {mat3} out */ mat3.translate = function(out, a, v) { var a00 = a[0], a01 = a[1], a02 = a[2], a10 = a[3], a11 = a[4], a12 = a[5], a20 = a[6], a21 = a[7], a22 = a[8], x = v[0], y = v[1]; out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a10; out[4] = a11; out[5] = a12; out[6] = x * a00 + y * a10 + a20; out[7] = x * a01 + y * a11 + a21; out[8] = x * a02 + y * a12 + a22; return out; }; /** * Rotates a mat3 by the given angle * * @param {mat3} out the receiving matrix * @param {mat3} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat3} out */ mat3.rotate = function (out, a, rad) { var a00 = a[0], a01 = a[1], a02 = a[2], a10 = a[3], a11 = a[4], a12 = a[5], a20 = a[6], a21 = a[7], a22 = a[8], s = Math.sin(rad), c = Math.cos(rad); out[0] = c * a00 + s * a10; out[1] = c * a01 + s * a11; out[2] = c * a02 + s * a12; out[3] = c * a10 - s * a00; out[4] = c * a11 - s * a01; out[5] = c * a12 - s * a02; out[6] = a20; out[7] = a21; out[8] = a22; return out; }; /** * Scales the mat3 by the dimensions in the given vec2 * * @param {mat3} out the receiving matrix * @param {mat3} a the matrix to rotate * @param {vec2} v the vec2 to scale the matrix by * @returns {mat3} out **/ mat3.scale = function(out, a, v) { var x = v[0], y = v[1]; out[0] = x * a[0]; out[1] = x * a[1]; out[2] = x * a[2]; out[3] = y * a[3]; out[4] = y * a[4]; out[5] = y * a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; return out; }; /** * Copies the values from a mat2d into a mat3 * * @param {mat3} out the receiving matrix * @param {mat2d} a the matrix to copy * @returns {mat3} out **/ mat3.fromMat2d = function(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = 0; out[3] = a[2]; out[4] = a[3]; out[5] = 0; out[6] = a[4]; out[7] = a[5]; out[8] = 1; return out; }; /** * Calculates a 3x3 matrix from the given quaternion * * @param {mat3} out mat3 receiving operation result * @param {quat} q Quaternion to create matrix from * * @returns {mat3} out */ mat3.fromQuat = function (out, q) { var x = q[0], y = q[1], z = q[2], w = q[3], x2 = x + x, y2 = y + y, z2 = z + z, xx = x * x2, yx = y * x2, yy = y * y2, zx = z * x2, zy = z * y2, zz = z * z2, wx = w * x2, wy = w * y2, wz = w * z2; out[0] = 1 - yy - zz; out[3] = yx - wz; out[6] = zx + wy; out[1] = yx + wz; out[4] = 1 - xx - zz; out[7] = zy - wx; out[2] = zx - wy; out[5] = zy + wx; out[8] = 1 - xx - yy; return out; }; /** * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix * * @param {mat3} out mat3 receiving operation result * @param {mat4} a Mat4 to derive the normal matrix from * * @returns {mat3} out */ mat3.normalFromMat4 = function (out, a) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15], b00 = a00 * a11 - a01 * a10, b01 = a00 * a12 - a02 * a10, b02 = a00 * a13 - a03 * a10, b03 = a01 * a12 - a02 * a11, b04 = a01 * a13 - a03 * a11, b05 = a02 * a13 - a03 * a12, b06 = a20 * a31 - a21 * a30, b07 = a20 * a32 - a22 * a30, b08 = a20 * a33 - a23 * a30, b09 = a21 * a32 - a22 * a31, b10 = a21 * a33 - a23 * a31, b11 = a22 * a33 - a23 * a32, // Calculate the determinant det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; if (!det) { return null; } det = 1.0 / det; out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det; out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det; out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det; out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det; out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det; out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det; out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det; out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det; return out; }; /** * Returns Frobenius norm of a mat3 * * @param {mat3} a the matrix to calculate Frobenius norm of * @returns {Number} Frobenius norm */ mat3.frob = function (a) { return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2))) }; /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 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. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ /** * @class Quaternion * @name quat */ var quat = {}; /** * Creates a new identity quat * * @returns {quat} a new quaternion */ quat.create = function() { var out = new GLMAT_ARRAY_TYPE(4); out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 1; return out; }; /** * Sets a quaternion to represent the shortest rotation from one * vector to another. * * Both vectors are assumed to be unit length. * * @param {quat} out the receiving quaternion. * @param {vec3} a the initial vector * @param {vec3} b the destination vector * @returns {quat} out */ quat.rotationTo = (function() { var tmpvec3 = vec3.create(); var xUnitVec3 = vec3.fromValues(1,0,0); var yUnitVec3 = vec3.fromValues(0,1,0); return function(out, a, b) { var dot = vec3.dot(a, b); if (dot < -0.999999) { vec3.cross(tmpvec3, xUnitVec3, a); if (vec3.length(tmpvec3) < 0.000001) vec3.cross(tmpvec3, yUnitVec3, a); vec3.normalize(tmpvec3, tmpvec3); quat.setAxisAngle(out, tmpvec3, Math.PI); return out; } else if (dot > 0.999999) { out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 1; return out; } else { vec3.cross(tmpvec3, a, b); out[0] = tmpvec3[0]; out[1] = tmpvec3[1]; out[2] = tmpvec3[2]; out[3] = 1 + dot; return quat.normalize(out, out); } }; })(); /** * Sets the specified quaternion with values corresponding to the given * axes. Each axis is a vec3 and is expected to be unit length and * perpendicular to all other specified axes. * * @param {vec3} view the vector representing the viewing direction * @param {vec3} right the vector representing the local "right" direction * @param {vec3} up the vector representing the local "up" direction * @returns {quat} out */ quat.setAxes = (function() { var matr = mat3.create(); return function(out, view, right, up) { matr[0] = right[0]; matr[3] = right[1]; matr[6] = right[2]; matr[1] = up[0]; matr[4] = up[1]; matr[7] = up[2]; matr[2] = -view[0]; matr[5] = -view[1]; matr[8] = -view[2]; return quat.normalize(out, quat.fromMat3(out, matr)); }; })(); /** * Creates a new quat initialized with values from an existing quaternion * * @param {quat} a quaternion to clone * @returns {quat} a new quaternion * @function */ quat.clone = vec4.clone; /** * Creates a new quat initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @param {Number} w W component * @returns {quat} a new quaternion * @function */ quat.fromValues = vec4.fromValues; /** * Copy the values from one quat to another * * @param {quat} out the receiving quaternion * @param {quat} a the source quaternion * @returns {quat} out * @function */ quat.copy = vec4.copy; /** * Set the components of a quat to the given values * * @param {quat} out the receiving quaternion * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @param {Number} w W component * @returns {quat} out * @function */ quat.set = vec4.set; /** * Set a quat to the identity quaternion * * @param {quat} out the receiving quaternion * @returns {quat} out */ quat.identity = function(out) { out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 1; return out; }; /** * Sets a quat from the given angle and rotation axis, * then returns it. * * @param {quat} out the receiving quaternion * @param {vec3} axis the axis around which to rotate * @param {Number} rad the angle in radians * @returns {quat} out **/ quat.setAxisAngle = function(out, axis, rad) { rad = rad * 0.5; var s = Math.sin(rad); out[0] = s * axis[0]; out[1] = s * axis[1]; out[2] = s * axis[2]; out[3] = Math.cos(rad); return out; }; /** * Adds two quat's * * @param {quat} out the receiving quaternion * @param {quat} a the first operand * @param {quat} b the second operand * @returns {quat} out * @function */ quat.add = vec4.add; /** * Multiplies two quat's * * @param {quat} out the receiving quaternion * @param {quat} a the first operand * @param {quat} b the second operand * @returns {quat} out */ quat.multiply = function(out, a, b) { var ax = a[0], ay = a[1], az = a[2], aw = a[3], bx = b[0], by = b[1], bz = b[2], bw = b[3]; out[0] = ax * bw + aw * bx + ay * bz - az * by; out[1] = ay * bw + aw * by + az * bx - ax * bz; out[2] = az * bw + aw * bz + ax * by - ay * bx; out[3] = aw * bw - ax * bx - ay * by - az * bz; return out; }; /** * Alias for {@link quat.multiply} * @function */ quat.mul = quat.multiply; /** * Scales a quat by a scalar number * * @param {quat} out the receiving vector * @param {quat} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {quat} out * @function */ quat.scale = vec4.scale; /** * Rotates a quaternion by the given angle about the X axis * * @param {quat} out quat receiving operation result * @param {quat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */ quat.rotateX = function (out, a, rad) { rad *= 0.5; var ax = a[0], ay = a[1], az = a[2], aw = a[3], bx = Math.sin(rad), bw = Math.cos(rad); out[0] = ax * bw + aw * bx; out[1] = ay * bw + az * bx; out[2] = az * bw - ay * bx; out[3] = aw * bw - ax * bx; return out; }; /** * Rotates a quaternion by the given angle about the Y axis * * @param {quat} out quat receiving operation result * @param {quat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */ quat.rotateY = function (out, a, rad) { rad *= 0.5; var ax = a[0], ay = a[1], az = a[2], aw = a[3], by = Math.sin(rad), bw = Math.cos(rad); out[0] = ax * bw - az * by; out[1] = ay * bw + aw * by; out[2] = az * bw + ax * by; out[3] = aw * bw - ay * by; return out; }; /** * Rotates a quaternion by the given angle about the Z axis * * @param {quat} out quat receiving operation result * @param {quat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */ quat.rotateZ = function (out, a, rad) { rad *= 0.5; var ax = a[0], ay = a[1], az = a[2], aw = a[3], bz = Math.sin(rad), bw = Math.cos(rad); out[0] = ax * bw + ay * bz; out[1] = ay * bw - ax * bz; out[2] = az * bw + aw * bz; out[3] = aw * bw - az * bz; return out; }; /** * Calculates the W component of a quat from the X, Y, and Z components. * Assumes that quaternion is 1 unit in length. * Any existing W component will be ignored. * * @param {quat} out the receiving quaternion * @param {quat} a quat to calculate W component of * @returns {quat} out */ quat.calculateW = function (out, a) { var x = a[0], y = a[1], z = a[2]; out[0] = x; out[1] = y; out[2] = z; out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z)); return out; }; /** * Calculates the dot product of two quat's * * @param {quat} a the first operand * @param {quat} b the second operand * @returns {Number} dot product of a and b * @function */ quat.dot = vec4.dot; /** * Performs a linear interpolation between two quat's * * @param {quat} out the receiving quaternion * @param {quat} a the first operand * @param {quat} b the second operand * @param {Number} t interpolation amount between the two inputs * @returns {quat} out * @function */ quat.lerp = vec4.lerp; /** * Performs a spherical linear interpolation between two quat * * @param {quat} out the receiving quaternion * @param {quat} a the first operand * @param {quat} b the second operand * @param {Number} t interpolation amount between the two inputs * @returns {quat} out */ quat.slerp = function (out, a, b, t) { // benchmarks: // http://jsperf.com/quaternion-slerp-implementations var ax = a[0], ay = a[1], az = a[2], aw = a[3], bx = b[0], by = b[1], bz = b[2], bw = b[3]; var omega, cosom, sinom, scale0, scale1; // calc cosine cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary) if ( cosom < 0.0 ) { cosom = -cosom; bx = - bx; by = - by; bz = - bz; bw = - bw; } // calculate coefficients if ( (1.0 - cosom) > 0.000001 ) { // standard case (slerp) omega = Math.acos(cosom); sinom = Math.sin(omega); scale0 = Math.sin((1.0 - t) * omega) / sinom; scale1 = Math.sin(t * omega) / sinom; } else { // "from" and "to" quaternions are very close // ... so we can do a linear interpolation scale0 = 1.0 - t; scale1 = t; } // calculate final values out[0] = scale0 * ax + scale1 * bx; out[1] = scale0 * ay + scale1 * by; out[2] = scale0 * az + scale1 * bz; out[3] = scale0 * aw + scale1 * bw; return out; }; /** * Calculates the inverse of a quat * * @param {quat} out the receiving quaternion * @param {quat} a quat to calculate inverse of * @returns {quat} out */ quat.invert = function(out, a) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], dot = a0*a0 + a1*a1 + a2*a2 + a3*a3, invDot = dot ? 1.0/dot : 0; // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0 out[0] = -a0*invDot; out[1] = -a1*invDot; out[2] = -a2*invDot; out[3] = a3*invDot; return out; }; /** * Calculates the conjugate of a quat * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result. * * @param {quat} out the receiving quaternion * @param {quat} a quat to calculate conjugate of * @returns {quat} out */ quat.conjugate = function (out, a) { out[0] = -a[0]; out[1] = -a[1]; out[2] = -a[2]; out[3] = a[3]; return out; }; /** * Calculates the length of a quat * * @param {quat} a vector to calculate length of * @returns {Number} length of a * @function */ quat.length = vec4.length; /** * Alias for {@link quat.length} * @function */ quat.len = quat.length; /** * Calculates the squared length of a quat * * @param {quat} a vector to calculate squared length of * @returns {Number} squared length of a * @function */ quat.squaredLength = vec4.squaredLength; /** * Alias for {@link quat.squaredLength} * @function */ quat.sqrLen = quat.squaredLength; /** * Normalize a quat * * @param {quat} out the receiving quaternion * @param {quat} a quaternion to normalize * @returns {quat} out * @function */ quat.normalize = vec4.normalize; /** * Creates a quaternion from the given 3x3 rotation matrix. * * NOTE: The resultant quaternion is not normalized, so you should be sure * to renormalize the quaternion yourself where necessary. * * @param {quat} out the receiving quaternion * @param {mat3} m rotation matrix * @returns {quat} out * @function */ quat.fromMat3 = function(out, m) { // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes // article "Quaternion Calculus and Fast Animation". var fTrace = m[0] + m[4] + m[8]; var fRoot; if ( fTrace > 0.0 ) { // |w| > 1/2, may as well choose w > 1/2 fRoot = Math.sqrt(fTrace + 1.0); // 2w out[3] = 0.5 * fRoot; fRoot = 0.5/fRoot; // 1/(4w) out[0] = (m[5]-m[7])*fRoot; out[1] = (m[6]-m[2])*fRoot; out[2] = (m[1]-m[3])*fRoot; } else { // |w| <= 1/2 var i = 0; if ( m[4] > m[0] ) i = 1; if ( m[8] > m[i*3+i] ) i = 2; var j = (i+1)%3; var k = (i+2)%3; fRoot = Math.sqrt(m[i*3+i]-m[j*3+j]-m[k*3+k] + 1.0); out[i] = 0.5 * fRoot; fRoot = 0.5 / fRoot; out[3] = (m[j*3+k] - m[k*3+j]) * fRoot; out[j] = (m[j*3+i] + m[i*3+j]) * fRoot; out[k] = (m[k*3+i] + m[i*3+k]) * fRoot; } return out; }; // Sampler clip is especially for the animation sampler in glTF // Use Typed Array can reduce a lot of heap memory // lerp function with offset in large array function vec3lerp(out, a, b, t, oa, ob) { var ax = a[oa]; var ay = a[oa + 1]; var az = a[oa + 2]; out[0] = ax + t * (b[ob] - ax); out[1] = ay + t * (b[ob + 1] - ay); out[2] = az + t * (b[ob + 2] - az); return out; } function quatSlerp(out, a, b, t, oa, ob) { // benchmarks: // http://jsperf.com/quaternion-slerp-implementations var ax = a[0 + oa], ay = a[1 + oa], az = a[2 + oa], aw = a[3 + oa], bx = b[0 + ob], by = b[1 + ob], bz = b[2 + ob], bw = b[3 + ob]; var omega, cosom, sinom, scale0, scale1; // calc cosine cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary) if (cosom < 0.0) { cosom = -cosom; bx = - bx; by = - by; bz = - bz; bw = - bw; } // calculate coefficients if ((1.0 - cosom) > 0.000001) { // standard case (slerp) omega = Math.acos(cosom); sinom = Math.sin(omega); scale0 = Math.sin((1.0 - t) * omega) / sinom; scale1 = Math.sin(t * omega) / sinom; } else { // 'from' and 'to' quaternions are very close // ... so we can do a linear interpolation scale0 = 1.0 - t; scale1 = t; } // calculate final values out[0] = scale0 * ax + scale1 * bx; out[1] = scale0 * ay + scale1 * by; out[2] = scale0 * az + scale1 * bz; out[3] = scale0 * aw + scale1 * bw; return out; } /** * SamplerTrack manages `position`, `rotation`, `scale` tracks in animation of single scene node. * @constructor * @alias clay.animation.SamplerTrack * @param {Object} [opts] * @param {string} [opts.name] Track name * @param {clay.Node} [opts.target] Target node's transform will updated automatically */ var SamplerTrack = function (opts) { opts = opts || {}; this.name = opts.name || ''; /** * @param {clay.Node} */ this.target = opts.target || null; /** * @type {Array} */ this.position = vec3.create(); /** * Rotation is represented by a quaternion * @type {Array} */ this.rotation = quat.create(); /** * @type {Array} */ this.scale = vec3.fromValues(1, 1, 1); this.channels = { time: null, position: null, rotation: null, scale: null }; this._cacheKey = 0; this._cacheTime = 0; }; SamplerTrack.prototype.setTime = function (time) { if (!this.channels.time) { return; } var channels = this.channels; var len = channels.time.length; var key = -1; // Only one frame if (len === 1) { if (channels.rotation) { quat.copy(this.rotation, channels.rotation); } if (channels.position) { vec3.copy(this.position, channels.position); } if (channels.scale) { vec3.copy(this.scale, channels.scale); } return; } // Clamp else if (time <= channels.time[0]) { time = channels.time[0]; key = 0; } else if (time >= channels.time[len - 1]) { time = channels.time[len - 1]; key = len - 2; } else { if (time < this._cacheTime) { var s = Math.min(len - 1, this._cacheKey + 1); for (var i = s; i >= 0; i--) { if (channels.time[i - 1] <= time && channels.time[i] > time) { key = i - 1; break; } } } else { for (var i = this._cacheKey; i < len - 1; i++) { if (channels.time[i] <= time && channels.time[i + 1] > time) { key = i; break; } } } } if (key > -1) { this._cacheKey = key; this._cacheTime = time; var start = key; var end = key + 1; var startTime = channels.time[start]; var endTime = channels.time[end]; var range = endTime - startTime; var percent = range === 0 ? 0 : (time - startTime) / range; if (channels.rotation) { quatSlerp(this.rotation, channels.rotation, channels.rotation, percent, start * 4, end * 4); } if (channels.position) { vec3lerp(this.position, channels.position, channels.position, percent, start * 3, end * 3); } if (channels.scale) { vec3lerp(this.scale, channels.scale, channels.scale, percent, start * 3, end * 3); } } // Loop handling if (key === len - 2) { this._cacheKey = 0; this._cacheTime = 0; } this.updateTarget(); }; /** * Update transform of target node manually */ SamplerTrack.prototype.updateTarget = function () { var channels = this.channels; if (this.target) { // Only update target prop if have data. if (channels.position) { this.target.position.setArray(this.position); } if (channels.rotation) { this.target.rotation.setArray(this.rotation); } if (channels.scale) { this.target.scale.setArray(this.scale); } } }; /** * @return {number} */ SamplerTrack.prototype.getMaxTime = function () { return this.channels.time[this.channels.time.length - 1]; }; /** * @param {number} startTime * @param {number} endTime * @return {clay.animation.SamplerTrack} */ SamplerTrack.prototype.getSubTrack = function (startTime, endTime) { var subClip = new SamplerTrack({ name: this.name }); var minTime = this.channels.time[0]; startTime = Math.min(Math.max(startTime, minTime), this.life); endTime = Math.min(Math.max(endTime, minTime), this.life); var rangeStart = this._findRange(startTime); var rangeEnd = this._findRange(endTime); var count = rangeEnd[0] - rangeStart[0] + 1; if (rangeStart[1] === 0 && rangeEnd[1] === 0) { count -= 1; } if (this.channels.rotation) { subClip.channels.rotation = new Float32Array(count * 4); } if (this.channels.position) { subClip.channels.position = new Float32Array(count * 3); } if (this.channels.scale) { subClip.channels.scale = new Float32Array(count * 3); } if (this.channels.time) { subClip.channels.time = new Float32Array(count); } // Clip at the start this.setTime(startTime); for (var i = 0; i < 3; i++) { subClip.channels.rotation[i] = this.rotation[i]; subClip.channels.position[i] = this.position[i]; subClip.channels.scale[i] = this.scale[i]; } subClip.channels.time[0] = 0; subClip.channels.rotation[3] = this.rotation[3]; for (var i = 1; i < count-1; i++) { var i2; for (var j = 0; j < 3; j++) { i2 = rangeStart[0] + i; subClip.channels.rotation[i * 4 + j] = this.channels.rotation[i2 * 4 + j]; subClip.channels.position[i * 3 + j] = this.channels.position[i2 * 3 + j]; subClip.channels.scale[i * 3 + j] = this.channels.scale[i2 * 3 + j]; } subClip.channels.time[i] = this.channels.time[i2] - startTime; subClip.channels.rotation[i * 4 + 3] = this.channels.rotation[i2 * 4 + 3]; } // Clip at the end this.setTime(endTime); for (var i = 0; i < 3; i++) { subClip.channels.rotation[(count - 1) * 4 + i] = this.rotation[i]; subClip.channels.position[(count - 1) * 3 + i] = this.position[i]; subClip.channels.scale[(count - 1) * 3 + i] = this.scale[i]; } subClip.channels.time[(count - 1)] = endTime - startTime; subClip.channels.rotation[(count - 1) * 4 + 3] = this.rotation[3]; // TODO set back ? subClip.life = endTime - startTime; return subClip; }; SamplerTrack.prototype._findRange = function (time) { var channels = this.channels; var len = channels.time.length; var start = -1; for (var i = 0; i < len - 1; i++) { if (channels.time[i] <= time && channels.time[i+1] > time) { start = i; } } var percent = 0; if (start >= 0) { var startTime = channels.time[start]; var endTime = channels.time[start+1]; var percent = (time-startTime) / (endTime-startTime); } // Percent [0, 1) return [start, percent]; }; /** * 1D blending between two clips * @function * @param {clay.animation.SamplerTrack|clay.animation.TransformTrack} c1 * @param {clay.animation.SamplerTrack|clay.animation.TransformTrack} c2 * @param {number} w */ SamplerTrack.prototype.blend1D = function (t1, t2, w) { vec3.lerp(this.position, t1.position, t2.position, w); vec3.lerp(this.scale, t1.scale, t2.scale, w); quat.slerp(this.rotation, t1.rotation, t2.rotation, w); }; /** * 2D blending between three clips * @function * @param {clay.animation.SamplerTrack|clay.animation.TransformTrack} c1 * @param {clay.animation.SamplerTrack|clay.animation.TransformTrack} c2 * @param {clay.animation.SamplerTrack|clay.animation.TransformTrack} c3 * @param {number} f * @param {number} g */ SamplerTrack.prototype.blend2D = (function () { var q1 = quat.create(); var q2 = quat.create(); return function (t1, t2, t3, f, g) { var a = 1 - f - g; this.position[0] = t1.position[0] * a + t2.position[0] * f + t3.position[0] * g; this.position[1] = t1.position[1] * a + t2.position[1] * f + t3.position[1] * g; this.position[2] = t1.position[2] * a + t2.position[2] * f + t3.position[2] * g; this.scale[0] = t1.scale[0] * a + t2.scale[0] * f + t3.scale[0] * g; this.scale[1] = t1.scale[1] * a + t2.scale[1] * f + t3.scale[1] * g; this.scale[2] = t1.scale[2] * a + t2.scale[2] * f + t3.scale[2] * g; // http://msdn.microsoft.com/en-us/library/windows/desktop/bb205403(v=vs.85).aspx // http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.quaternion.xmquaternionbarycentric(v=vs.85).aspx var s = f + g; if (s === 0) { quat.copy(this.rotation, t1.rotation); } else { quat.slerp(q1, t1.rotation, t2.rotation, s); quat.slerp(q2, t1.rotation, t3.rotation, s); quat.slerp(this.rotation, q1, q2, g / s); } }; })(); /** * Additive blending between two clips * @function * @param {clay.animation.SamplerTrack|clay.animation.TransformTrack} c1 * @param {clay.animation.SamplerTrack|clay.animation.TransformTrack} c2 */ SamplerTrack.prototype.additiveBlend = function (t1, t2) { vec3.add(this.position, t1.position, t2.position); vec3.add(this.scale, t1.scale, t2.scale); quat.multiply(this.rotation, t2.rotation, t1.rotation); }; /** * Subtractive blending between two clips * @function * @param {clay.animation.SamplerTrack|clay.animation.TransformTrack} c1 * @param {clay.animation.SamplerTrack|clay.animation.TransformTrack} c2 */ SamplerTrack.prototype.subtractiveBlend = function (t1, t2) { vec3.sub(this.position, t1.position, t2.position); vec3.sub(this.scale, t1.scale, t2.scale); quat.invert(this.rotation, t2.rotation); quat.multiply(this.rotation, this.rotation, t1.rotation); }; /** * Clone a new SamplerTrack * @return {clay.animation.SamplerTrack} */ SamplerTrack.prototype.clone = function () { var track = SamplerTrack.prototype.clone.call(this); track.channels = { time: this.channels.time || null, position: this.channels.position || null, rotation: this.channels.rotation || null, scale: this.channels.scale || null }; vec3.copy(track.position, this.position); quat.copy(track.rotation, this.rotation); vec3.copy(track.scale, this.scale); track.target = this.target; track.updateTarget(); return track; }; /** * Extend a sub class from base class * @param {object|Function} makeDefaultOpt default option of this sub class, method of the sub can use this.xxx to access this option * @param {Function} [initialize] Initialize after the sub class is instantiated * @param {Object} [proto] Prototype methods/properties of the sub class * @memberOf clay.core.mixin.extend * @return {Function} */ function derive(makeDefaultOpt, initialize/*optional*/, proto/*optional*/) { if (typeof initialize == 'object') { proto = initialize; initialize = null; } var _super = this; var propList; if (!(makeDefaultOpt instanceof Function)) { // Optimize the property iterate if it have been fixed propList = []; for (var propName in makeDefaultOpt) { if (makeDefaultOpt.hasOwnProperty(propName)) { propList.push(propName); } } } var sub = function(options) { // call super constructor _super.apply(this, arguments); if (makeDefaultOpt instanceof Function) { // Invoke makeDefaultOpt each time if it is a function, So we can make sure each // property in the object will not be shared by mutiple instances extend(this, makeDefaultOpt.call(this, options)); } else { extendWithPropList(this, makeDefaultOpt, propList); } if (this.constructor === sub) { // Initialize function will be called in the order of inherit var initializers = sub.__initializers__; for (var i = 0; i < initializers.length; i++) { initializers[i].apply(this, arguments); } } }; // save super constructor sub.__super__ = _super; // Initialize function will be called after all the super constructor is called if (!_super.__initializers__) { sub.__initializers__ = []; } else { sub.__initializers__ = _super.__initializers__.slice(); } if (initialize) { sub.__initializers__.push(initialize); } var Ctor = function() {}; Ctor.prototype = _super.prototype; sub.prototype = new Ctor(); sub.prototype.constructor = sub; extend(sub.prototype, proto); // extend the derive method as a static method; sub.extend = _super.extend; // DEPCRATED sub.derive = _super.extend; return sub; } function extend(target, source) { if (!source) { return; } for (var name in source) { if (source.hasOwnProperty(name)) { target[name] = source[name]; } } } function extendWithPropList(target, source, propList) { for (var i = 0; i < propList.length; i++) { var propName = propList[i]; target[propName] = source[propName]; } } /** * @alias clay.core.mixin.extend * @mixin */ var extendMixin = { extend: derive, // DEPCRATED derive: derive }; function Handler(action, context) { this.action = action; this.context = context; } /** * @mixin * @alias clay.core.mixin.notifier */ var notifier = { /** * Trigger event * @param {string} name */ trigger: function(name) { if (!this.hasOwnProperty('__handlers__')) { return; } if (!this.__handlers__.hasOwnProperty(name)) { return; } var hdls = this.__handlers__[name]; var l = hdls.length, i = -1, args = arguments; // Optimize advise from backbone switch (args.length) { case 1: while (++i < l) { hdls[i].action.call(hdls[i].context); } return; case 2: while (++i < l) { hdls[i].action.call(hdls[i].context, args[1]); } return; case 3: while (++i < l) { hdls[i].action.call(hdls[i].context, args[1], args[2]); } return; case 4: while (++i < l) { hdls[i].action.call(hdls[i].context, args[1], args[2], args[3]); } return; case 5: while (++i < l) { hdls[i].action.call(hdls[i].context, args[1], args[2], args[3], args[4]); } return; default: while (++i < l) { hdls[i].action.apply(hdls[i].context, Array.prototype.slice.call(args, 1)); } return; } }, /** * Register event handler * @param {string} name * @param {Function} action * @param {Object} [context] * @chainable */ on: function(name, action, context) { if (!name || !action) { return; } var handlers = this.__handlers__ || (this.__handlers__={}); if (!handlers[name]) { handlers[name] = []; } else { if (this.has(name, action)) { return; } } var handler = new Handler(action, context || this); handlers[name].push(handler); return this; }, /** * Register event, event will only be triggered once and then removed * @param {string} name * @param {Function} action * @param {Object} [context] * @chainable */ once: function(name, action, context) { if (!name || !action) { return; } var self = this; function wrapper() { self.off(name, wrapper); action.apply(this, arguments); } return this.on(name, wrapper, context); }, /** * Alias of once('before' + name) * @param {string} name * @param {Function} action * @param {Object} [context] * @chainable */ before: function(name, action, context) { if (!name || !action) { return; } name = 'before' + name; return this.on(name, action, context); }, /** * Alias of once('after' + name) * @param {string} name * @param {Function} action * @param {Object} [context] * @chainable */ after: function(name, action, context) { if (!name || !action) { return; } name = 'after' + name; return this.on(name, action, context); }, /** * Alias of on('success') * @param {Function} action * @param {Object} [context] * @chainable */ success: function(action, context) { return this.once('success', action, context); }, /** * Alias of on('error') * @param {Function} action * @param {Object} [context] * @chainable */ error: function(action, context) { return this.once('error', action, context); }, /** * Remove event listener * @param {Function} action * @param {Object} [context] * @chainable */ off: function(name, action) { var handlers = this.__handlers__ || (this.__handlers__={}); if (!action) { handlers[name] = []; return; } if (handlers[name]) { var hdls = handlers[name]; var retains = []; for (var i = 0; i < hdls.length; i++) { if (action && hdls[i].action !== action) { retains.push(hdls[i]); } } handlers[name] = retains; } return this; }, /** * If registered the event handler * @param {string} name * @param {Function} action * @return {boolean} */ has: function(name, action) { var handlers = this.__handlers__; if (! handlers || ! handlers[name]) { return false; } var hdls = handlers[name]; for (var i = 0; i < hdls.length; i++) { if (hdls[i].action === action) { return true; } } } }; var guid = 0; var ArrayProto = Array.prototype; var nativeForEach = ArrayProto.forEach; /** * Util functions * @namespace clay.core.util */ var util$1 = { /** * Generate GUID * @return {number} * @memberOf clay.core.util */ genGUID: function () { return ++guid; }, /** * Relative path to absolute path * @param {string} path * @param {string} basePath * @return {string} * @memberOf clay.core.util */ relative2absolute: function (path, basePath) { if (!basePath || path.match(/^\//)) { return path; } var pathParts = path.split('/'); var basePathParts = basePath.split('/'); var item = pathParts[0]; while(item === '.' || item === '..') { if (item === '..') { basePathParts.pop(); } pathParts.shift(); item = pathParts[0]; } return basePathParts.join('/') + '/' + pathParts.join('/'); }, /** * Extend target with source * @param {Object} target * @param {Object} source * @return {Object} * @memberOf clay.core.util */ extend: function (target, source) { if (source) { for (var name in source) { if (source.hasOwnProperty(name)) { target[name] = source[name]; } } } return target; }, /** * Extend properties to target if not exist. * @param {Object} target * @param {Object} source * @return {Object} * @memberOf clay.core.util */ defaults: function (target, source) { if (source) { for (var propName in source) { if (target[propName] === undefined) { target[propName] = source[propName]; } } } return target; }, /** * Extend properties with a given property list to avoid for..in.. iteration. * @param {Object} target * @param {Object} source * @param {Array.} propList * @return {Object} * @memberOf clay.core.util */ extendWithPropList: function (target, source, propList) { if (source) { for (var i = 0; i < propList.length; i++) { var propName = propList[i]; target[propName] = source[propName]; } } return target; }, /** * Extend properties to target if not exist. With a given property list avoid for..in.. iteration. * @param {Object} target * @param {Object} source * @param {Array.} propList * @return {Object} * @memberOf clay.core.util */ defaultsWithPropList: function (target, source, propList) { if (source) { for (var i = 0; i < propList.length; i++) { var propName = propList[i]; if (target[propName] == null) { target[propName] = source[propName]; } } } return target; }, /** * @param {Object|Array} obj * @param {Function} iterator * @param {Object} [context] * @memberOf clay.core.util */ each: function (obj, iterator, context) { if (!(obj && iterator)) { return; } if (obj.forEach && obj.forEach === nativeForEach) { obj.forEach(iterator, context); } else if (obj.length === + obj.length) { for (var i = 0, len = obj.length; i < len; i++) { iterator.call(context, obj[i], i, obj); } } else { for (var key in obj) { if (obj.hasOwnProperty(key)) { iterator.call(context, obj[key], key, obj); } } } }, /** * Is object * @param {} obj * @return {boolean} * @memberOf clay.core.util */ isObject: function (obj) { return obj === Object(obj); }, /** * Is array ? * @param {} obj * @return {boolean} * @memberOf clay.core.util */ isArray: function (obj) { return Array.isArray(obj); }, /** * Is array like, which have a length property * @param {} obj * @return {boolean} * @memberOf clay.core.util */ isArrayLike: function (obj) { if (!obj) { return false; } else { return obj.length === + obj.length; } }, /** * @param {} obj * @return {} * @memberOf clay.core.util */ clone: function (obj) { if (!util$1.isObject(obj)) { return obj; } else if (util$1.isArray(obj)) { return obj.slice(); } else if (util$1.isArrayLike(obj)) { // is typed array var ret = new obj.constructor(obj.length); for (var i = 0; i < obj.length; i++) { ret[i] = obj[i]; } return ret; } else { return util$1.extend({}, obj); } } }; /** * Base class of all objects * @constructor * @alias clay.core.Base * @mixes clay.core.mixin.notifier */ var Base = function () { /** * @type {number} */ this.__uid__ = util$1.genGUID(); }; Base.__initializers__ = [ function (opts) { util$1.extend(this, opts); } ]; util$1.extend(Base, extendMixin); util$1.extend(Base.prototype, notifier); function get(options) { var xhr = new XMLHttpRequest(); xhr.open('get', options.url); // With response type set browser can get and put binary data // https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Sending_and_Receiving_Binary_Data // Default is text, and it can be set // arraybuffer, blob, document, json, text xhr.responseType = options.responseType || 'text'; if (options.onprogress) { //https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest xhr.onprogress = function(e) { if (e.lengthComputable) { var percent = e.loaded / e.total; options.onprogress(percent, e.loaded, e.total); } else { options.onprogress(null); } }; } xhr.onload = function(e) { if (xhr.status >= 400) { options.onerror && options.onerror(); } else { options.onload && options.onload(xhr.response); } }; if (options.onerror) { xhr.onerror = options.onerror; } xhr.send(null); } var request = { get: get }; var supportWebGL; var vendor = {}; /** * If support WebGL * @return {boolean} */ vendor.supportWebGL = function () { if (supportWebGL == null) { try { var canvas = document.createElement('canvas'); var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); if (!gl) { throw new Error(); } } catch (e) { supportWebGL = false; } } return supportWebGL; }; vendor.Int8Array = typeof Int8Array === 'undefined' ? Array : Int8Array; vendor.Uint8Array = typeof Uint8Array === 'undefined' ? Array : Uint8Array; vendor.Uint16Array = typeof Uint16Array === 'undefined' ? Array : Uint16Array; vendor.Uint32Array = typeof Uint32Array === 'undefined' ? Array : Uint32Array; vendor.Int16Array = typeof Int16Array === 'undefined' ? Array : Int16Array; vendor.Float32Array = typeof Float32Array === 'undefined' ? Array : Float32Array; vendor.Float64Array = typeof Float64Array === 'undefined' ? Array : Float64Array; var g = {}; if (typeof window !== 'undefined') { g = window; } else if (typeof global !== 'undefined') { g = global; } vendor.requestAnimationFrame = g.requestAnimationFrame || g.msRequestAnimationFrame || g.mozRequestAnimationFrame || g.webkitRequestAnimationFrame || function (func){ setTimeout(func, 16); }; vendor.createCanvas = function () { return document.createElement('canvas'); }; vendor.createImage = function () { return new g.Image(); }; vendor.request = { get: request.get }; vendor.addEventListener = function (dom, type, func, useCapture) { dom.addEventListener(type, func, useCapture); }; vendor.removeEventListener = function (dom, type, func) { dom.removeEventListener(type, func); }; /** * Animation is global timeline that schedule all clips. each frame animation will set the time of clips to current and update the states of clips * @constructor clay.Timeline * @extends clay.core.Base * * @example * var animation = new clay.Timeline(); * var node = new clay.Node(); * animation.animate(node.position) * .when(1000, { * x: 500, * y: 500 * }) * .when(2000, { * x: 100, * y: 100 * }) * .when(3000, { * z: 10 * }) * .start('spline'); */ var Timeline = Base.extend(function () { return /** @lends clay.Timeline# */{ /** * stage is an object with render method, each frame if there exists any animating clips, stage.render will be called * @type {Object} */ stage: null, _clips: [], _running: false, _time: 0, _paused: false, _pausedTime: 0 }; }, /** @lends clay.Timeline.prototype */ { /** * Add animator * @param {clay.animate.Animator} animator */ addAnimator: function (animator) { animator.animation = this; var clips = animator.getClips(); for (var i = 0; i < clips.length; i++) { this.addClip(clips[i]); } }, /** * @param {clay.animation.Clip} clip */ addClip: function (clip) { if (this._clips.indexOf(clip) < 0) { this._clips.push(clip); } }, /** * @param {clay.animation.Clip} clip */ removeClip: function (clip) { var idx = this._clips.indexOf(clip); if (idx >= 0) { this._clips.splice(idx, 1); } }, /** * Remove animator * @param {clay.animate.Animator} animator */ removeAnimator: function (animator) { var clips = animator.getClips(); for (var i = 0; i < clips.length; i++) { this.removeClip(clips[i]); } animator.animation = null; }, _update: function () { var time = Date.now() - this._pausedTime; var delta = time - this._time; var clips = this._clips; var len = clips.length; var deferredEvents = []; var deferredClips = []; for (var i = 0; i < len; i++) { var clip = clips[i]; var e = clip.step(time, delta, false); // Throw out the events need to be called after // stage.render, like finish if (e) { deferredEvents.push(e); deferredClips.push(clip); } } // Remove the finished clip for (var i = 0; i < len;) { if (clips[i]._needsRemove) { clips[i] = clips[len-1]; clips.pop(); len--; } else { i++; } } len = deferredEvents.length; for (var i = 0; i < len; i++) { deferredClips[i].fire(deferredEvents[i]); } this._time = time; this.trigger('frame', delta); if (this.stage && this.stage.render) { this.stage.render(); } }, /** * Start running animation */ start: function () { var self = this; this._running = true; this._time = Date.now(); this._pausedTime = 0; var requestAnimationFrame = vendor.requestAnimationFrame; function step() { if (self._running) { requestAnimationFrame(step); if (!self._paused) { self._update(); } } } requestAnimationFrame(step); }, /** * Stop running animation */ stop: function () { this._running = false; }, /** * Pause */ pause: function () { if (!this._paused) { this._pauseStart = Date.now(); this._paused = true; } }, /** * Resume */ resume: function () { if (this._paused) { this._pausedTime += Date.now() - this._pauseStart; this._paused = false; } }, /** * Remove all clips */ removeClipsAll: function () { this._clips = []; }, /** * Create an animator * @param {Object} target * @param {Object} [options] * @param {boolean} [options.loop] * @param {Function} [options.getter] * @param {Function} [options.setter] * @param {Function} [options.interpolater] * @return {clay.animation.Animator} */ animate: function (target, options) { options = options || {}; var animator = new Animator( target, options.loop, options.getter, options.setter, options.interpolater ); animator.animation = this; return animator; } }); // DEPRECATED /** * * Animation clip that manage a collection of {@link clay.animation.SamplerTrack} * @constructor * @alias clay.animation.TrackClip * * @extends clay.animation.Clip * @param {Object} [opts] * @param {string} [opts.name] * @param {Object} [opts.target] * @param {number} [opts.life] * @param {number} [opts.delay] * @param {number} [opts.gap] * @param {number} [opts.playbackRatio] * @param {boolean|number} [opts.loop] If loop is a number, it indicate the loop count of animation * @param {string|Function} [opts.easing] * @param {Function} [opts.onframe] * @param {Function} [opts.onfinish] * @param {Function} [opts.onrestart] * @param {Array.} [opts.tracks] */ var TrackClip = function (opts) { opts = opts || {}; Clip.call(this, opts); /** * * @type {clay.animation.SamplerTrack[]} */ this.tracks = opts.tracks || []; this.calcLifeFromTracks(); }; TrackClip.prototype = Object.create(Clip.prototype); TrackClip.prototype.constructor = TrackClip; TrackClip.prototype.step = function (time, dTime, silent) { var ret = Clip.prototype.step.call(this, time, dTime, true); if (ret !== 'finish') { var time = this.getElapsedTime(); // TODO life may be changed. if (this._range) { time = this._range[0] + time; } this.setTime(time); } // PENDING Schedule if (!silent && ret !== 'paused') { this.fire('frame'); } return ret; }; /** * @param {Array.} range */ TrackClip.prototype.setRange = function (range) { this.calcLifeFromTracks(); this._range = range; if (range) { range[1] = Math.min(range[1], this.life); range[0] = Math.min(range[0], this.life); this.life = (range[1] - range[0]); } }; TrackClip.prototype.setTime = function (time) { for (var i = 0; i < this.tracks.length; i++) { this.tracks[i].setTime(time); } }; TrackClip.prototype.calcLifeFromTracks = function () { this.life = 0; for (var i = 0; i < this.tracks.length; i++) { this.life = Math.max(this.life, this.tracks[i].getMaxTime()); } }; /** * @param {clay.animation.SamplerTrack} track */ TrackClip.prototype.addTrack = function (track) { this.tracks.push(track); this.calcLifeFromTracks(); }; /** * @param {clay.animation.SamplerTrack} track */ TrackClip.prototype.removeTarck = function (track) { var idx = this.tracks.indexOf(track); if (idx >= 0) { this.tracks.splice(idx, 1); } }; /** * @param {number} startTime * @param {number} endTime * @param {boolean} isLoop * @return {clay.animation.TrackClip} */ TrackClip.prototype.getSubClip = function (startTime, endTime, isLoop) { var subClip = new TrackClip({ name: this.name }); for (var i = 0; i < this.tracks.length; i++) { var subTrack = this.tracks[i].getSubTrack(startTime, endTime); subClip.addTrack(subTrack); } if (isLoop !== undefined) { subClip.setLoop(isLoop); } subClip.life = endTime - startTime; return subClip; }; /** * 1d blending from two skinning clips * @param {clay.animation.TrackClip} clip1 * @param {clay.animation.TrackClip} clip2 * @param {number} w */ TrackClip.prototype.blend1D = function (clip1, clip2, w) { for (var i = 0; i < this.tracks.length; i++) { var c1 = clip1.tracks[i]; var c2 = clip2.tracks[i]; var tClip = this.tracks[i]; tClip.blend1D(c1, c2, w); } }; /** * Additive blending from two skinning clips * @param {clay.animation.TrackClip} clip1 * @param {clay.animation.TrackClip} clip2 */ TrackClip.prototype.additiveBlend = function (clip1, clip2) { for (var i = 0; i < this.tracks.length; i++) { var c1 = clip1.tracks[i]; var c2 = clip2.tracks[i]; var tClip = this.tracks[i]; tClip.additiveBlend(c1, c2); } }; /** * Subtractive blending from two skinning clips * @param {clay.animation.TrackClip} clip1 * @param {clay.animation.TrackClip} clip2 */ TrackClip.prototype.subtractiveBlend = function (clip1, clip2) { for (var i = 0; i < this.tracks.length; i++) { var c1 = clip1.tracks[i]; var c2 = clip2.tracks[i]; var tClip = this.tracks[i]; tClip.subtractiveBlend(c1, c2); } }; /** * 2D blending from three skinning clips * @param {clay.animation.TrackClip} clip1 * @param {clay.animation.TrackClip} clip2 * @param {clay.animation.TrackClip} clip3 * @param {number} f * @param {number} g */ TrackClip.prototype.blend2D = function (clip1, clip2, clip3, f, g) { for (var i = 0; i < this.tracks.length; i++) { var c1 = clip1.tracks[i]; var c2 = clip2.tracks[i]; var c3 = clip3.tracks[i]; var tClip = this.tracks[i]; tClip.blend2D(c1, c2, c3, f, g); } }; /** * Copy SRT of all joints clips from another TrackClip * @param {clay.animation.TrackClip} clip */ TrackClip.prototype.copy = function (clip) { for (var i = 0; i < this.tracks.length; i++) { var sTrack = clip.tracks[i]; var tTrack = this.tracks[i]; vec3.copy(tTrack.position, sTrack.position); vec3.copy(tTrack.scale, sTrack.scale); quat.copy(tTrack.rotation, sTrack.rotation); } }; TrackClip.prototype.clone = function () { var clip = Clip.prototype.clone.call(this); for (var i = 0; i < this.tracks.length; i++) { clip.addTrack(this.tracks[i].clone()); } clip.life = this.life; return clip; }; var EXTENSION_LIST = [ 'OES_texture_float', 'OES_texture_half_float', 'OES_texture_float_linear', 'OES_texture_half_float_linear', 'OES_standard_derivatives', 'OES_vertex_array_object', 'OES_element_index_uint', 'WEBGL_compressed_texture_s3tc', 'WEBGL_depth_texture', 'EXT_texture_filter_anisotropic', 'EXT_shader_texture_lod', 'WEBGL_draw_buffers', 'EXT_frag_depth', 'EXT_sRGB' ]; var PARAMETER_NAMES = [ 'MAX_TEXTURE_SIZE', 'MAX_CUBE_MAP_TEXTURE_SIZE' ]; function GLInfo(_gl) { var extensions = {}; var parameters = {}; // Get webgl extension for (var i = 0; i < EXTENSION_LIST.length; i++) { var extName = EXTENSION_LIST[i]; createExtension(extName); } // Get parameters for (var i = 0; i < PARAMETER_NAMES.length; i++) { var name = PARAMETER_NAMES[i]; parameters[name] = _gl.getParameter(_gl[name]); } this.getExtension = function (name) { if (!(name in extensions)) { createExtension(name); } return extensions[name]; }; this.getParameter = function (name) { return parameters[name]; }; this.getMaxJointNumber = function () { return 15; }; function createExtension(name) { var ext = _gl.getExtension(name); if (!ext) { ext = _gl.getExtension('MOZ_' + name); } if (!ext) { ext = _gl.getExtension('WEBKIT_' + name); } extensions[name] = ext; } } /** * @namespace clay.core.glenum * @see http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14 */ var glenum = { /* ClearBufferMask */ DEPTH_BUFFER_BIT : 0x00000100, STENCIL_BUFFER_BIT : 0x00000400, COLOR_BUFFER_BIT : 0x00004000, /* BeginMode */ POINTS : 0x0000, LINES : 0x0001, LINE_LOOP : 0x0002, LINE_STRIP : 0x0003, TRIANGLES : 0x0004, TRIANGLE_STRIP : 0x0005, TRIANGLE_FAN : 0x0006, /* AlphaFunction (not supported in ES20) */ /* NEVER */ /* LESS */ /* EQUAL */ /* LEQUAL */ /* GREATER */ /* NOTEQUAL */ /* GEQUAL */ /* ALWAYS */ /* BlendingFactorDest */ ZERO : 0, ONE : 1, SRC_COLOR : 0x0300, ONE_MINUS_SRC_COLOR : 0x0301, SRC_ALPHA : 0x0302, ONE_MINUS_SRC_ALPHA : 0x0303, DST_ALPHA : 0x0304, ONE_MINUS_DST_ALPHA : 0x0305, /* BlendingFactorSrc */ /* ZERO */ /* ONE */ DST_COLOR : 0x0306, ONE_MINUS_DST_COLOR : 0x0307, SRC_ALPHA_SATURATE : 0x0308, /* SRC_ALPHA */ /* ONE_MINUS_SRC_ALPHA */ /* DST_ALPHA */ /* ONE_MINUS_DST_ALPHA */ /* BlendEquationSeparate */ FUNC_ADD : 0x8006, BLEND_EQUATION : 0x8009, BLEND_EQUATION_RGB : 0x8009, /* same as BLEND_EQUATION */ BLEND_EQUATION_ALPHA : 0x883D, /* BlendSubtract */ FUNC_SUBTRACT : 0x800A, FUNC_REVERSE_SUBTRACT : 0x800B, /* Separate Blend Functions */ BLEND_DST_RGB : 0x80C8, BLEND_SRC_RGB : 0x80C9, BLEND_DST_ALPHA : 0x80CA, BLEND_SRC_ALPHA : 0x80CB, CONSTANT_COLOR : 0x8001, ONE_MINUS_CONSTANT_COLOR : 0x8002, CONSTANT_ALPHA : 0x8003, ONE_MINUS_CONSTANT_ALPHA : 0x8004, BLEND_COLOR : 0x8005, /* Buffer Objects */ ARRAY_BUFFER : 0x8892, ELEMENT_ARRAY_BUFFER : 0x8893, ARRAY_BUFFER_BINDING : 0x8894, ELEMENT_ARRAY_BUFFER_BINDING : 0x8895, STREAM_DRAW : 0x88E0, STATIC_DRAW : 0x88E4, DYNAMIC_DRAW : 0x88E8, BUFFER_SIZE : 0x8764, BUFFER_USAGE : 0x8765, CURRENT_VERTEX_ATTRIB : 0x8626, /* CullFaceMode */ FRONT : 0x0404, BACK : 0x0405, FRONT_AND_BACK : 0x0408, /* DepthFunction */ /* NEVER */ /* LESS */ /* EQUAL */ /* LEQUAL */ /* GREATER */ /* NOTEQUAL */ /* GEQUAL */ /* ALWAYS */ /* EnableCap */ /* TEXTURE_2D */ CULL_FACE : 0x0B44, BLEND : 0x0BE2, DITHER : 0x0BD0, STENCIL_TEST : 0x0B90, DEPTH_TEST : 0x0B71, SCISSOR_TEST : 0x0C11, POLYGON_OFFSET_FILL : 0x8037, SAMPLE_ALPHA_TO_COVERAGE : 0x809E, SAMPLE_COVERAGE : 0x80A0, /* ErrorCode */ NO_ERROR : 0, INVALID_ENUM : 0x0500, INVALID_VALUE : 0x0501, INVALID_OPERATION : 0x0502, OUT_OF_MEMORY : 0x0505, /* FrontFaceDirection */ CW : 0x0900, CCW : 0x0901, /* GetPName */ LINE_WIDTH : 0x0B21, ALIASED_POINT_SIZE_RANGE : 0x846D, ALIASED_LINE_WIDTH_RANGE : 0x846E, CULL_FACE_MODE : 0x0B45, FRONT_FACE : 0x0B46, DEPTH_RANGE : 0x0B70, DEPTH_WRITEMASK : 0x0B72, DEPTH_CLEAR_VALUE : 0x0B73, DEPTH_FUNC : 0x0B74, STENCIL_CLEAR_VALUE : 0x0B91, STENCIL_FUNC : 0x0B92, STENCIL_FAIL : 0x0B94, STENCIL_PASS_DEPTH_FAIL : 0x0B95, STENCIL_PASS_DEPTH_PASS : 0x0B96, STENCIL_REF : 0x0B97, STENCIL_VALUE_MASK : 0x0B93, STENCIL_WRITEMASK : 0x0B98, STENCIL_BACK_FUNC : 0x8800, STENCIL_BACK_FAIL : 0x8801, STENCIL_BACK_PASS_DEPTH_FAIL : 0x8802, STENCIL_BACK_PASS_DEPTH_PASS : 0x8803, STENCIL_BACK_REF : 0x8CA3, STENCIL_BACK_VALUE_MASK : 0x8CA4, STENCIL_BACK_WRITEMASK : 0x8CA5, VIEWPORT : 0x0BA2, SCISSOR_BOX : 0x0C10, /* SCISSOR_TEST */ COLOR_CLEAR_VALUE : 0x0C22, COLOR_WRITEMASK : 0x0C23, UNPACK_ALIGNMENT : 0x0CF5, PACK_ALIGNMENT : 0x0D05, MAX_TEXTURE_SIZE : 0x0D33, MAX_VIEWPORT_DIMS : 0x0D3A, SUBPIXEL_BITS : 0x0D50, RED_BITS : 0x0D52, GREEN_BITS : 0x0D53, BLUE_BITS : 0x0D54, ALPHA_BITS : 0x0D55, DEPTH_BITS : 0x0D56, STENCIL_BITS : 0x0D57, POLYGON_OFFSET_UNITS : 0x2A00, /* POLYGON_OFFSET_FILL */ POLYGON_OFFSET_FACTOR : 0x8038, TEXTURE_BINDING_2D : 0x8069, SAMPLE_BUFFERS : 0x80A8, SAMPLES : 0x80A9, SAMPLE_COVERAGE_VALUE : 0x80AA, SAMPLE_COVERAGE_INVERT : 0x80AB, /* GetTextureParameter */ /* TEXTURE_MAG_FILTER */ /* TEXTURE_MIN_FILTER */ /* TEXTURE_WRAP_S */ /* TEXTURE_WRAP_T */ COMPRESSED_TEXTURE_FORMATS : 0x86A3, /* HintMode */ DONT_CARE : 0x1100, FASTEST : 0x1101, NICEST : 0x1102, /* HintTarget */ GENERATE_MIPMAP_HINT : 0x8192, /* DataType */ BYTE : 0x1400, UNSIGNED_BYTE : 0x1401, SHORT : 0x1402, UNSIGNED_SHORT : 0x1403, INT : 0x1404, UNSIGNED_INT : 0x1405, FLOAT : 0x1406, /* PixelFormat */ DEPTH_COMPONENT : 0x1902, ALPHA : 0x1906, RGB : 0x1907, RGBA : 0x1908, LUMINANCE : 0x1909, LUMINANCE_ALPHA : 0x190A, /* PixelType */ /* UNSIGNED_BYTE */ UNSIGNED_SHORT_4_4_4_4 : 0x8033, UNSIGNED_SHORT_5_5_5_1 : 0x8034, UNSIGNED_SHORT_5_6_5 : 0x8363, /* Shaders */ FRAGMENT_SHADER : 0x8B30, VERTEX_SHADER : 0x8B31, MAX_VERTEX_ATTRIBS : 0x8869, MAX_VERTEX_UNIFORM_VECTORS : 0x8DFB, MAX_VARYING_VECTORS : 0x8DFC, MAX_COMBINED_TEXTURE_IMAGE_UNITS : 0x8B4D, MAX_VERTEX_TEXTURE_IMAGE_UNITS : 0x8B4C, MAX_TEXTURE_IMAGE_UNITS : 0x8872, MAX_FRAGMENT_UNIFORM_VECTORS : 0x8DFD, SHADER_TYPE : 0x8B4F, DELETE_STATUS : 0x8B80, LINK_STATUS : 0x8B82, VALIDATE_STATUS : 0x8B83, ATTACHED_SHADERS : 0x8B85, ACTIVE_UNIFORMS : 0x8B86, ACTIVE_ATTRIBUTES : 0x8B89, SHADING_LANGUAGE_VERSION : 0x8B8C, CURRENT_PROGRAM : 0x8B8D, /* StencilFunction */ NEVER : 0x0200, LESS : 0x0201, EQUAL : 0x0202, LEQUAL : 0x0203, GREATER : 0x0204, NOTEQUAL : 0x0205, GEQUAL : 0x0206, ALWAYS : 0x0207, /* StencilOp */ /* ZERO */ KEEP : 0x1E00, REPLACE : 0x1E01, INCR : 0x1E02, DECR : 0x1E03, INVERT : 0x150A, INCR_WRAP : 0x8507, DECR_WRAP : 0x8508, /* StringName */ VENDOR : 0x1F00, RENDERER : 0x1F01, VERSION : 0x1F02, /* TextureMagFilter */ NEAREST : 0x2600, LINEAR : 0x2601, /* TextureMinFilter */ /* NEAREST */ /* LINEAR */ NEAREST_MIPMAP_NEAREST : 0x2700, LINEAR_MIPMAP_NEAREST : 0x2701, NEAREST_MIPMAP_LINEAR : 0x2702, LINEAR_MIPMAP_LINEAR : 0x2703, /* TextureParameterName */ TEXTURE_MAG_FILTER : 0x2800, TEXTURE_MIN_FILTER : 0x2801, TEXTURE_WRAP_S : 0x2802, TEXTURE_WRAP_T : 0x2803, /* TextureTarget */ TEXTURE_2D : 0x0DE1, TEXTURE : 0x1702, TEXTURE_CUBE_MAP : 0x8513, TEXTURE_BINDING_CUBE_MAP : 0x8514, TEXTURE_CUBE_MAP_POSITIVE_X : 0x8515, TEXTURE_CUBE_MAP_NEGATIVE_X : 0x8516, TEXTURE_CUBE_MAP_POSITIVE_Y : 0x8517, TEXTURE_CUBE_MAP_NEGATIVE_Y : 0x8518, TEXTURE_CUBE_MAP_POSITIVE_Z : 0x8519, TEXTURE_CUBE_MAP_NEGATIVE_Z : 0x851A, MAX_CUBE_MAP_TEXTURE_SIZE : 0x851C, /* TextureUnit */ TEXTURE0 : 0x84C0, TEXTURE1 : 0x84C1, TEXTURE2 : 0x84C2, TEXTURE3 : 0x84C3, TEXTURE4 : 0x84C4, TEXTURE5 : 0x84C5, TEXTURE6 : 0x84C6, TEXTURE7 : 0x84C7, TEXTURE8 : 0x84C8, TEXTURE9 : 0x84C9, TEXTURE10 : 0x84CA, TEXTURE11 : 0x84CB, TEXTURE12 : 0x84CC, TEXTURE13 : 0x84CD, TEXTURE14 : 0x84CE, TEXTURE15 : 0x84CF, TEXTURE16 : 0x84D0, TEXTURE17 : 0x84D1, TEXTURE18 : 0x84D2, TEXTURE19 : 0x84D3, TEXTURE20 : 0x84D4, TEXTURE21 : 0x84D5, TEXTURE22 : 0x84D6, TEXTURE23 : 0x84D7, TEXTURE24 : 0x84D8, TEXTURE25 : 0x84D9, TEXTURE26 : 0x84DA, TEXTURE27 : 0x84DB, TEXTURE28 : 0x84DC, TEXTURE29 : 0x84DD, TEXTURE30 : 0x84DE, TEXTURE31 : 0x84DF, ACTIVE_TEXTURE : 0x84E0, /* TextureWrapMode */ REPEAT : 0x2901, CLAMP_TO_EDGE : 0x812F, MIRRORED_REPEAT : 0x8370, /* Uniform Types */ FLOAT_VEC2 : 0x8B50, FLOAT_VEC3 : 0x8B51, FLOAT_VEC4 : 0x8B52, INT_VEC2 : 0x8B53, INT_VEC3 : 0x8B54, INT_VEC4 : 0x8B55, BOOL : 0x8B56, BOOL_VEC2 : 0x8B57, BOOL_VEC3 : 0x8B58, BOOL_VEC4 : 0x8B59, FLOAT_MAT2 : 0x8B5A, FLOAT_MAT3 : 0x8B5B, FLOAT_MAT4 : 0x8B5C, SAMPLER_2D : 0x8B5E, SAMPLER_CUBE : 0x8B60, /* Vertex Arrays */ VERTEX_ATTRIB_ARRAY_ENABLED : 0x8622, VERTEX_ATTRIB_ARRAY_SIZE : 0x8623, VERTEX_ATTRIB_ARRAY_STRIDE : 0x8624, VERTEX_ATTRIB_ARRAY_TYPE : 0x8625, VERTEX_ATTRIB_ARRAY_NORMALIZED : 0x886A, VERTEX_ATTRIB_ARRAY_POINTER : 0x8645, VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F, /* Shader Source */ COMPILE_STATUS : 0x8B81, /* Shader Precision-Specified Types */ LOW_FLOAT : 0x8DF0, MEDIUM_FLOAT : 0x8DF1, HIGH_FLOAT : 0x8DF2, LOW_INT : 0x8DF3, MEDIUM_INT : 0x8DF4, HIGH_INT : 0x8DF5, /* Framebuffer Object. */ FRAMEBUFFER : 0x8D40, RENDERBUFFER : 0x8D41, RGBA4 : 0x8056, RGB5_A1 : 0x8057, RGB565 : 0x8D62, DEPTH_COMPONENT16 : 0x81A5, STENCIL_INDEX : 0x1901, STENCIL_INDEX8 : 0x8D48, DEPTH_STENCIL : 0x84F9, RENDERBUFFER_WIDTH : 0x8D42, RENDERBUFFER_HEIGHT : 0x8D43, RENDERBUFFER_INTERNAL_FORMAT : 0x8D44, RENDERBUFFER_RED_SIZE : 0x8D50, RENDERBUFFER_GREEN_SIZE : 0x8D51, RENDERBUFFER_BLUE_SIZE : 0x8D52, RENDERBUFFER_ALPHA_SIZE : 0x8D53, RENDERBUFFER_DEPTH_SIZE : 0x8D54, RENDERBUFFER_STENCIL_SIZE : 0x8D55, FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE : 0x8CD0, FRAMEBUFFER_ATTACHMENT_OBJECT_NAME : 0x8CD1, FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL : 0x8CD2, FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE : 0x8CD3, COLOR_ATTACHMENT0 : 0x8CE0, DEPTH_ATTACHMENT : 0x8D00, STENCIL_ATTACHMENT : 0x8D20, DEPTH_STENCIL_ATTACHMENT : 0x821A, NONE : 0, FRAMEBUFFER_COMPLETE : 0x8CD5, FRAMEBUFFER_INCOMPLETE_ATTACHMENT : 0x8CD6, FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : 0x8CD7, FRAMEBUFFER_INCOMPLETE_DIMENSIONS : 0x8CD9, FRAMEBUFFER_UNSUPPORTED : 0x8CDD, FRAMEBUFFER_BINDING : 0x8CA6, RENDERBUFFER_BINDING : 0x8CA7, MAX_RENDERBUFFER_SIZE : 0x84E8, INVALID_FRAMEBUFFER_OPERATION : 0x0506, /* WebGL-specific enums */ UNPACK_FLIP_Y_WEBGL : 0x9240, UNPACK_PREMULTIPLY_ALPHA_WEBGL : 0x9241, CONTEXT_LOST_WEBGL : 0x9242, UNPACK_COLORSPACE_CONVERSION_WEBGL : 0x9243, BROWSER_DEFAULT_WEBGL : 0x9244, }; /** * Simple double linked list. Compared with array, it has O(1) remove operation. * @constructor * @alias clay.core.LinkedList */ var LinkedList = function () { /** * @type {clay.core.LinkedList.Entry} */ this.head = null; /** * @type {clay.core.LinkedList.Entry} */ this.tail = null; this._length = 0; }; /** * Insert a new value at the tail * @param {} val * @return {clay.core.LinkedList.Entry} */ LinkedList.prototype.insert = function (val) { var entry = new LinkedList.Entry(val); this.insertEntry(entry); return entry; }; /** * Insert a new value at idx * @param {number} idx * @param {} val * @return {clay.core.LinkedList.Entry} */ LinkedList.prototype.insertAt = function (idx, val) { if (idx < 0) { return; } var next = this.head; var cursor = 0; while (next && cursor != idx) { next = next.next; cursor++; } if (next) { var entry = new LinkedList.Entry(val); var prev = next.prev; if (!prev) { //next is head this.head = entry; } else { prev.next = entry; entry.prev = prev; } entry.next = next; next.prev = entry; } else { this.insert(val); } }; LinkedList.prototype.insertBeforeEntry = function (val, next) { var entry = new LinkedList.Entry(val); var prev = next.prev; if (!prev) { //next is head this.head = entry; } else { prev.next = entry; entry.prev = prev; } entry.next = next; next.prev = entry; this._length++; }; /** * Insert an entry at the tail * @param {clay.core.LinkedList.Entry} entry */ LinkedList.prototype.insertEntry = function (entry) { if (!this.head) { this.head = this.tail = entry; } else { this.tail.next = entry; entry.prev = this.tail; this.tail = entry; } this._length++; }; /** * Remove entry. * @param {clay.core.LinkedList.Entry} entry */ LinkedList.prototype.remove = function (entry) { var prev = entry.prev; var next = entry.next; if (prev) { prev.next = next; } else { // Is head this.head = next; } if (next) { next.prev = prev; } else { // Is tail this.tail = prev; } entry.next = entry.prev = null; this._length--; }; /** * Remove entry at index. * @param {number} idx * @return {} */ LinkedList.prototype.removeAt = function (idx) { if (idx < 0) { return; } var curr = this.head; var cursor = 0; while (curr && cursor != idx) { curr = curr.next; cursor++; } if (curr) { this.remove(curr); return curr.value; } }; /** * Get head value * @return {} */ LinkedList.prototype.getHead = function () { if (this.head) { return this.head.value; } }; /** * Get tail value * @return {} */ LinkedList.prototype.getTail = function () { if (this.tail) { return this.tail.value; } }; /** * Get value at idx * @param {number} idx * @return {} */ LinkedList.prototype.getAt = function (idx) { if (idx < 0) { return; } var curr = this.head; var cursor = 0; while (curr && cursor != idx) { curr = curr.next; cursor++; } return curr.value; }; /** * @param {} value * @return {number} */ LinkedList.prototype.indexOf = function (value) { var curr = this.head; var cursor = 0; while (curr) { if (curr.value === value) { return cursor; } curr = curr.next; cursor++; } }; /** * @return {number} */ LinkedList.prototype.length = function () { return this._length; }; /** * If list is empty */ LinkedList.prototype.isEmpty = function () { return this._length === 0; }; /** * @param {Function} cb * @param {} context */ LinkedList.prototype.forEach = function (cb, context) { var curr = this.head; var idx = 0; var haveContext = typeof(context) != 'undefined'; while (curr) { if (haveContext) { cb.call(context, curr.value, idx); } else { cb(curr.value, idx); } curr = curr.next; idx++; } }; /** * Clear the list */ LinkedList.prototype.clear = function () { this.tail = this.head = null; this._length = 0; }; /** * @constructor * @param {} val */ LinkedList.Entry = function (val) { /** * @type {} */ this.value = val; /** * @type {clay.core.LinkedList.Entry} */ this.next = null; /** * @type {clay.core.LinkedList.Entry} */ this.prev = null; }; /** * LRU Cache * @constructor * @alias clay.core.LRU */ var LRU$1 = function (maxSize) { this._list = new LinkedList(); this._map = {}; this._maxSize = maxSize || 10; }; /** * Set cache max size * @param {number} size */ LRU$1.prototype.setMaxSize = function (size) { this._maxSize = size; }; /** * @param {string} key * @param {} value */ LRU$1.prototype.put = function (key, value) { if (!this._map.hasOwnProperty(key)) { var len = this._list.length(); if (len >= this._maxSize && len > 0) { // Remove the least recently used var leastUsedEntry = this._list.head; this._list.remove(leastUsedEntry); delete this._map[leastUsedEntry.key]; } var entry = this._list.insert(value); entry.key = key; this._map[key] = entry; } }; /** * @param {string} key * @return {} */ LRU$1.prototype.get = function (key) { var entry = this._map[key]; if (this._map.hasOwnProperty(key)) { // Put the latest used entry in the tail if (entry !== this._list.tail) { this._list.remove(entry); this._list.insertEntry(entry); } return entry.value; } }; /** * @param {string} key */ LRU$1.prototype.remove = function (key) { var entry = this._map[key]; if (typeof(entry) !== 'undefined') { delete this._map[key]; this._list.remove(entry); } }; /** * Clear the cache */ LRU$1.prototype.clear = function () { this._list.clear(); this._map = {}; }; /** * @namespace clay.core.color */ var colorUtil = {}; var kCSSColorTable = { 'transparent': [0,0,0,0], 'aliceblue': [240,248,255,1], 'antiquewhite': [250,235,215,1], 'aqua': [0,255,255,1], 'aquamarine': [127,255,212,1], 'azure': [240,255,255,1], 'beige': [245,245,220,1], 'bisque': [255,228,196,1], 'black': [0,0,0,1], 'blanchedalmond': [255,235,205,1], 'blue': [0,0,255,1], 'blueviolet': [138,43,226,1], 'brown': [165,42,42,1], 'burlywood': [222,184,135,1], 'cadetblue': [95,158,160,1], 'chartreuse': [127,255,0,1], 'chocolate': [210,105,30,1], 'coral': [255,127,80,1], 'cornflowerblue': [100,149,237,1], 'cornsilk': [255,248,220,1], 'crimson': [220,20,60,1], 'cyan': [0,255,255,1], 'darkblue': [0,0,139,1], 'darkcyan': [0,139,139,1], 'darkgoldenrod': [184,134,11,1], 'darkgray': [169,169,169,1], 'darkgreen': [0,100,0,1], 'darkgrey': [169,169,169,1], 'darkkhaki': [189,183,107,1], 'darkmagenta': [139,0,139,1], 'darkolivegreen': [85,107,47,1], 'darkorange': [255,140,0,1], 'darkorchid': [153,50,204,1], 'darkred': [139,0,0,1], 'darksalmon': [233,150,122,1], 'darkseagreen': [143,188,143,1], 'darkslateblue': [72,61,139,1], 'darkslategray': [47,79,79,1], 'darkslategrey': [47,79,79,1], 'darkturquoise': [0,206,209,1], 'darkviolet': [148,0,211,1], 'deeppink': [255,20,147,1], 'deepskyblue': [0,191,255,1], 'dimgray': [105,105,105,1], 'dimgrey': [105,105,105,1], 'dodgerblue': [30,144,255,1], 'firebrick': [178,34,34,1], 'floralwhite': [255,250,240,1], 'forestgreen': [34,139,34,1], 'fuchsia': [255,0,255,1], 'gainsboro': [220,220,220,1], 'ghostwhite': [248,248,255,1], 'gold': [255,215,0,1], 'goldenrod': [218,165,32,1], 'gray': [128,128,128,1], 'green': [0,128,0,1], 'greenyellow': [173,255,47,1], 'grey': [128,128,128,1], 'honeydew': [240,255,240,1], 'hotpink': [255,105,180,1], 'indianred': [205,92,92,1], 'indigo': [75,0,130,1], 'ivory': [255,255,240,1], 'khaki': [240,230,140,1], 'lavender': [230,230,250,1], 'lavenderblush': [255,240,245,1], 'lawngreen': [124,252,0,1], 'lemonchiffon': [255,250,205,1], 'lightblue': [173,216,230,1], 'lightcoral': [240,128,128,1], 'lightcyan': [224,255,255,1], 'lightgoldenrodyellow': [250,250,210,1], 'lightgray': [211,211,211,1], 'lightgreen': [144,238,144,1], 'lightgrey': [211,211,211,1], 'lightpink': [255,182,193,1], 'lightsalmon': [255,160,122,1], 'lightseagreen': [32,178,170,1], 'lightskyblue': [135,206,250,1], 'lightslategray': [119,136,153,1], 'lightslategrey': [119,136,153,1], 'lightsteelblue': [176,196,222,1], 'lightyellow': [255,255,224,1], 'lime': [0,255,0,1], 'limegreen': [50,205,50,1], 'linen': [250,240,230,1], 'magenta': [255,0,255,1], 'maroon': [128,0,0,1], 'mediumaquamarine': [102,205,170,1], 'mediumblue': [0,0,205,1], 'mediumorchid': [186,85,211,1], 'mediumpurple': [147,112,219,1], 'mediumseagreen': [60,179,113,1], 'mediumslateblue': [123,104,238,1], 'mediumspringgreen': [0,250,154,1], 'mediumturquoise': [72,209,204,1], 'mediumvioletred': [199,21,133,1], 'midnightblue': [25,25,112,1], 'mintcream': [245,255,250,1], 'mistyrose': [255,228,225,1], 'moccasin': [255,228,181,1], 'navajowhite': [255,222,173,1], 'navy': [0,0,128,1], 'oldlace': [253,245,230,1], 'olive': [128,128,0,1], 'olivedrab': [107,142,35,1], 'orange': [255,165,0,1], 'orangered': [255,69,0,1], 'orchid': [218,112,214,1], 'palegoldenrod': [238,232,170,1], 'palegreen': [152,251,152,1], 'paleturquoise': [175,238,238,1], 'palevioletred': [219,112,147,1], 'papayawhip': [255,239,213,1], 'peachpuff': [255,218,185,1], 'peru': [205,133,63,1], 'pink': [255,192,203,1], 'plum': [221,160,221,1], 'powderblue': [176,224,230,1], 'purple': [128,0,128,1], 'red': [255,0,0,1], 'rosybrown': [188,143,143,1], 'royalblue': [65,105,225,1], 'saddlebrown': [139,69,19,1], 'salmon': [250,128,114,1], 'sandybrown': [244,164,96,1], 'seagreen': [46,139,87,1], 'seashell': [255,245,238,1], 'sienna': [160,82,45,1], 'silver': [192,192,192,1], 'skyblue': [135,206,235,1], 'slateblue': [106,90,205,1], 'slategray': [112,128,144,1], 'slategrey': [112,128,144,1], 'snow': [255,250,250,1], 'springgreen': [0,255,127,1], 'steelblue': [70,130,180,1], 'tan': [210,180,140,1], 'teal': [0,128,128,1], 'thistle': [216,191,216,1], 'tomato': [255,99,71,1], 'turquoise': [64,224,208,1], 'violet': [238,130,238,1], 'wheat': [245,222,179,1], 'white': [255,255,255,1], 'whitesmoke': [245,245,245,1], 'yellow': [255,255,0,1], 'yellowgreen': [154,205,50,1] }; function clampCssByte(i) { // Clamp to integer 0 .. 255. i = Math.round(i); // Seems to be what Chrome does (vs truncation). return i < 0 ? 0 : i > 255 ? 255 : i; } function clampCssAngle(i) { // Clamp to integer 0 .. 360. i = Math.round(i); // Seems to be what Chrome does (vs truncation). return i < 0 ? 0 : i > 360 ? 360 : i; } function clampCssFloat(f) { // Clamp to float 0.0 .. 1.0. return f < 0 ? 0 : f > 1 ? 1 : f; } function parseCssInt(str) { // int or percentage. if (str.length && str.charAt(str.length - 1) === '%') { return clampCssByte(parseFloat(str) / 100 * 255); } return clampCssByte(parseInt(str, 10)); } function parseCssFloat(str) { // float or percentage. if (str.length && str.charAt(str.length - 1) === '%') { return clampCssFloat(parseFloat(str) / 100); } return clampCssFloat(parseFloat(str)); } function cssHueToRgb(m1, m2, h) { if (h < 0) { h += 1; } else if (h > 1) { h -= 1; } if (h * 6 < 1) { return m1 + (m2 - m1) * h * 6; } if (h * 2 < 1) { return m2; } if (h * 3 < 2) { return m1 + (m2 - m1) * (2/3 - h) * 6; } return m1; } function lerpNumber(a, b, p) { return a + (b - a) * p; } function setRgba(out, r, g, b, a) { out[0] = r; out[1] = g; out[2] = b; out[3] = a; return out; } function copyRgba(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; } var colorCache = new LRU$1(20); var lastRemovedArr = null; function putToCache(colorStr, rgbaArr) { // Reuse removed array if (lastRemovedArr) { copyRgba(lastRemovedArr, rgbaArr); } lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || (rgbaArr.slice())); } /** * @name clay.core.color.parse * @param {string} colorStr * @param {Array.} out * @return {Array.} */ colorUtil.parse = function (colorStr, rgbaArr) { if (!colorStr) { return; } rgbaArr = rgbaArr || []; var cached = colorCache.get(colorStr); if (cached) { return copyRgba(rgbaArr, cached); } // colorStr may be not string colorStr = colorStr + ''; // Remove all whitespace, not compliant, but should just be more accepting. var str = colorStr.replace(/ /g, '').toLowerCase(); // Color keywords (and transparent) lookup. if (str in kCSSColorTable) { copyRgba(rgbaArr, kCSSColorTable[str]); putToCache(colorStr, rgbaArr); return rgbaArr; } // #abc and #abc123 syntax. if (str.charAt(0) === '#') { if (str.length === 4) { var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing. if (!(iv >= 0 && iv <= 0xfff)) { setRgba(rgbaArr, 0, 0, 0, 1); return; // Covers NaN. } setRgba(rgbaArr, ((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8), (iv & 0xf0) | ((iv & 0xf0) >> 4), (iv & 0xf) | ((iv & 0xf) << 4), 1 ); putToCache(colorStr, rgbaArr); return rgbaArr; } else if (str.length === 7) { var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing. if (!(iv >= 0 && iv <= 0xffffff)) { setRgba(rgbaArr, 0, 0, 0, 1); return; // Covers NaN. } setRgba(rgbaArr, (iv & 0xff0000) >> 16, (iv & 0xff00) >> 8, iv & 0xff, 1 ); putToCache(colorStr, rgbaArr); return rgbaArr; } return; } var op = str.indexOf('('), ep = str.indexOf(')'); if (op !== -1 && ep + 1 === str.length) { var fname = str.substr(0, op); var params = str.substr(op + 1, ep - (op + 1)).split(','); var alpha = 1; // To allow case fallthrough. switch (fname) { case 'rgba': if (params.length !== 4) { setRgba(rgbaArr, 0, 0, 0, 1); return; } alpha = parseCssFloat(params.pop()); // jshint ignore:line // Fall through. case 'rgb': if (params.length !== 3) { setRgba(rgbaArr, 0, 0, 0, 1); return; } setRgba(rgbaArr, parseCssInt(params[0]), parseCssInt(params[1]), parseCssInt(params[2]), alpha ); putToCache(colorStr, rgbaArr); return rgbaArr; case 'hsla': if (params.length !== 4) { setRgba(rgbaArr, 0, 0, 0, 1); return; } params[3] = parseCssFloat(params[3]); hsla2rgba(params, rgbaArr); putToCache(colorStr, rgbaArr); return rgbaArr; case 'hsl': if (params.length !== 3) { setRgba(rgbaArr, 0, 0, 0, 1); return; } hsla2rgba(params, rgbaArr); putToCache(colorStr, rgbaArr); return rgbaArr; default: return; } } setRgba(rgbaArr, 0, 0, 0, 1); return; }; colorUtil.parseToFloat = function (colorStr, rgbaArr) { rgbaArr = colorUtil.parse(colorStr, rgbaArr); if (!rgbaArr) { return; } rgbaArr[0] /= 255; rgbaArr[1] /= 255; rgbaArr[2] /= 255; return rgbaArr; }; /** * @name clay.core.color.hsla2rgba * @param {Array.} hsla * @param {Array.} rgba * @return {Array.} rgba */ function hsla2rgba(hsla, rgba) { var h = (((parseFloat(hsla[0]) % 360) + 360) % 360) / 360; // 0 .. 1 // NOTE(deanm): According to the CSS spec s/l should only be // percentages, but we don't bother and let float or percentage. var s = parseCssFloat(hsla[1]); var l = parseCssFloat(hsla[2]); var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; var m1 = l * 2 - m2; rgba = rgba || []; setRgba(rgba, clampCssByte(cssHueToRgb(m1, m2, h + 1 / 3) * 255), clampCssByte(cssHueToRgb(m1, m2, h) * 255), clampCssByte(cssHueToRgb(m1, m2, h - 1 / 3) * 255), 1 ); if (hsla.length === 4) { rgba[3] = hsla[3]; } return rgba; } /** * @name clay.core.color.rgba2hsla * @param {Array.} rgba * @return {Array.} hsla */ function rgba2hsla(rgba) { if (!rgba) { return; } // RGB from 0 to 255 var R = rgba[0] / 255; var G = rgba[1] / 255; var B = rgba[2] / 255; var vMin = Math.min(R, G, B); // Min. value of RGB var vMax = Math.max(R, G, B); // Max. value of RGB var delta = vMax - vMin; // Delta RGB value var L = (vMax + vMin) / 2; var H; var S; // HSL results from 0 to 1 if (delta === 0) { H = 0; S = 0; } else { if (L < 0.5) { S = delta / (vMax + vMin); } else { S = delta / (2 - vMax - vMin); } var deltaR = (((vMax - R) / 6) + (delta / 2)) / delta; var deltaG = (((vMax - G) / 6) + (delta / 2)) / delta; var deltaB = (((vMax - B) / 6) + (delta / 2)) / delta; if (R === vMax) { H = deltaB - deltaG; } else if (G === vMax) { H = (1 / 3) + deltaR - deltaB; } else if (B === vMax) { H = (2 / 3) + deltaG - deltaR; } if (H < 0) { H += 1; } if (H > 1) { H -= 1; } } var hsla = [H * 360, S, L]; if (rgba[3] != null) { hsla.push(rgba[3]); } return hsla; } /** * @name clay.core.color.lift * @param {string} color * @param {number} level * @return {string} */ colorUtil.lift = function (color, level) { var colorArr = colorUtil.parse(color); if (colorArr) { for (var i = 0; i < 3; i++) { if (level < 0) { colorArr[i] = colorArr[i] * (1 - level) | 0; } else { colorArr[i] = ((255 - colorArr[i]) * level + colorArr[i]) | 0; } } return colorUtil.stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb'); } }; /** * @name clay.core.color.toHex * @param {string} color * @return {string} */ colorUtil.toHex = function (color) { var colorArr = colorUtil.parse(color); if (colorArr) { return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + (+colorArr[2])).toString(16).slice(1); } }; /** * Map value to color. Faster than lerp methods because color is represented by rgba array. * @name clay.core.color * @param {number} normalizedValue A float between 0 and 1. * @param {Array.>} colors List of rgba color array * @param {Array.} [out] Mapped gba color array * @return {Array.} will be null/undefined if input illegal. */ colorUtil.fastLerp = function (normalizedValue, colors, out) { if (!(colors && colors.length) || !(normalizedValue >= 0 && normalizedValue <= 1) ) { return; } out = out || []; var value = normalizedValue * (colors.length - 1); var leftIndex = Math.floor(value); var rightIndex = Math.ceil(value); var leftColor = colors[leftIndex]; var rightColor = colors[rightIndex]; var dv = value - leftIndex; out[0] = clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)); out[1] = clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)); out[2] = clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)); out[3] = clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv)); return out; }; colorUtil.fastMapToColor = colorUtil.fastLerp; /** * @param {number} normalizedValue A float between 0 and 1. * @param {Array.} colors Color list. * @param {boolean=} fullOutput Default false. * @return {(string|Object)} Result color. If fullOutput, * return {color: ..., leftIndex: ..., rightIndex: ..., value: ...}, */ colorUtil.lerp = function (normalizedValue, colors, fullOutput) { if (!(colors && colors.length) || !(normalizedValue >= 0 && normalizedValue <= 1) ) { return; } var value = normalizedValue * (colors.length - 1); var leftIndex = Math.floor(value); var rightIndex = Math.ceil(value); var leftColor = colorUtil.parse(colors[leftIndex]); var rightColor = colorUtil.parse(colors[rightIndex]); var dv = value - leftIndex; var color = colorUtil.stringify( [ clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)), clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)), clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)), clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv)) ], 'rgba' ); return fullOutput ? { color: color, leftIndex: leftIndex, rightIndex: rightIndex, value: value } : color; }; /** * @deprecated */ colorUtil.mapToColor = colorUtil.lerp; /** * @name clay.core.color * @param {string} color * @param {number=} h 0 ~ 360, ignore when null. * @param {number=} s 0 ~ 1, ignore when null. * @param {number=} l 0 ~ 1, ignore when null. * @return {string} Color string in rgba format. */ colorUtil.modifyHSL = function (color, h, s, l) { color = colorUtil.parse(color); if (color) { color = rgba2hsla(color); h != null && (color[0] = clampCssAngle(h)); s != null && (color[1] = parseCssFloat(s)); l != null && (color[2] = parseCssFloat(l)); return colorUtil.stringify(hsla2rgba(color), 'rgba'); } }; /** * @param {string} color * @param {number=} alpha 0 ~ 1 * @return {string} Color string in rgba format. */ colorUtil.modifyAlpha = function (color, alpha) { color = colorUtil.parse(color); if (color && alpha != null) { color[3] = clampCssFloat(alpha); return colorUtil.stringify(color, 'rgba'); } }; /** * @param {Array.} arrColor like [12,33,44,0.4] * @param {string} type 'rgba', 'hsva', ... * @return {string} Result color. (If input illegal, return undefined). */ colorUtil.stringify = function (arrColor, type) { if (!arrColor || !arrColor.length) { return; } var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2]; if (type === 'rgba' || type === 'hsva' || type === 'hsla') { colorStr += ',' + arrColor[3]; } return type + '(' + colorStr + ')'; }; var parseColor$1 = colorUtil.parseToFloat; var programKeyCache = {}; function getDefineCode(defines) { var defineKeys = Object.keys(defines); defineKeys.sort(); var defineStr = []; // Custom Defines for (var i = 0; i < defineKeys.length; i++) { var key = defineKeys[i]; var value = defines[key]; if (value === null) { defineStr.push(key); } else{ defineStr.push(key + ' ' + value.toString()); } } return defineStr.join('\n'); } function getProgramKey(vertexDefines, fragmentDefines, enabledTextures) { enabledTextures.sort(); var defineStr = []; for (var i = 0; i < enabledTextures.length; i++) { var symbol = enabledTextures[i]; defineStr.push(symbol); } var key = getDefineCode(vertexDefines) + '\n' + getDefineCode(fragmentDefines) + '\n' + defineStr.join('\n'); if (programKeyCache[key]) { return programKeyCache[key]; } var id = util$1.genGUID(); programKeyCache[key] = id; return id; } /** * Material defines the appearance of mesh surface, like `color`, `roughness`, `metalness`, etc. * It contains a {@link clay.Shader} and corresponding uniforms. * * Here is a basic example to create a standard material ```js var material = new clay.Material({ shader: new clay.Shader( clay.Shader.source('clay.vertex'), clay.Shader.source('clay.fragment') ) }); ``` * @constructor clay.Material * @extends clay.core.Base */ var Material = Base.extend(function () { return /** @lends clay.Material# */ { /** * @type {string} */ name: '', /** * @type {Object} */ // uniforms: null, /** * @type {clay.Shader} */ // shader: null, /** * @type {boolean} */ depthTest: true, /** * @type {boolean} */ depthMask: true, /** * @type {boolean} */ transparent: false, /** * Blend func is a callback function when the material * have custom blending * The gl context will be the only argument passed in tho the * blend function * Detail of blend function in WebGL: * http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf * * Example : * function(_gl) { * _gl.blendEquation(_gl.FUNC_ADD); * _gl.blendFunc(_gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA); * } */ blend: null, /** * If update texture status automatically. */ autoUpdateTextureStatus: true, uniforms: {}, vertexDefines: {}, fragmentDefines: {}, _textureStatus: {}, // shadowTransparentMap : null // PENDING enable the uniform that only used in shader. _enabledUniforms: null, }; }, function () { if (!this.name) { this.name = 'MATERIAL_' + this.__uid__; } if (this.shader) { // Keep status, mainly preset uniforms, vertexDefines and fragmentDefines this.attachShader(this.shader, true); } }, /** @lends clay.Material.prototype */ { precision: 'highp', /** * Set material uniform * @example * mat.setUniform('color', [1, 1, 1, 1]); * @param {string} symbol * @param {number|array|clay.Texture|ArrayBufferView} value */ setUniform: function (symbol, value) { if (value === undefined) { console.warn('Uniform value "' + symbol + '" is undefined'); } var uniform = this.uniforms[symbol]; if (uniform) { if (typeof value === 'string') { // Try to parse as a color. Invalid color string will return null. value = parseColor$1(value) || value; } uniform.value = value; if (this.autoUpdateTextureStatus && uniform.type === 't') { if (value) { this.enableTexture(symbol); } else { this.disableTexture(symbol); } } } }, /** * @param {Object} obj */ setUniforms: function(obj) { for (var key in obj) { var val = obj[key]; this.setUniform(key, val); } }, /** * @param {string} symbol * @return {boolean} */ isUniformEnabled: function (symbol) { return this._enabledUniforms.indexOf(symbol) >= 0; }, getEnabledUniforms: function () { return this._enabledUniforms; }, getTextureUniforms: function () { return this._textureUniforms; }, /** * Alias of setUniform and setUniforms * @param {object|string} symbol * @param {number|array|clay.Texture|ArrayBufferView} [value] */ set: function (symbol, value) { if (typeof(symbol) === 'object') { for (var key in symbol) { var val = symbol[key]; this.setUniform(key, val); } } else { this.setUniform(symbol, value); } }, /** * Get uniform value * @param {string} symbol * @return {number|array|clay.Texture|ArrayBufferView} */ get: function (symbol) { var uniform = this.uniforms[symbol]; if (uniform) { return uniform.value; } }, /** * Attach a shader instance * @param {clay.Shader} shader * @param {boolean} keepStatus If try to keep uniform and texture */ attachShader: function(shader, keepStatus) { var originalUniforms = this.uniforms; // Ignore if uniform can use in shader. this.uniforms = shader.createUniforms(); this.shader = shader; var uniforms = this.uniforms; this._enabledUniforms = Object.keys(uniforms); // Make sure uniforms are set in same order to avoid texture slot wrong this._enabledUniforms.sort(); this._textureUniforms = this._enabledUniforms.filter(function (uniformName) { var type = this.uniforms[uniformName].type; return type === 't' || type === 'tv'; }, this); var originalVertexDefines = this.vertexDefines; var originalFragmentDefines = this.fragmentDefines; this.vertexDefines = util$1.clone(shader.vertexDefines); this.fragmentDefines = util$1.clone(shader.fragmentDefines); if (keepStatus) { for (var symbol in originalUniforms) { if (uniforms[symbol]) { uniforms[symbol].value = originalUniforms[symbol].value; } } util$1.defaults(this.vertexDefines, originalVertexDefines); util$1.defaults(this.fragmentDefines, originalFragmentDefines); } var textureStatus = {}; for (var key in shader.textures) { textureStatus[key] = { shaderType: shader.textures[key].shaderType, type: shader.textures[key].type, enabled: (keepStatus && this._textureStatus[key]) ? this._textureStatus[key].enabled : false }; } this._textureStatus = textureStatus; this._programKey = ''; }, /** * Clone a new material and keep uniforms, shader will not be cloned * @return {clay.Material} */ clone: function () { var material = new this.constructor({ name: this.name, shader: this.shader }); for (var symbol in this.uniforms) { material.uniforms[symbol].value = this.uniforms[symbol].value; } material.depthTest = this.depthTest; material.depthMask = this.depthMask; material.transparent = this.transparent; material.blend = this.blend; material.vertexDefines = util$1.clone(this.vertexDefines); material.fragmentDefines = util$1.clone(this.fragmentDefines); material.enableTexture(this.getEnabledTextures()); material.precision = this.precision; return material; }, /** * Add a #define macro in shader code * @param {string} shaderType Can be vertex, fragment or both * @param {string} symbol * @param {number} [val] */ define: function (shaderType, symbol, val) { var vertexDefines = this.vertexDefines; var fragmentDefines = this.fragmentDefines; if (shaderType !== 'vertex' && shaderType !== 'fragment' && shaderType !== 'both' && arguments.length < 3 ) { // shaderType default to be 'both' val = symbol; symbol = shaderType; shaderType = 'both'; } val = val != null ? val : null; if (shaderType === 'vertex' || shaderType === 'both') { if (vertexDefines[symbol] !== val) { vertexDefines[symbol] = val; // Mark as dirty this._programKey = ''; } } if (shaderType === 'fragment' || shaderType === 'both') { if (fragmentDefines[symbol] !== val) { fragmentDefines[symbol] = val; if (shaderType !== 'both') { this._programKey = ''; } } } }, /** * Remove a #define macro in shader code * @param {string} shaderType Can be vertex, fragment or both * @param {string} symbol */ undefine: function (shaderType, symbol) { if (shaderType !== 'vertex' && shaderType !== 'fragment' && shaderType !== 'both' && arguments.length < 2 ) { // shaderType default to be 'both' symbol = shaderType; shaderType = 'both'; } if (shaderType === 'vertex' || shaderType === 'both') { if (this.isDefined('vertex', symbol)) { delete this.vertexDefines[symbol]; // Mark as dirty this._programKey = ''; } } if (shaderType === 'fragment' || shaderType === 'both') { if (this.isDefined('fragment', symbol)) { delete this.fragmentDefines[symbol]; if (shaderType !== 'both') { this._programKey = ''; } } } }, /** * If macro is defined in shader. * @param {string} shaderType Can be vertex, fragment or both * @param {string} symbol */ isDefined: function (shaderType, symbol) { // PENDING hasOwnProperty ? switch (shaderType) { case 'vertex': return this.vertexDefines[symbol] !== undefined; case 'fragment': return this.fragmentDefines[symbol] !== undefined; } }, /** * Get macro value defined in shader. * @param {string} shaderType Can be vertex, fragment or both * @param {string} symbol */ getDefine: function (shaderType, symbol) { switch(shaderType) { case 'vertex': return this.vertexDefines[symbol]; case 'fragment': return this.fragmentDefines[symbol]; } }, /** * Enable a texture, actually it will add a #define macro in the shader code * For example, if texture symbol is diffuseMap, it will add a line `#define DIFFUSEMAP_ENABLED` in the shader code * @param {string} symbol */ enableTexture: function (symbol) { if (Array.isArray(symbol)) { for (var i = 0; i < symbol.length; i++) { this.enableTexture(symbol[i]); } return; } var status = this._textureStatus[symbol]; if (status) { var isEnabled = status.enabled; if (!isEnabled) { status.enabled = true; this._programKey = ''; } } }, /** * Enable all textures used in the shader */ enableTexturesAll: function () { var textureStatus = this._textureStatus; for (var symbol in textureStatus) { textureStatus[symbol].enabled = true; } this._programKey = ''; }, /** * Disable a texture, it remove a #define macro in the shader * @param {string} symbol */ disableTexture: function (symbol) { if (Array.isArray(symbol)) { for (var i = 0; i < symbol.length; i++) { this.disableTexture(symbol[i]); } return; } var status = this._textureStatus[symbol]; if (status) { var isDisabled = ! status.enabled; if (!isDisabled) { status.enabled = false; this._programKey = ''; } } }, /** * Disable all textures used in the shader */ disableTexturesAll: function () { var textureStatus = this._textureStatus; for (var symbol in textureStatus) { textureStatus[symbol].enabled = false; } this._programKey = ''; }, /** * If texture of given type is enabled. * @param {string} symbol * @return {boolean} */ isTextureEnabled: function (symbol) { var textureStatus = this._textureStatus; return !!textureStatus[symbol] && textureStatus[symbol].enabled; }, /** * Get all enabled textures * @return {string[]} */ getEnabledTextures: function () { var enabledTextures = []; var textureStatus = this._textureStatus; for (var symbol in textureStatus) { if (textureStatus[symbol].enabled) { enabledTextures.push(symbol); } } return enabledTextures; }, /** * Mark defines are updated. */ dirtyDefines: function () { this._programKey = ''; }, getProgramKey: function () { if (!this._programKey) { this._programKey = getProgramKey( this.vertexDefines, this.fragmentDefines, this.getEnabledTextures() ); } return this._programKey; } }); var SHADER_STATE_TO_ENABLE = 1; var SHADER_STATE_KEEP_ENABLE = 2; var SHADER_STATE_PENDING = 3; // Enable attribute operation is global to all programs // Here saved the list of all enabled attribute index // http://www.mjbshaw.com/2013/03/webgl-fixing-invalidoperation.html var enabledAttributeList = {}; // some util functions function addLineNumbers(string) { var chunks = string.split('\n'); for (var i = 0, il = chunks.length; i < il; i ++) { // Chrome reports shader errors on lines // starting counting from 1 chunks[i] = (i + 1) + ': ' + chunks[i]; } return chunks.join('\n'); } // Return true or error msg if error happened function checkShaderErrorMsg(_gl, shader, shaderString) { if (!_gl.getShaderParameter(shader, _gl.COMPILE_STATUS)) { return [_gl.getShaderInfoLog(shader), addLineNumbers(shaderString)].join('\n'); } } var tmpFloat32Array16 = new vendor.Float32Array(16); var GLProgram = Base.extend({ uniformSemantics: {}, attributes: {} }, function () { this._locations = {}; this._textureSlot = 0; this._program = null; }, { bind: function (renderer) { this._textureSlot = 0; renderer.gl.useProgram(this._program); }, hasUniform: function (symbol) { var location = this._locations[symbol]; return location !== null && location !== undefined; }, useTextureSlot: function (renderer, texture, slot) { if (texture) { renderer.gl.activeTexture(renderer.gl.TEXTURE0 + slot); // Maybe texture is not loaded yet; if (texture.isRenderable()) { texture.bind(renderer); } else { // Bind texture to null texture.unbind(renderer); } } }, currentTextureSlot: function () { return this._textureSlot; }, resetTextureSlot: function (slot) { this._textureSlot = slot || 0; }, takeCurrentTextureSlot: function (renderer, texture) { var textureSlot = this._textureSlot; this.useTextureSlot(renderer, texture, textureSlot); this._textureSlot++; return textureSlot; }, setUniform: function (_gl, type, symbol, value) { var locationMap = this._locations; var location = locationMap[symbol]; // Uniform is not existed in the shader if (location === null || location === undefined) { return false; } switch (type) { case 'm4': if (!(value instanceof Float32Array)) { // Use Float32Array is much faster than array when uniformMatrix4fv. for (var i = 0; i < value.length; i++) { tmpFloat32Array16[i] = value[i]; } value = tmpFloat32Array16; } _gl.uniformMatrix4fv(location, false, value); break; case '2i': _gl.uniform2i(location, value[0], value[1]); break; case '2f': _gl.uniform2f(location, value[0], value[1]); break; case '3i': _gl.uniform3i(location, value[0], value[1], value[2]); break; case '3f': _gl.uniform3f(location, value[0], value[1], value[2]); break; case '4i': _gl.uniform4i(location, value[0], value[1], value[2], value[3]); break; case '4f': _gl.uniform4f(location, value[0], value[1], value[2], value[3]); break; case '1i': _gl.uniform1i(location, value); break; case '1f': _gl.uniform1f(location, value); break; case '1fv': _gl.uniform1fv(location, value); break; case '1iv': _gl.uniform1iv(location, value); break; case '2iv': _gl.uniform2iv(location, value); break; case '2fv': _gl.uniform2fv(location, value); break; case '3iv': _gl.uniform3iv(location, value); break; case '3fv': _gl.uniform3fv(location, value); break; case '4iv': _gl.uniform4iv(location, value); break; case '4fv': _gl.uniform4fv(location, value); break; case 'm2': case 'm2v': _gl.uniformMatrix2fv(location, false, value); break; case 'm3': case 'm3v': _gl.uniformMatrix3fv(location, false, value); break; case 'm4v': // Raw value if (Array.isArray(value) && Array.isArray(value[0])) { var array = new vendor.Float32Array(value.length * 16); var cursor = 0; for (var i = 0; i < value.length; i++) { var item = value[i]; for (var j = 0; j < 16; j++) { array[cursor++] = item[j]; } } _gl.uniformMatrix4fv(location, false, array); } else { // ArrayBufferView _gl.uniformMatrix4fv(location, false, value); } break; } return true; }, setUniformOfSemantic: function (_gl, semantic, val) { var semanticInfo = this.uniformSemantics[semantic]; if (semanticInfo) { return this.setUniform(_gl, semanticInfo.type, semanticInfo.symbol, val); } return false; }, // Used for creating VAO // Enable the attributes passed in and disable the rest // Example Usage: // enableAttributes(renderer, ["position", "texcoords"]) enableAttributes: function (renderer, attribList, vao) { var _gl = renderer.gl; var program = this._program; var locationMap = this._locations; var enabledAttributeListInContext; if (vao) { enabledAttributeListInContext = vao.__enabledAttributeList; } else { enabledAttributeListInContext = enabledAttributeList[renderer.__uid__]; } if (!enabledAttributeListInContext) { // In vertex array object context // PENDING Each vao object needs to enable attributes again? if (vao) { enabledAttributeListInContext = vao.__enabledAttributeList = []; } else { enabledAttributeListInContext = enabledAttributeList[renderer.__uid__] = []; } } var locationList = []; for (var i = 0; i < attribList.length; i++) { var symbol = attribList[i]; if (!this.attributes[symbol]) { locationList[i] = -1; continue; } var location = locationMap[symbol]; if (location == null) { location = _gl.getAttribLocation(program, symbol); // Attrib location is a number from 0 to ... if (location === -1) { locationList[i] = -1; continue; } locationMap[symbol] = location; } locationList[i] = location; if (!enabledAttributeListInContext[location]) { enabledAttributeListInContext[location] = SHADER_STATE_TO_ENABLE; } else { enabledAttributeListInContext[location] = SHADER_STATE_KEEP_ENABLE; } } for (var i = 0; i < enabledAttributeListInContext.length; i++) { switch(enabledAttributeListInContext[i]){ case SHADER_STATE_TO_ENABLE: _gl.enableVertexAttribArray(i); enabledAttributeListInContext[i] = SHADER_STATE_PENDING; break; case SHADER_STATE_KEEP_ENABLE: enabledAttributeListInContext[i] = SHADER_STATE_PENDING; break; // Expired case SHADER_STATE_PENDING: _gl.disableVertexAttribArray(i); enabledAttributeListInContext[i] = 0; break; } } return locationList; }, buildProgram: function (_gl, shader, vertexShaderCode, fragmentShaderCode) { var vertexShader = _gl.createShader(_gl.VERTEX_SHADER); var program = _gl.createProgram(); _gl.shaderSource(vertexShader, vertexShaderCode); _gl.compileShader(vertexShader); var fragmentShader = _gl.createShader(_gl.FRAGMENT_SHADER); _gl.shaderSource(fragmentShader, fragmentShaderCode); _gl.compileShader(fragmentShader); var msg = checkShaderErrorMsg(_gl, vertexShader, vertexShaderCode); if (msg) { return msg; } msg = checkShaderErrorMsg(_gl, fragmentShader, fragmentShaderCode); if (msg) { return msg; } _gl.attachShader(program, vertexShader); _gl.attachShader(program, fragmentShader); // Force the position bind to location 0; if (shader.attributeSemantics['POSITION']) { _gl.bindAttribLocation(program, 0, shader.attributeSemantics['POSITION'].symbol); } else { // Else choose an attribute and bind to location 0; var keys = Object.keys(this.attributes); _gl.bindAttribLocation(program, 0, keys[0]); } _gl.linkProgram(program); if (!_gl.getProgramParameter(program, _gl.LINK_STATUS)) { return 'Could not link program\n' + _gl.getProgramInfoLog(program); } // Cache uniform locations for (var i = 0; i < shader.uniforms.length; i++) { var uniformSymbol = shader.uniforms[i]; this._locations[uniformSymbol] = _gl.getUniformLocation(program, uniformSymbol); } _gl.deleteShader(vertexShader); _gl.deleteShader(fragmentShader); this._program = program; // Save code. this.vertexCode = vertexShaderCode; this.fragmentCode = fragmentShaderCode; } }); var loopRegex = /for\s*?\(int\s*?_idx_\s*\=\s*([\w-]+)\;\s*_idx_\s*<\s*([\w-]+);\s*_idx_\s*\+\+\s*\)\s*\{\{([\s\S]+?)(?=\}\})\}\}/g; function unrollLoop(shaderStr, defines, lightsNumbers) { // Loop unroll from three.js, https://github.com/mrdoob/three.js/blob/master/src/renderers/webgl/WebGLProgram.js#L175 // In some case like shadowMap in loop use 'i' to index value much slower. // Loop use _idx_ and increased with _idx_++ will be unrolled // Use {{ }} to match the pair so the if statement will not be affected // Write like following // for (int _idx_ = 0; _idx_ < 4; _idx_++) {{ // vec3 color = texture2D(textures[_idx_], uv).rgb; // }} function replace(match, start, end, snippet) { var unroll = ''; // Try to treat as define if (isNaN(start)) { if (start in defines) { start = defines[start]; } else { start = lightNumberDefines[start]; } } if (isNaN(end)) { if (end in defines) { end = defines[end]; } else { end = lightNumberDefines[end]; } } // TODO Error checking for (var idx = parseInt(start); idx < parseInt(end); idx++) { // PENDING Add scope? unroll += '{' + snippet .replace(/float\s*\(\s*_idx_\s*\)/g, idx.toFixed(1)) .replace(/_idx_/g, idx) + '}'; } return unroll; } var lightNumberDefines = {}; for (var lightType in lightsNumbers) { lightNumberDefines[lightType + '_COUNT'] = lightsNumbers[lightType]; } return shaderStr.replace(loopRegex, replace); } function getDefineCode$1(defines, lightsNumbers, enabledTextures) { var defineStr = []; if (lightsNumbers) { for (var lightType in lightsNumbers) { var count = lightsNumbers[lightType]; if (count > 0) { defineStr.push('#define ' + lightType.toUpperCase() + '_COUNT ' + count); } } } if (enabledTextures) { for (var i = 0; i < enabledTextures.length; i++) { var symbol = enabledTextures[i]; defineStr.push('#define ' + symbol.toUpperCase() + '_ENABLED'); } } // Custom Defines for (var symbol in defines) { var value = defines[symbol]; if (value === null) { defineStr.push('#define ' + symbol); } else{ defineStr.push('#define ' + symbol + ' ' + value.toString()); } } return defineStr.join('\n'); } function getExtensionCode(exts) { // Extension declaration must before all non-preprocessor codes // TODO vertex ? extension enum ? var extensionStr = []; for (var i = 0; i < exts.length; i++) { extensionStr.push('#extension GL_' + exts[i] + ' : enable'); } return extensionStr.join('\n'); } function getPrecisionCode(precision) { return ['precision', precision, 'float'].join(' ') + ';\n' + ['precision', precision, 'int'].join(' ') + ';\n' // depth texture may have precision problem on iOS device. + ['precision', precision, 'sampler2D'].join(' ') + ';\n'; } function ProgramManager(renderer) { this._renderer = renderer; this._cache = {}; } ProgramManager.prototype.getProgram = function (renderable, material, scene) { var cache = this._cache; var isSkinnedMesh = renderable.isSkinnedMesh && renderable.isSkinnedMesh(); var key = 's' + material.shader.shaderID + 'm' + material.getProgramKey(); if (scene) { key += 'se' + scene.getProgramKey(renderable.lightGroup); } if (isSkinnedMesh) { key += ',' + renderable.joints.length; } var program = cache[key]; if (program) { return program; } var lightsNumbers = scene ? scene.getLightsNumbers(renderable.lightGroup) : {}; var renderer = this._renderer; var _gl = renderer.gl; var enabledTextures = material.getEnabledTextures(); var skinDefineCode = ''; if (isSkinnedMesh) { var skinDefines = { SKINNING: null, JOINT_COUNT: renderable.joints.length }; if (renderable.joints.length > renderer.getMaxJointNumber()) { skinDefines.USE_SKIN_MATRICES_TEXTURE = null; } // TODO Add skinning code? skinDefineCode = '\n' + getDefineCode$1(skinDefines) + '\n'; } // TODO Optimize key generation // VERTEX var vertexDefineStr = skinDefineCode + getDefineCode$1(material.vertexDefines, lightsNumbers, enabledTextures); // FRAGMENT var fragmentDefineStr = skinDefineCode + getDefineCode$1(material.fragmentDefines, lightsNumbers, enabledTextures); var vertexCode = vertexDefineStr + '\n' + material.shader.vertex; var extensions = [ 'OES_standard_derivatives', 'EXT_shader_texture_lod' ].filter(function (ext) { return renderer.getGLExtension(ext) != null; }); if (extensions.indexOf('EXT_shader_texture_lod') >= 0) { fragmentDefineStr += '\n#define SUPPORT_TEXTURE_LOD'; } if (extensions.indexOf('OES_standard_derivatives') >= 0) { fragmentDefineStr += '\n#define SUPPORT_STANDARD_DERIVATIVES'; } var fragmentCode = getExtensionCode(extensions) + '\n' + getPrecisionCode(material.precision) + '\n' + fragmentDefineStr + '\n' + material.shader.fragment; var finalVertexCode = unrollLoop(vertexCode, material.vertexDefines, lightsNumbers); var finalFragmentCode = unrollLoop(fragmentCode, material.fragmentDefines, lightsNumbers); var program = new GLProgram(); program.uniformSemantics = material.shader.uniformSemantics; program.attributes = material.shader.attributes; var errorMsg = program.buildProgram(_gl, material.shader, finalVertexCode, finalFragmentCode); program.__error = errorMsg; cache[key] = program; return program; }; /** * Mainly do the parse and compile of shader string * Support shader code chunk import and export * Support shader semantics * http://www.nvidia.com/object/using_sas.html * https://github.com/KhronosGroup/collada2json/issues/45 */ var uniformRegex = /uniform\s+(bool|float|int|vec2|vec3|vec4|ivec2|ivec3|ivec4|mat2|mat3|mat4|sampler2D|samplerCube)\s+([\s\S]*?);/g; var attributeRegex = /attribute\s+(float|int|vec2|vec3|vec4)\s+([\s\S]*?);/g; // Only parse number define. var defineRegex = /#define\s+(\w+)?(\s+[\d-.]+)?\s*;?\s*\n/g; var uniformTypeMap = { 'bool': '1i', 'int': '1i', 'sampler2D': 't', 'samplerCube': 't', 'float': '1f', 'vec2': '2f', 'vec3': '3f', 'vec4': '4f', 'ivec2': '2i', 'ivec3': '3i', 'ivec4': '4i', 'mat2': 'm2', 'mat3': 'm3', 'mat4': 'm4' }; function createZeroArray(len) { var arr = []; for (var i = 0; i < len; i++) { arr[i] = 0; } return arr; } var uniformValueConstructor = { 'bool': function () { return true; }, 'int': function () { return 0; }, 'float': function () { return 0; }, 'sampler2D': function () { return null; }, 'samplerCube': function () { return null; }, 'vec2': function () { return createZeroArray(2); }, 'vec3': function () { return createZeroArray(3); }, 'vec4': function () { return createZeroArray(4); }, 'ivec2': function () { return createZeroArray(2); }, 'ivec3': function () { return createZeroArray(3); }, 'ivec4': function () { return createZeroArray(4); }, 'mat2': function () { return createZeroArray(4); }, 'mat3': function () { return createZeroArray(9); }, 'mat4': function () { return createZeroArray(16); }, 'array': function () { return []; } }; var attributeSemantics = [ 'POSITION', 'NORMAL', 'BINORMAL', 'TANGENT', 'TEXCOORD', 'TEXCOORD_0', 'TEXCOORD_1', 'COLOR', // Skinning // https://github.com/KhronosGroup/glTF/blob/master/specification/README.md#semantics 'JOINT', 'WEIGHT' ]; var uniformSemantics = [ 'SKIN_MATRIX', // Information about viewport 'VIEWPORT_SIZE', 'VIEWPORT', 'DEVICEPIXELRATIO', // Window size for window relative coordinate // https://www.opengl.org/sdk/docs/man/html/gl_FragCoord.xhtml 'WINDOW_SIZE', // Infomation about camera 'NEAR', 'FAR', // Time 'TIME' ]; var matrixSemantics = [ 'WORLD', 'VIEW', 'PROJECTION', 'WORLDVIEW', 'VIEWPROJECTION', 'WORLDVIEWPROJECTION', 'WORLDINVERSE', 'VIEWINVERSE', 'PROJECTIONINVERSE', 'WORLDVIEWINVERSE', 'VIEWPROJECTIONINVERSE', 'WORLDVIEWPROJECTIONINVERSE', 'WORLDTRANSPOSE', 'VIEWTRANSPOSE', 'PROJECTIONTRANSPOSE', 'WORLDVIEWTRANSPOSE', 'VIEWPROJECTIONTRANSPOSE', 'WORLDVIEWPROJECTIONTRANSPOSE', 'WORLDINVERSETRANSPOSE', 'VIEWINVERSETRANSPOSE', 'PROJECTIONINVERSETRANSPOSE', 'WORLDVIEWINVERSETRANSPOSE', 'VIEWPROJECTIONINVERSETRANSPOSE', 'WORLDVIEWPROJECTIONINVERSETRANSPOSE' ]; var attributeSizeMap = { // WebGL does not support integer attributes 'vec4': 4, 'vec3': 3, 'vec2': 2, 'float': 1 }; var shaderIDCache = {}; var shaderCodeCache = {}; function getShaderID(vertex, fragment) { var key = 'vertex:' + vertex + 'fragment:' + fragment; if (shaderIDCache[key]) { return shaderIDCache[key]; } var id = util$1.genGUID(); shaderIDCache[key] = id; shaderCodeCache[id] = { vertex: vertex, fragment: fragment }; return id; } function removeComment(code) { return code.replace(/[ \t]*\/\/.*\n/g, '' ) // remove // .replace(/[ \t]*\/\*[\s\S]*?\*\//g, '' ); // remove /* */ } function logSyntaxError() { console.error('Wrong uniform/attributes syntax'); } function parseDeclarations(type, line) { var speratorsRegexp = /[,=\(\):]/; var tokens = line // Convert `symbol: [1,2,3]` to `symbol: vec3(1,2,3)` .replace(/:\s*\[\s*(.*)\s*\]/g, '=' + type + '($1)') .replace(/\s+/g, '') .split(/(?=[,=\(\):])/g); var newTokens = []; for (var i = 0; i < tokens.length; i++) { if (tokens[i].match(speratorsRegexp)) { newTokens.push( tokens[i].charAt(0), tokens[i].slice(1) ); } else { newTokens.push(tokens[i]); } } tokens = newTokens; var TYPE_SYMBOL = 0; var TYPE_ASSIGN = 1; var TYPE_VEC = 2; var TYPE_ARR = 3; var TYPE_SEMANTIC = 4; var TYPE_NORMAL = 5; var opType = TYPE_SYMBOL; var declarations = {}; var declarationValue = null; var currentDeclaration; addSymbol(tokens[0]); function addSymbol(symbol) { if (!symbol) { logSyntaxError(); } var arrResult = symbol.match(/\[(.*?)\]/); currentDeclaration = symbol.replace(/\[(.*?)\]/, ''); declarations[currentDeclaration] = {}; if (arrResult) { declarations[currentDeclaration].isArray = true; declarations[currentDeclaration].arraySize = arrResult[1]; } } for (var i = 1; i < tokens.length; i++) { var token = tokens[i]; if (!token) { // Empty token; continue; } if (token === '=') { if (opType !== TYPE_SYMBOL && opType !== TYPE_ARR) { logSyntaxError(); break; } opType = TYPE_ASSIGN; continue; } else if (token === ':') { opType = TYPE_SEMANTIC; continue; } else if (token === ',') { if (opType === TYPE_VEC) { if (!(declarationValue instanceof Array)) { logSyntaxError(); break; } declarationValue.push(+tokens[++i]); } else { opType = TYPE_NORMAL; } continue; } else if (token === ')') { declarations[currentDeclaration].value = new vendor.Float32Array(declarationValue); declarationValue = null; opType = TYPE_NORMAL; continue; } else if (token === '(') { if (opType !== TYPE_VEC) { logSyntaxError(); break; } if (!(declarationValue instanceof Array)) { logSyntaxError(); break; } declarationValue.push(+tokens[++i]); continue; } else if (token.indexOf('vec') >= 0) { if (opType !== TYPE_ASSIGN // Compatitable with old syntax `symbol: [1,2,3]` && opType !== TYPE_SEMANTIC) { logSyntaxError(); break; } opType = TYPE_VEC; declarationValue = []; continue; } else if (opType === TYPE_ASSIGN) { if (type === 'bool') { declarations[currentDeclaration].value = token === 'true'; } else { declarations[currentDeclaration].value = parseFloat(token); } declarationValue = null; continue; } else if (opType === TYPE_SEMANTIC) { var semantic = token; if (attributeSemantics.indexOf(semantic) >= 0 || uniformSemantics.indexOf(semantic) >= 0 || matrixSemantics.indexOf(semantic) >= 0 ) { declarations[currentDeclaration].semantic = semantic; } else if (semantic === 'ignore' || semantic === 'unconfigurable') { declarations[currentDeclaration].ignore = true; } else { // Try to parse as a default tvalue. if (type === 'bool') { declarations[currentDeclaration].value = semantic === 'true'; } else { declarations[currentDeclaration].value = parseFloat(semantic); } } continue; } // treat as symbol. addSymbol(token); opType = TYPE_SYMBOL; } return declarations; } /** * @constructor * @extends clay.core.Base * @alias clay.Shader * @param {string} vertex * @param {string} fragment * @example * // Create a phong shader * var shader = new clay.Shader( * clay.Shader.source('clay.standard.vertex'), * clay.Shader.source('clay.standard.fragment') * ); */ function Shader(vertex, fragment) { // First argument can be { vertex, fragment } if (typeof vertex === 'object') { fragment = vertex.fragment; vertex = vertex.vertex; } vertex = removeComment(vertex); fragment = removeComment(fragment); this._shaderID = getShaderID(vertex, fragment); this._vertexCode = Shader.parseImport(vertex); this._fragmentCode = Shader.parseImport(fragment); /** * @readOnly */ this.attributeSemantics = {}; /** * @readOnly */ this.matrixSemantics = {}; /** * @readOnly */ this.uniformSemantics = {}; /** * @readOnly */ this.matrixSemanticKeys = []; /** * @readOnly */ this.uniformTemplates = {}; /** * @readOnly */ this.attributes = {}; /** * @readOnly */ this.textures = {}; /** * @readOnly */ this.vertexDefines = {}; /** * @readOnly */ this.fragmentDefines = {}; this._parseAttributes(); this._parseUniforms(); this._parseDefines(); } Shader.prototype = { constructor: Shader, // Create a new uniform instance for material createUniforms: function () { var uniforms = {}; for (var symbol in this.uniformTemplates){ var uniformTpl = this.uniformTemplates[symbol]; uniforms[symbol] = { type: uniformTpl.type, value: uniformTpl.value() }; } return uniforms; }, _parseImport: function () { this._vertexCode = Shader.parseImport(this.vertex); this._fragmentCode = Shader.parseImport(this.fragment); }, _addSemanticUniform: function (symbol, uniformType, semantic) { // This case is only for SKIN_MATRIX // TODO if (attributeSemantics.indexOf(semantic) >= 0) { this.attributeSemantics[semantic] = { symbol: symbol, type: uniformType }; } else if (matrixSemantics.indexOf(semantic) >= 0) { var isTranspose = false; var semanticNoTranspose = semantic; if (semantic.match(/TRANSPOSE$/)) { isTranspose = true; semanticNoTranspose = semantic.slice(0, -9); } this.matrixSemantics[semantic] = { symbol: symbol, type: uniformType, isTranspose: isTranspose, semanticNoTranspose: semanticNoTranspose }; } else if (uniformSemantics.indexOf(semantic) >= 0) { this.uniformSemantics[semantic] = { symbol: symbol, type: uniformType }; } }, _addMaterialUniform: function (symbol, type, uniformType, defaultValueFunc, isArray, materialUniforms) { materialUniforms[symbol] = { type: uniformType, value: isArray ? uniformValueConstructor['array'] : (defaultValueFunc || uniformValueConstructor[type]), semantic: null }; }, _parseUniforms: function () { var uniforms = {}; var self = this; var shaderType = 'vertex'; this._uniformList = []; this._vertexCode = this._vertexCode.replace(uniformRegex, _uniformParser); shaderType = 'fragment'; this._fragmentCode = this._fragmentCode.replace(uniformRegex, _uniformParser); self.matrixSemanticKeys = Object.keys(this.matrixSemantics); function makeDefaultValueFunc(value) { return value != null ? function () { return value; } : null; } function _uniformParser(str, type, content) { var declaredUniforms = parseDeclarations(type, content); var uniformMainStr = []; for (var symbol in declaredUniforms) { var uniformInfo = declaredUniforms[symbol]; var semantic = uniformInfo.semantic; var tmpStr = symbol; var uniformType = uniformTypeMap[type]; var defaultValueFunc = makeDefaultValueFunc(declaredUniforms[symbol].value); if (declaredUniforms[symbol].isArray) { tmpStr += '[' + declaredUniforms[symbol].arraySize + ']'; uniformType += 'v'; } uniformMainStr.push(tmpStr); self._uniformList.push(symbol); if (!uniformInfo.ignore) { if (type === 'sampler2D' || type === 'samplerCube') { // Texture is default disabled self.textures[symbol] = { shaderType: shaderType, type: type }; } if (semantic) { // TODO Should not declare multiple symbols if have semantic. self._addSemanticUniform(symbol, uniformType, semantic); } else { self._addMaterialUniform( symbol, type, uniformType, defaultValueFunc, declaredUniforms[symbol].isArray, uniforms ); } } } return uniformMainStr.length > 0 ? 'uniform ' + type + ' ' + uniformMainStr.join(',') + ';\n' : ''; } this.uniformTemplates = uniforms; }, _parseAttributes: function () { var attributes = {}; var self = this; this._vertexCode = this._vertexCode.replace(attributeRegex, _attributeParser); function _attributeParser(str, type, content) { var declaredAttributes = parseDeclarations(type, content); var size = attributeSizeMap[type] || 1; var attributeMainStr = []; for (var symbol in declaredAttributes) { var semantic = declaredAttributes[symbol].semantic; attributes[symbol] = { // TODO Can only be float type: 'float', size: size, semantic: semantic || null }; // TODO Should not declare multiple symbols if have semantic. if (semantic) { if (attributeSemantics.indexOf(semantic) < 0) { throw new Error('Unkown semantic "' + semantic + '"'); } else { self.attributeSemantics[semantic] = { symbol: symbol, type: type }; } } attributeMainStr.push(symbol); } return 'attribute ' + type + ' ' + attributeMainStr.join(',') + ';\n'; } this.attributes = attributes; }, _parseDefines: function () { var self = this; var shaderType = 'vertex'; this._vertexCode = this._vertexCode.replace(defineRegex, _defineParser); shaderType = 'fragment'; this._fragmentCode = this._fragmentCode.replace(defineRegex, _defineParser); function _defineParser(str, symbol, value) { var defines = shaderType === 'vertex' ? self.vertexDefines : self.fragmentDefines; if (!defines[symbol]) { // Haven't been defined by user if (value === 'false') { defines[symbol] = false; } else if (value === 'true') { defines[symbol] = true; } else { defines[symbol] = value // If can parse to float ? (isNaN(parseFloat(value)) ? value.trim() : parseFloat(value)) : null; } } return ''; } }, /** * Clone a new shader * @return {clay.Shader} */ clone: function () { var code = shaderCodeCache[this._shaderID]; var shader = new Shader(code.vertex, code.fragment); return shader; } }; if (Object.defineProperty) { Object.defineProperty(Shader.prototype, 'shaderID', { get: function () { return this._shaderID; } }); Object.defineProperty(Shader.prototype, 'vertex', { get: function () { return this._vertexCode; } }); Object.defineProperty(Shader.prototype, 'fragment', { get: function () { return this._fragmentCode; } }); Object.defineProperty(Shader.prototype, 'uniforms', { get: function () { return this._uniformList; } }); } var importRegex = /(@import)\s*([0-9a-zA-Z_\-\.]*)/g; Shader.parseImport = function (shaderStr) { shaderStr = shaderStr.replace(importRegex, function (str, importSymbol, importName) { var str = Shader.source(importName); if (str) { // Recursively parse return Shader.parseImport(str); } else { console.error('Shader chunk "' + importName + '" not existed in library'); return ''; } }); return shaderStr; }; var exportRegex = /(@export)\s*([0-9a-zA-Z_\-\.]*)\s*\n([\s\S]*?)@end/g; /** * Import shader source * @param {string} shaderStr * @memberOf clay.Shader */ Shader['import'] = function (shaderStr) { shaderStr.replace(exportRegex, function (str, exportSymbol, exportName, code) { var code = code.replace(/(^[\s\t\xa0\u3000]+)|([\u3000\xa0\s\t]+\x24)/g, ''); if (code) { var parts = exportName.split('.'); var obj = Shader.codes; var i = 0; var key; while (i < parts.length - 1) { key = parts[i++]; if (!obj[key]) { obj[key] = {}; } obj = obj[key]; } key = parts[i]; obj[key] = code; } return code; }); }; /** * Library to store all the loaded shader codes * @type {Object} * @readOnly * @memberOf clay.Shader */ Shader.codes = {}; /** * Get shader source * @param {string} name * @return {string} */ Shader.source = function (name) { var parts = name.split('.'); var obj = Shader.codes; var i = 0; while (obj && i < parts.length) { var key = parts[i++]; obj = obj[key]; } if (typeof obj !== 'string') { // FIXME Use default instead console.error('Shader "' + name + '" not existed in library'); return ''; } return obj; }; var prezGlsl = "@export clay.prez.vertex\nuniform mat4 WVP : WORLDVIEWPROJECTION;\nattribute vec3 pos : POSITION;\nattribute vec2 uv : TEXCOORD_0;\n@import clay.chunk.skinning_header\nvarying vec2 v_Texcoord;\nvoid main()\n{\n vec3 P = pos;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n P = (skinMatrixWS * vec4(pos, 1.0)).xyz;\n#endif\n gl_Position = WVP * vec4(P, 1.0);\n v_Texcoord = uv;\n}\n@end\n@export clay.prez.fragment\nuniform sampler2D alphaMap;\nuniform float alphaCutoff: 0.0;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n if (alphaCutoff > 0.0) {\n if (texture2D(alphaMap, v_Texcoord).a <= alphaCutoff) {\n discard;\n }\n }\n gl_FragColor = vec4(0.0,0.0,0.0,1.0);\n}\n@end"; /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 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. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ /** * @class 4x4 Matrix * @name mat4 */ var mat4 = {}; /** * Creates a new identity mat4 * * @returns {mat4} a new 4x4 matrix */ mat4.create = function() { var out = new GLMAT_ARRAY_TYPE(16); out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = 1; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 1; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; }; /** * Creates a new mat4 initialized with values from an existing matrix * * @param {mat4} a matrix to clone * @returns {mat4} a new 4x4 matrix */ mat4.clone = function(a) { var out = new GLMAT_ARRAY_TYPE(16); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; out[9] = a[9]; out[10] = a[10]; out[11] = a[11]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; return out; }; /** * Copy the values from one mat4 to another * * @param {mat4} out the receiving matrix * @param {mat4} a the source matrix * @returns {mat4} out */ mat4.copy = function(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; out[9] = a[9]; out[10] = a[10]; out[11] = a[11]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; return out; }; /** * Set a mat4 to the identity matrix * * @param {mat4} out the receiving matrix * @returns {mat4} out */ mat4.identity = function(out) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = 1; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 1; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; }; /** * Transpose the values of a mat4 * * @param {mat4} out the receiving matrix * @param {mat4} a the source matrix * @returns {mat4} out */ mat4.transpose = function(out, a) { // If we are transposing ourselves we can skip a few steps but have to cache some values if (out === a) { var a01 = a[1], a02 = a[2], a03 = a[3], a12 = a[6], a13 = a[7], a23 = a[11]; out[1] = a[4]; out[2] = a[8]; out[3] = a[12]; out[4] = a01; out[6] = a[9]; out[7] = a[13]; out[8] = a02; out[9] = a12; out[11] = a[14]; out[12] = a03; out[13] = a13; out[14] = a23; } else { out[0] = a[0]; out[1] = a[4]; out[2] = a[8]; out[3] = a[12]; out[4] = a[1]; out[5] = a[5]; out[6] = a[9]; out[7] = a[13]; out[8] = a[2]; out[9] = a[6]; out[10] = a[10]; out[11] = a[14]; out[12] = a[3]; out[13] = a[7]; out[14] = a[11]; out[15] = a[15]; } return out; }; /** * Inverts a mat4 * * @param {mat4} out the receiving matrix * @param {mat4} a the source matrix * @returns {mat4} out */ mat4.invert = function(out, a) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15], b00 = a00 * a11 - a01 * a10, b01 = a00 * a12 - a02 * a10, b02 = a00 * a13 - a03 * a10, b03 = a01 * a12 - a02 * a11, b04 = a01 * a13 - a03 * a11, b05 = a02 * a13 - a03 * a12, b06 = a20 * a31 - a21 * a30, b07 = a20 * a32 - a22 * a30, b08 = a20 * a33 - a23 * a30, b09 = a21 * a32 - a22 * a31, b10 = a21 * a33 - a23 * a31, b11 = a22 * a33 - a23 * a32, // Calculate the determinant det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; if (!det) { return null; } det = 1.0 / det; out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; return out; }; /** * Calculates the adjugate of a mat4 * * @param {mat4} out the receiving matrix * @param {mat4} a the source matrix * @returns {mat4} out */ mat4.adjoint = function(out, a) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; out[0] = (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22)); out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22)); out[2] = (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12)); out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12)); out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22)); out[5] = (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22)); out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12)); out[7] = (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12)); out[8] = (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21)); out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21)); out[10] = (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11)); out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11)); out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21)); out[13] = (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21)); out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11)); out[15] = (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11)); return out; }; /** * Calculates the determinant of a mat4 * * @param {mat4} a the source matrix * @returns {Number} determinant of a */ mat4.determinant = function (a) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15], b00 = a00 * a11 - a01 * a10, b01 = a00 * a12 - a02 * a10, b02 = a00 * a13 - a03 * a10, b03 = a01 * a12 - a02 * a11, b04 = a01 * a13 - a03 * a11, b05 = a02 * a13 - a03 * a12, b06 = a20 * a31 - a21 * a30, b07 = a20 * a32 - a22 * a30, b08 = a20 * a33 - a23 * a30, b09 = a21 * a32 - a22 * a31, b10 = a21 * a33 - a23 * a31, b11 = a22 * a33 - a23 * a32; // Calculate the determinant return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; }; /** * Multiplies two mat4's * * @param {mat4} out the receiving matrix * @param {mat4} a the first operand * @param {mat4} b the second operand * @returns {mat4} out */ mat4.multiply = function (out, a, b) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; // Cache only the current line of the second matrix var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; out[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30; out[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31; out[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32; out[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33; b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7]; out[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30; out[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31; out[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32; out[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33; b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11]; out[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30; out[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31; out[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32; out[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33; b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15]; out[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30; out[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31; out[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32; out[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33; return out; }; /** * Multiplies two affine mat4's * Add by https://github.com/pissang * @param {mat4} out the receiving matrix * @param {mat4} a the first operand * @param {mat4} b the second operand * @returns {mat4} out */ mat4.multiplyAffine = function (out, a, b) { var a00 = a[0], a01 = a[1], a02 = a[2], a10 = a[4], a11 = a[5], a12 = a[6], a20 = a[8], a21 = a[9], a22 = a[10], a30 = a[12], a31 = a[13], a32 = a[14]; // Cache only the current line of the second matrix var b0 = b[0], b1 = b[1], b2 = b[2]; out[0] = b0*a00 + b1*a10 + b2*a20; out[1] = b0*a01 + b1*a11 + b2*a21; out[2] = b0*a02 + b1*a12 + b2*a22; // out[3] = 0; b0 = b[4]; b1 = b[5]; b2 = b[6]; out[4] = b0*a00 + b1*a10 + b2*a20; out[5] = b0*a01 + b1*a11 + b2*a21; out[6] = b0*a02 + b1*a12 + b2*a22; // out[7] = 0; b0 = b[8]; b1 = b[9]; b2 = b[10]; out[8] = b0*a00 + b1*a10 + b2*a20; out[9] = b0*a01 + b1*a11 + b2*a21; out[10] = b0*a02 + b1*a12 + b2*a22; // out[11] = 0; b0 = b[12]; b1 = b[13]; b2 = b[14]; out[12] = b0*a00 + b1*a10 + b2*a20 + a30; out[13] = b0*a01 + b1*a11 + b2*a21 + a31; out[14] = b0*a02 + b1*a12 + b2*a22 + a32; // out[15] = 1; return out; }; /** * Alias for {@link mat4.multiply} * @function */ mat4.mul = mat4.multiply; /** * Alias for {@link mat4.multiplyAffine} * @function */ mat4.mulAffine = mat4.multiplyAffine; /** * Translate a mat4 by the given vector * * @param {mat4} out the receiving matrix * @param {mat4} a the matrix to translate * @param {vec3} v vector to translate by * @returns {mat4} out */ mat4.translate = function (out, a, v) { var x = v[0], y = v[1], z = v[2], a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23; if (a === out) { out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; } else { a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03; out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13; out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23; out[12] = a00 * x + a10 * y + a20 * z + a[12]; out[13] = a01 * x + a11 * y + a21 * z + a[13]; out[14] = a02 * x + a12 * y + a22 * z + a[14]; out[15] = a03 * x + a13 * y + a23 * z + a[15]; } return out; }; /** * Scales the mat4 by the dimensions in the given vec3 * * @param {mat4} out the receiving matrix * @param {mat4} a the matrix to scale * @param {vec3} v the vec3 to scale the matrix by * @returns {mat4} out **/ mat4.scale = function(out, a, v) { var x = v[0], y = v[1], z = v[2]; out[0] = a[0] * x; out[1] = a[1] * x; out[2] = a[2] * x; out[3] = a[3] * x; out[4] = a[4] * y; out[5] = a[5] * y; out[6] = a[6] * y; out[7] = a[7] * y; out[8] = a[8] * z; out[9] = a[9] * z; out[10] = a[10] * z; out[11] = a[11] * z; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; return out; }; /** * Rotates a mat4 by the given angle * * @param {mat4} out the receiving matrix * @param {mat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @param {vec3} axis the axis to rotate around * @returns {mat4} out */ mat4.rotate = function (out, a, rad, axis) { var x = axis[0], y = axis[1], z = axis[2], len = Math.sqrt(x * x + y * y + z * z), s, c, t, a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, b00, b01, b02, b10, b11, b12, b20, b21, b22; if (Math.abs(len) < GLMAT_EPSILON) { return null; } len = 1 / len; x *= len; y *= len; z *= len; s = Math.sin(rad); c = Math.cos(rad); t = 1 - c; a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; // Construct the elements of the rotation matrix b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s; b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s; b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c; // Perform rotation-specific matrix multiplication out[0] = a00 * b00 + a10 * b01 + a20 * b02; out[1] = a01 * b00 + a11 * b01 + a21 * b02; out[2] = a02 * b00 + a12 * b01 + a22 * b02; out[3] = a03 * b00 + a13 * b01 + a23 * b02; out[4] = a00 * b10 + a10 * b11 + a20 * b12; out[5] = a01 * b10 + a11 * b11 + a21 * b12; out[6] = a02 * b10 + a12 * b11 + a22 * b12; out[7] = a03 * b10 + a13 * b11 + a23 * b12; out[8] = a00 * b20 + a10 * b21 + a20 * b22; out[9] = a01 * b20 + a11 * b21 + a21 * b22; out[10] = a02 * b20 + a12 * b21 + a22 * b22; out[11] = a03 * b20 + a13 * b21 + a23 * b22; if (a !== out) { // If the source and destination differ, copy the unchanged last row out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } return out; }; /** * Rotates a matrix by the given angle around the X axis * * @param {mat4} out the receiving matrix * @param {mat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ mat4.rotateX = function (out, a, rad) { var s = Math.sin(rad), c = Math.cos(rad), a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; if (a !== out) { // If the source and destination differ, copy the unchanged rows out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } // Perform axis-specific matrix multiplication out[4] = a10 * c + a20 * s; out[5] = a11 * c + a21 * s; out[6] = a12 * c + a22 * s; out[7] = a13 * c + a23 * s; out[8] = a20 * c - a10 * s; out[9] = a21 * c - a11 * s; out[10] = a22 * c - a12 * s; out[11] = a23 * c - a13 * s; return out; }; /** * Rotates a matrix by the given angle around the Y axis * * @param {mat4} out the receiving matrix * @param {mat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ mat4.rotateY = function (out, a, rad) { var s = Math.sin(rad), c = Math.cos(rad), a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; if (a !== out) { // If the source and destination differ, copy the unchanged rows out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } // Perform axis-specific matrix multiplication out[0] = a00 * c - a20 * s; out[1] = a01 * c - a21 * s; out[2] = a02 * c - a22 * s; out[3] = a03 * c - a23 * s; out[8] = a00 * s + a20 * c; out[9] = a01 * s + a21 * c; out[10] = a02 * s + a22 * c; out[11] = a03 * s + a23 * c; return out; }; /** * Rotates a matrix by the given angle around the Z axis * * @param {mat4} out the receiving matrix * @param {mat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ mat4.rotateZ = function (out, a, rad) { var s = Math.sin(rad), c = Math.cos(rad), a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; if (a !== out) { // If the source and destination differ, copy the unchanged last row out[8] = a[8]; out[9] = a[9]; out[10] = a[10]; out[11] = a[11]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } // Perform axis-specific matrix multiplication out[0] = a00 * c + a10 * s; out[1] = a01 * c + a11 * s; out[2] = a02 * c + a12 * s; out[3] = a03 * c + a13 * s; out[4] = a10 * c - a00 * s; out[5] = a11 * c - a01 * s; out[6] = a12 * c - a02 * s; out[7] = a13 * c - a03 * s; return out; }; /** * Creates a matrix from a quaternion rotation and vector translation * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.translate(dest, vec); * var quatMat = mat4.create(); * quat4.toMat4(quat, quatMat); * mat4.multiply(dest, quatMat); * * @param {mat4} out mat4 receiving operation result * @param {quat4} q Rotation quaternion * @param {vec3} v Translation vector * @returns {mat4} out */ mat4.fromRotationTranslation = function (out, q, v) { // Quaternion math var x = q[0], y = q[1], z = q[2], w = q[3], x2 = x + x, y2 = y + y, z2 = z + z, xx = x * x2, xy = x * y2, xz = x * z2, yy = y * y2, yz = y * z2, zz = z * z2, wx = w * x2, wy = w * y2, wz = w * z2; out[0] = 1 - (yy + zz); out[1] = xy + wz; out[2] = xz - wy; out[3] = 0; out[4] = xy - wz; out[5] = 1 - (xx + zz); out[6] = yz + wx; out[7] = 0; out[8] = xz + wy; out[9] = yz - wx; out[10] = 1 - (xx + yy); out[11] = 0; out[12] = v[0]; out[13] = v[1]; out[14] = v[2]; out[15] = 1; return out; }; mat4.fromQuat = function (out, q) { var x = q[0], y = q[1], z = q[2], w = q[3], x2 = x + x, y2 = y + y, z2 = z + z, xx = x * x2, yx = y * x2, yy = y * y2, zx = z * x2, zy = z * y2, zz = z * z2, wx = w * x2, wy = w * y2, wz = w * z2; out[0] = 1 - yy - zz; out[1] = yx + wz; out[2] = zx - wy; out[3] = 0; out[4] = yx - wz; out[5] = 1 - xx - zz; out[6] = zy + wx; out[7] = 0; out[8] = zx + wy; out[9] = zy - wx; out[10] = 1 - xx - yy; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; }; /** * Generates a frustum matrix with the given bounds * * @param {mat4} out mat4 frustum matrix will be written into * @param {Number} left Left bound of the frustum * @param {Number} right Right bound of the frustum * @param {Number} bottom Bottom bound of the frustum * @param {Number} top Top bound of the frustum * @param {Number} near Near bound of the frustum * @param {Number} far Far bound of the frustum * @returns {mat4} out */ mat4.frustum = function (out, left, right, bottom, top, near, far) { var rl = 1 / (right - left), tb = 1 / (top - bottom), nf = 1 / (near - far); out[0] = (near * 2) * rl; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = (near * 2) * tb; out[6] = 0; out[7] = 0; out[8] = (right + left) * rl; out[9] = (top + bottom) * tb; out[10] = (far + near) * nf; out[11] = -1; out[12] = 0; out[13] = 0; out[14] = (far * near * 2) * nf; out[15] = 0; return out; }; /** * Generates a perspective projection matrix with the given bounds * * @param {mat4} out mat4 frustum matrix will be written into * @param {number} fovy Vertical field of view in radians * @param {number} aspect Aspect ratio. typically viewport width/height * @param {number} near Near bound of the frustum * @param {number} far Far bound of the frustum * @returns {mat4} out */ mat4.perspective = function (out, fovy, aspect, near, far) { var f = 1.0 / Math.tan(fovy / 2), nf = 1 / (near - far); out[0] = f / aspect; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = f; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = (far + near) * nf; out[11] = -1; out[12] = 0; out[13] = 0; out[14] = (2 * far * near) * nf; out[15] = 0; return out; }; /** * Generates a orthogonal projection matrix with the given bounds * * @param {mat4} out mat4 frustum matrix will be written into * @param {number} left Left bound of the frustum * @param {number} right Right bound of the frustum * @param {number} bottom Bottom bound of the frustum * @param {number} top Top bound of the frustum * @param {number} near Near bound of the frustum * @param {number} far Far bound of the frustum * @returns {mat4} out */ mat4.ortho = function (out, left, right, bottom, top, near, far) { var lr = 1 / (left - right), bt = 1 / (bottom - top), nf = 1 / (near - far); out[0] = -2 * lr; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = -2 * bt; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 2 * nf; out[11] = 0; out[12] = (left + right) * lr; out[13] = (top + bottom) * bt; out[14] = (far + near) * nf; out[15] = 1; return out; }; /** * Generates a look-at matrix with the given eye position, focal point, and up axis * * @param {mat4} out mat4 frustum matrix will be written into * @param {vec3} eye Position of the viewer * @param {vec3} center Point the viewer is looking at * @param {vec3} up vec3 pointing up * @returns {mat4} out */ mat4.lookAt = function (out, eye, center, up) { var x0, x1, x2, y0, y1, y2, z0, z1, z2, len, eyex = eye[0], eyey = eye[1], eyez = eye[2], upx = up[0], upy = up[1], upz = up[2], centerx = center[0], centery = center[1], centerz = center[2]; if (Math.abs(eyex - centerx) < GLMAT_EPSILON && Math.abs(eyey - centery) < GLMAT_EPSILON && Math.abs(eyez - centerz) < GLMAT_EPSILON) { return mat4.identity(out); } z0 = eyex - centerx; z1 = eyey - centery; z2 = eyez - centerz; len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2); z0 *= len; z1 *= len; z2 *= len; x0 = upy * z2 - upz * z1; x1 = upz * z0 - upx * z2; x2 = upx * z1 - upy * z0; len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2); if (!len) { x0 = 0; x1 = 0; x2 = 0; } else { len = 1 / len; x0 *= len; x1 *= len; x2 *= len; } y0 = z1 * x2 - z2 * x1; y1 = z2 * x0 - z0 * x2; y2 = z0 * x1 - z1 * x0; len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2); if (!len) { y0 = 0; y1 = 0; y2 = 0; } else { len = 1 / len; y0 *= len; y1 *= len; y2 *= len; } out[0] = x0; out[1] = y0; out[2] = z0; out[3] = 0; out[4] = x1; out[5] = y1; out[6] = z1; out[7] = 0; out[8] = x2; out[9] = y2; out[10] = z2; out[11] = 0; out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); out[15] = 1; return out; }; /** * Returns Frobenius norm of a mat4 * * @param {mat4} a the matrix to calculate Frobenius norm of * @returns {Number} Frobenius norm */ mat4.frob = function (a) { return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2) + Math.pow(a[9], 2) + Math.pow(a[10], 2) + Math.pow(a[11], 2) + Math.pow(a[12], 2) + Math.pow(a[13], 2) + Math.pow(a[14], 2) + Math.pow(a[15], 2) )) }; // TODO Resources like shader, texture, geometry reference management // Trace and find out which shader, texture, geometry can be destroyed // Light header Shader['import'](prezGlsl); var mat4Create = mat4.create; var errorShader = {}; function defaultGetMaterial(renderable) { return renderable.material; } function defaultGetUniform(renderable, material, symbol) { return material.uniforms[symbol].value; } function defaultIsMaterialChanged(renderabled, prevRenderable, material, prevMaterial) { return material !== prevMaterial; } function defaultIfRender(renderable) { return true; } function noop$1() {} var attributeBufferTypeMap = { float: glenum.FLOAT, byte: glenum.BYTE, ubyte: glenum.UNSIGNED_BYTE, short: glenum.SHORT, ushort: glenum.UNSIGNED_SHORT }; function VertexArrayObject(availableAttributes, availableAttributeSymbols, indicesBuffer) { this.availableAttributes = availableAttributes; this.availableAttributeSymbols = availableAttributeSymbols; this.indicesBuffer = indicesBuffer; this.vao = null; } function PlaceHolderTexture(renderer) { var blankCanvas; var webglTexture; this.bind = function (renderer) { if (!blankCanvas) { // TODO Environment not support createCanvas. blankCanvas = vendor.createCanvas(); blankCanvas.width = blankCanvas.height = 1; blankCanvas.getContext('2d'); } var gl = renderer.gl; var firstBind = !webglTexture; if (firstBind) { webglTexture = gl.createTexture(); } gl.bindTexture(gl.TEXTURE_2D, webglTexture); if (firstBind) { gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, blankCanvas); } }; this.unbind = function (renderer) { renderer.gl.bindTexture(renderer.gl.TEXTURE_2D, null); }; this.isRenderable = function () { return true; }; } /** * @constructor clay.Renderer * @extends clay.core.Base */ var Renderer = Base.extend(function () { return /** @lends clay.Renderer# */ { /** * @type {HTMLCanvasElement} * @readonly */ canvas: null, /** * Canvas width, set by resize method * @type {number} * @private */ _width: 100, /** * Canvas width, set by resize method * @type {number} * @private */ _height: 100, /** * Device pixel ratio, set by setDevicePixelRatio method * Specially for high defination display * @see http://www.khronos.org/webgl/wiki/HandlingHighDPI * @type {number} * @private */ devicePixelRatio: (typeof window !== 'undefined' && window.devicePixelRatio) || 1.0, /** * Clear color * @type {number[]} */ clearColor: [0.0, 0.0, 0.0, 0.0], /** * Default: * _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT | _gl.STENCIL_BUFFER_BIT * @type {number} */ clearBit: 17664, // Settings when getting context // http://www.khronos.org/registry/webgl/specs/latest/#2.4 /** * If enable alpha, default true * @type {boolean} */ alpha: true, /** * If enable depth buffer, default true * @type {boolean} */ depth: true, /** * If enable stencil buffer, default false * @type {boolean} */ stencil: false, /** * If enable antialias, default true * @type {boolean} */ antialias: true, /** * If enable premultiplied alpha, default true * @type {boolean} */ premultipliedAlpha: true, /** * If preserve drawing buffer, default false * @type {boolean} */ preserveDrawingBuffer: false, /** * If throw context error, usually turned on in debug mode * @type {boolean} */ throwError: true, /** * WebGL Context created from given canvas * @type {WebGLRenderingContext} */ gl: null, /** * Renderer viewport, read-only, can be set by setViewport method * @type {Object} */ viewport: {}, // Set by FrameBuffer#bind __currentFrameBuffer: null, _viewportStack: [], _clearStack: [], _sceneRendering: null }; }, function () { if (!this.canvas) { this.canvas = vendor.createCanvas(); } var canvas = this.canvas; try { var opts = { alpha: this.alpha, depth: this.depth, stencil: this.stencil, antialias: this.antialias, premultipliedAlpha: this.premultipliedAlpha, preserveDrawingBuffer: this.preserveDrawingBuffer }; this.gl = canvas.getContext('webgl', opts) || canvas.getContext('experimental-webgl', opts); if (!this.gl) { throw new Error(); } this._glinfo = new GLInfo(this.gl); if (this.gl.targetRenderer) { console.error('Already created a renderer'); } this.gl.targetRenderer = this; this.resize(); } catch (e) { throw 'Error creating WebGL Context ' + e; } // Init managers this._programMgr = new ProgramManager(this); this._placeholderTexture = new PlaceHolderTexture(this); }, /** @lends clay.Renderer.prototype. **/ { /** * Resize the canvas * @param {number} width * @param {number} height */ resize: function(width, height) { var canvas = this.canvas; // http://www.khronos.org/webgl/wiki/HandlingHighDPI // set the display size of the canvas. var dpr = this.devicePixelRatio; if (width != null) { canvas.style.width = width + 'px'; canvas.style.height = height + 'px'; // set the size of the drawingBuffer canvas.width = width * dpr; canvas.height = height * dpr; this._width = width; this._height = height; } else { this._width = canvas.width / dpr; this._height = canvas.height / dpr; } this.setViewport(0, 0, this._width, this._height); }, /** * Get renderer width * @return {number} */ getWidth: function () { return this._width; }, /** * Get renderer height * @return {number} */ getHeight: function () { return this._height; }, /** * Get viewport aspect, * @return {number} */ getViewportAspect: function () { var viewport = this.viewport; return viewport.width / viewport.height; }, /** * Set devicePixelRatio * @param {number} devicePixelRatio */ setDevicePixelRatio: function(devicePixelRatio) { this.devicePixelRatio = devicePixelRatio; this.resize(this._width, this._height); }, /** * Get devicePixelRatio * @param {number} devicePixelRatio */ getDevicePixelRatio: function () { return this.devicePixelRatio; }, /** * Get WebGL extension * @param {string} name * @return {object} */ getGLExtension: function (name) { return this._glinfo.getExtension(name); }, /** * Get WebGL parameter * @param {string} name * @return {*} */ getGLParameter: function (name) { return this._glinfo.getParameter(name); }, /** * Set rendering viewport * @param {number|Object} x * @param {number} [y] * @param {number} [width] * @param {number} [height] * @param {number} [devicePixelRatio] * Defaultly use the renderere devicePixelRatio * It needs to be 1 when setViewport is called by frameBuffer * * @example * setViewport(0,0,width,height,1) * setViewport({ * x: 0, * y: 0, * width: width, * height: height, * devicePixelRatio: 1 * }) */ setViewport: function (x, y, width, height, dpr) { if (typeof x === 'object') { var obj = x; x = obj.x; y = obj.y; width = obj.width; height = obj.height; dpr = obj.devicePixelRatio; } dpr = dpr || this.devicePixelRatio; this.gl.viewport( x * dpr, y * dpr, width * dpr, height * dpr ); // Use a fresh new object, not write property. this.viewport = { x: x, y: y, width: width, height: height, devicePixelRatio: dpr }; }, /** * Push current viewport into a stack */ saveViewport: function () { this._viewportStack.push(this.viewport); }, /** * Pop viewport from stack, restore in the renderer */ restoreViewport: function () { if (this._viewportStack.length > 0) { this.setViewport(this._viewportStack.pop()); } }, /** * Push current clear into a stack */ saveClear: function () { this._clearStack.push({ clearBit: this.clearBit, clearColor: this.clearColor }); }, /** * Pop clear from stack, restore in the renderer */ restoreClear: function () { if (this._clearStack.length > 0) { var opt = this._clearStack.pop(); this.clearColor = opt.clearColor; this.clearBit = opt.clearBit; } }, bindSceneRendering: function (scene) { this._sceneRendering = scene; }, /** * Render the scene in camera to the screen or binded offline framebuffer * @param {clay.Scene} scene * @param {clay.Camera} camera * @param {boolean} [notUpdateScene] If not call the scene.update methods in the rendering, default true * @param {boolean} [preZ] If use preZ optimization, default false * @return {IRenderInfo} */ render: function(scene, camera, notUpdateScene, preZ) { var _gl = this.gl; var clearColor = this.clearColor; if (this.clearBit) { // Must set depth and color mask true before clear _gl.colorMask(true, true, true, true); _gl.depthMask(true); var viewport = this.viewport; var needsScissor = false; var viewportDpr = viewport.devicePixelRatio; if (viewport.width !== this._width || viewport.height !== this._height || (viewportDpr && viewportDpr !== this.devicePixelRatio) || viewport.x || viewport.y ) { needsScissor = true; // http://stackoverflow.com/questions/11544608/how-to-clear-a-rectangle-area-in-webgl // Only clear the viewport _gl.enable(_gl.SCISSOR_TEST); _gl.scissor(viewport.x * viewportDpr, viewport.y * viewportDpr, viewport.width * viewportDpr, viewport.height * viewportDpr); } _gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); _gl.clear(this.clearBit); if (needsScissor) { _gl.disable(_gl.SCISSOR_TEST); } } // If the scene have been updated in the prepass like shadow map // There is no need to update it again if (!notUpdateScene) { scene.update(false); } scene.updateLights(); camera = camera || scene.getMainCamera(); if (!camera) { console.error('Can\'t find camera in the scene.'); return; } camera.update(); var renderList = scene.updateRenderList(camera, true); this._sceneRendering = scene; var opaqueList = renderList.opaque; var transparentList = renderList.transparent; var sceneMaterial = scene.material; scene.trigger('beforerender', this, scene, camera, renderList); // Render pre z if (preZ) { this.renderPreZ(opaqueList, scene, camera); _gl.depthFunc(_gl.LEQUAL); } else { _gl.depthFunc(_gl.LESS); } // Update the depth of transparent list. var worldViewMat = mat4Create(); var posViewSpace = vec3.create(); for (var i = 0; i < transparentList.length; i++) { var renderable = transparentList[i]; mat4.multiplyAffine(worldViewMat, camera.viewMatrix.array, renderable.worldTransform.array); vec3.transformMat4(posViewSpace, renderable.position.array, worldViewMat); renderable.__depth = posViewSpace[2]; } // Render opaque list this.renderPass(opaqueList, camera, { getMaterial: function (renderable) { return sceneMaterial || renderable.material; }, sortCompare: this.opaqueSortCompare }); this.renderPass(transparentList, camera, { getMaterial: function (renderable) { return sceneMaterial || renderable.material; }, sortCompare: this.transparentSortCompare }); scene.trigger('afterrender', this, scene, camera, renderList); // Cleanup this._sceneRendering = null; }, getProgram: function (renderable, renderMaterial, scene) { renderMaterial = renderMaterial || renderable.material; return this._programMgr.getProgram(renderable, renderMaterial, scene); }, validateProgram: function (program) { if (program.__error) { var errorMsg = program.__error; if (errorShader[program.__uid__]) { return; } errorShader[program.__uid__] = true; if (this.throwError) { throw new Error(errorMsg); } else { this.trigger('error', errorMsg); } } }, updatePrograms: function (list, scene, passConfig) { var getMaterial = (passConfig && passConfig.getMaterial) || defaultGetMaterial; scene = scene || null; for (var i = 0; i < list.length; i++) { var renderable = list[i]; var renderMaterial = getMaterial.call(this, renderable); if (i > 0) { var prevRenderable = list[i - 1]; var prevJointsLen = prevRenderable.joints ? prevRenderable.joints.length : 0; var jointsLen = renderable.joints ? renderable.joints.length : 0; // Keep program not change if joints, material, lightGroup are same of two renderables. if (jointsLen === prevJointsLen && renderable.material === prevRenderable.material && renderable.lightGroup === prevRenderable.lightGroup ) { renderable.__program = prevRenderable.__program; continue; } } var program = this._programMgr.getProgram(renderable, renderMaterial, scene); this.validateProgram(program); renderable.__program = program; } }, /** * Render a single renderable list in camera in sequence * @param {clay.Renderable[]} list List of all renderables. * @param {clay.Camera} [camera] Camera provide view matrix and porjection matrix. It can be null. * @param {Object} [passConfig] * @param {Function} [passConfig.getMaterial] Get renderable material. * @param {Function} [passConfig.getUniform] Get material uniform value. * @param {Function} [passConfig.isMaterialChanged] If material changed. * @param {Function} [passConfig.beforeRender] Before render each renderable. * @param {Function} [passConfig.afterRender] After render each renderable * @param {Function} [passConfig.ifRender] If render the renderable. * @param {Function} [passConfig.sortCompare] Sort compare function. * @return {IRenderInfo} */ renderPass: function(list, camera, passConfig) { this.trigger('beforerenderpass', this, list, camera, passConfig); passConfig = passConfig || {}; passConfig.getMaterial = passConfig.getMaterial || defaultGetMaterial; passConfig.getUniform = passConfig.getUniform || defaultGetUniform; // PENDING Better solution? passConfig.isMaterialChanged = passConfig.isMaterialChanged || defaultIsMaterialChanged; passConfig.beforeRender = passConfig.beforeRender || noop$1; passConfig.afterRender = passConfig.afterRender || noop$1; var ifRenderObject = passConfig.ifRender || defaultIfRender; this.updatePrograms(list, this._sceneRendering, passConfig); if (passConfig.sortCompare) { list.sort(passConfig.sortCompare); } // Some common builtin uniforms var viewport = this.viewport; var vDpr = viewport.devicePixelRatio; var viewportUniform = [ viewport.x * vDpr, viewport.y * vDpr, viewport.width * vDpr, viewport.height * vDpr ]; var windowDpr = this.devicePixelRatio; var windowSizeUniform = this.__currentFrameBuffer ? [this.__currentFrameBuffer.getTextureWidth(), this.__currentFrameBuffer.getTextureHeight()] : [this._width * windowDpr, this._height * windowDpr]; // DEPRECATED var viewportSizeUniform = [ viewportUniform[2], viewportUniform[3] ]; var time = Date.now(); // Calculate view and projection matrix if (camera) { mat4.copy(matrices.VIEW, camera.viewMatrix.array); mat4.copy(matrices.PROJECTION, camera.projectionMatrix.array); mat4.copy(matrices.VIEWINVERSE, camera.worldTransform.array); } else { mat4.identity(matrices.VIEW); mat4.identity(matrices.PROJECTION); mat4.identity(matrices.VIEWINVERSE); } mat4.multiply(matrices.VIEWPROJECTION, matrices.PROJECTION, matrices.VIEW); mat4.invert(matrices.PROJECTIONINVERSE, matrices.PROJECTION); mat4.invert(matrices.VIEWPROJECTIONINVERSE, matrices.VIEWPROJECTION); var _gl = this.gl; var scene = this._sceneRendering; var prevMaterial; var prevProgram; var prevRenderable; // Status var depthTest, depthMask; var culling, cullFace, frontFace; var transparent; var drawID; var currentVAO; var materialTakesTextureSlot; // var vaoExt = this.getGLExtension('OES_vertex_array_object'); // not use vaoExt, some platforms may mess it up. var vaoExt = null; for (var i = 0; i < list.length; i++) { var renderable = list[i]; var isSceneNode = renderable.worldTransform != null; var worldM; if (!ifRenderObject(renderable)) { continue; } // Skinned mesh will transformed to joint space. Ignore the mesh transform if (isSceneNode) { worldM = (renderable.isSkinnedMesh && renderable.isSkinnedMesh()) ? matrices.IDENTITY : renderable.worldTransform.array; } var geometry = renderable.geometry; var material = passConfig.getMaterial.call(this, renderable); var program = renderable.__program; var shader = material.shader; var currentDrawID = geometry.__uid__ + '-' + program.__uid__; var drawIDChanged = currentDrawID !== drawID; drawID = currentDrawID; if (drawIDChanged && vaoExt) { // TODO Seems need to be bound to null immediately (or before bind another program?) if vao is changed vaoExt.bindVertexArrayOES(null); } if (isSceneNode) { mat4.copy(matrices.WORLD, worldM); mat4.multiply(matrices.WORLDVIEWPROJECTION, matrices.VIEWPROJECTION, worldM); mat4.multiplyAffine(matrices.WORLDVIEW, matrices.VIEW, worldM); if (shader.matrixSemantics.WORLDINVERSE || shader.matrixSemantics.WORLDINVERSETRANSPOSE) { mat4.invert(matrices.WORLDINVERSE, worldM); } if (shader.matrixSemantics.WORLDVIEWINVERSE || shader.matrixSemantics.WORLDVIEWINVERSETRANSPOSE) { mat4.invert(matrices.WORLDVIEWINVERSE, matrices.WORLDVIEW); } if (shader.matrixSemantics.WORLDVIEWPROJECTIONINVERSE || shader.matrixSemantics.WORLDVIEWPROJECTIONINVERSETRANSPOSE) { mat4.invert(matrices.WORLDVIEWPROJECTIONINVERSE, matrices.WORLDVIEWPROJECTION); } } // Before render hook renderable.beforeRender && renderable.beforeRender(this); passConfig.beforeRender.call(this, renderable, material, prevMaterial); var programChanged = program !== prevProgram; if (programChanged) { // Set lights number program.bind(this); // Set some common uniforms program.setUniformOfSemantic(_gl, 'VIEWPORT', viewportUniform); program.setUniformOfSemantic(_gl, 'WINDOW_SIZE', windowSizeUniform); if (camera) { program.setUniformOfSemantic(_gl, 'NEAR', camera.near); program.setUniformOfSemantic(_gl, 'FAR', camera.far); } program.setUniformOfSemantic(_gl, 'DEVICEPIXELRATIO', vDpr); program.setUniformOfSemantic(_gl, 'TIME', time); // DEPRECATED program.setUniformOfSemantic(_gl, 'VIEWPORT_SIZE', viewportSizeUniform); // Set lights uniforms // TODO needs optimized if (scene) { scene.setLightUniforms(program, renderable.lightGroup, this); } } else { program = prevProgram; } // Program changes also needs reset the materials. if (programChanged || passConfig.isMaterialChanged( renderable, prevRenderable, material, prevMaterial )) { if (material.depthTest !== depthTest) { material.depthTest ? _gl.enable(_gl.DEPTH_TEST) : _gl.disable(_gl.DEPTH_TEST); depthTest = material.depthTest; } if (material.depthMask !== depthMask) { _gl.depthMask(material.depthMask); depthMask = material.depthMask; } if (material.transparent !== transparent) { material.transparent ? _gl.enable(_gl.BLEND) : _gl.disable(_gl.BLEND); transparent = material.transparent; } // TODO cache blending if (material.transparent) { if (material.blend) { material.blend(_gl); } else { // Default blend function _gl.blendEquationSeparate(_gl.FUNC_ADD, _gl.FUNC_ADD); _gl.blendFuncSeparate(_gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA); } } materialTakesTextureSlot = this._bindMaterial( renderable, material, program, prevRenderable || null, prevMaterial || null, prevProgram || null, passConfig.getUniform ); prevMaterial = material; } var matrixSemanticKeys = shader.matrixSemanticKeys; if (isSceneNode) { for (var k = 0; k < matrixSemanticKeys.length; k++) { var semantic = matrixSemanticKeys[k]; var semanticInfo = shader.matrixSemantics[semantic]; var matrix = matrices[semantic]; if (semanticInfo.isTranspose) { var matrixNoTranspose = matrices[semanticInfo.semanticNoTranspose]; mat4.transpose(matrix, matrixNoTranspose); } program.setUniform(_gl, semanticInfo.type, semanticInfo.symbol, matrix); } } if (renderable.cullFace !== cullFace) { cullFace = renderable.cullFace; _gl.cullFace(cullFace); } if (renderable.frontFace !== frontFace) { frontFace = renderable.frontFace; _gl.frontFace(frontFace); } if (renderable.culling !== culling) { culling = renderable.culling; culling ? _gl.enable(_gl.CULL_FACE) : _gl.disable(_gl.CULL_FACE); } // TODO Not update skeleton in each renderable. this._updateSkeleton(renderable, program, materialTakesTextureSlot); if (drawIDChanged) { currentVAO = this._bindVAO(vaoExt, shader, geometry, program); } this._renderObject(renderable, currentVAO); // After render hook passConfig.afterRender(this, renderable); renderable.afterRender && renderable.afterRender(this); prevProgram = program; prevRenderable = renderable; } // TODO Seems need to be bound to null immediately if vao is changed? if (vaoExt) { vaoExt.bindVertexArrayOES(null); } this.trigger('afterrenderpass', this, list, camera, passConfig); }, getMaxJointNumber: function () { return this._glinfo.getMaxJointNumber(); }, _updateSkeleton: function (object, program, slot) { var _gl = this.gl; var skeleton = object.skeleton; // Set pose matrices of skinned mesh if (skeleton) { // TODO Update before culling. skeleton.update(); if (object.joints.length > this._glinfo.getMaxJointNumber()) { var skinMatricesTexture = skeleton.getSubSkinMatricesTexture(object.__uid__, object.joints); program.useTextureSlot(this, skinMatricesTexture, slot); program.setUniform(_gl, '1i', 'skinMatricesTexture', slot); program.setUniform(_gl, '1f', 'skinMatricesTextureSize', skinMatricesTexture.width); } else { var skinMatricesArray = skeleton.getSubSkinMatrices(object.__uid__, object.joints); program.setUniformOfSemantic(_gl, 'SKIN_MATRIX', skinMatricesArray); } } }, _renderObject: function (renderable, vao) { var _gl = this.gl; var geometry = renderable.geometry; var glDrawMode = renderable.mode; if (glDrawMode == null) { glDrawMode = 0x0004; } // if (glDrawMode === glenum.LINES || glDrawMode === glenum.LINE_STRIP || glDrawMode === glenum.LINE_LOOP) { // _gl.lineWidth(this.lineWidth); // } if (vao.indicesBuffer) { var uintExt = this.getGLExtension('OES_element_index_uint'); var useUintExt = uintExt && (geometry.indices instanceof Uint32Array); var indicesType = useUintExt ? _gl.UNSIGNED_INT : _gl.UNSIGNED_SHORT; _gl.drawElements(glDrawMode, vao.indicesBuffer.count, indicesType, 0); } else { // FIXME Use vertex number in buffer // vertexCount may get the wrong value when geometry forget to mark dirty after update _gl.drawArrays(glDrawMode, 0, geometry.vertexCount); } }, _bindMaterial: function (renderable, material, program, prevRenderable, prevMaterial, prevProgram, getUniformValue) { var _gl = this.gl; // PENDING Same texture in different material take different slot? // May use shader of other material if shader code are same var sameProgram = prevProgram === program; var currentTextureSlot = program.currentTextureSlot(); var enabledUniforms = material.getEnabledUniforms(); var textureUniforms = material.getTextureUniforms(); var placeholderTexture = this._placeholderTexture; for (var u = 0; u < textureUniforms.length; u++) { var symbol = textureUniforms[u]; var uniformValue = getUniformValue(renderable, material, symbol); var uniformType = material.uniforms[symbol].type; // Not use `instanceof` to determine if a value is texture in Material#bind. // Use type instead, in some case texture may be in different namespaces. // TODO Duck type validate. if (uniformType === 't' && uniformValue) { // Reset slot uniformValue.__slot = -1; } else if (uniformType === 'tv') { for (var i = 0; i < uniformValue.length; i++) { if (uniformValue[i]) { uniformValue[i].__slot = -1; } } } } placeholderTexture.__slot = -1; // Set uniforms for (var u = 0; u < enabledUniforms.length; u++) { var symbol = enabledUniforms[u]; var uniform = material.uniforms[symbol]; var uniformValue = getUniformValue(renderable, material, symbol); var uniformType = uniform.type; var isTexture = uniformType === 't'; if (isTexture) { if (!uniformValue || !uniformValue.isRenderable()) { uniformValue = placeholderTexture; } } // PENDING // When binding two materials with the same shader // Many uniforms will be be set twice even if they have the same value // So add a evaluation to see if the uniform is really needed to be set if (prevMaterial && sameProgram) { var prevUniformValue = getUniformValue(prevRenderable, prevMaterial, symbol); if (isTexture) { if (!prevUniformValue || !prevUniformValue.isRenderable()) { prevUniformValue = placeholderTexture; } } if (prevUniformValue === uniformValue) { if (isTexture) { // Still take the slot to make sure same texture in different materials have same slot. program.takeCurrentTextureSlot(this, null); } else if (uniformType === 'tv' && uniformValue) { for (var i = 0; i < uniformValue.length; i++) { program.takeCurrentTextureSlot(this, null); } } continue; } } if (uniformValue == null) { continue; } else if (isTexture) { if (uniformValue.__slot < 0) { var slot = program.currentTextureSlot(); var res = program.setUniform(_gl, '1i', symbol, slot); if (res) { // Texture uniform is enabled program.takeCurrentTextureSlot(this, uniformValue); uniformValue.__slot = slot; } } // Multiple uniform use same texture.. else { program.setUniform(_gl, '1i', symbol, uniformValue.__slot); } } else if (Array.isArray(uniformValue)) { if (uniformValue.length === 0) { continue; } // Texture Array if (uniformType === 'tv') { if (!program.hasUniform(symbol)) { continue; } var arr = []; for (var i = 0; i < uniformValue.length; i++) { var texture = uniformValue[i]; if (texture.__slot < 0) { var slot = program.currentTextureSlot(); arr.push(slot); program.takeCurrentTextureSlot(this, texture); texture.__slot = slot; } else { arr.push(texture.__slot); } } program.setUniform(_gl, '1iv', symbol, arr); } else { program.setUniform(_gl, uniform.type, symbol, uniformValue); } } else{ program.setUniform(_gl, uniform.type, symbol, uniformValue); } } var newSlot = program.currentTextureSlot(); // Texture slot maybe used out of material. program.resetTextureSlot(currentTextureSlot); return newSlot; }, _bindVAO: function (vaoExt, shader, geometry, program) { var isStatic = !geometry.dynamic; var _gl = this.gl; var vaoId = this.__uid__ + '-' + program.__uid__; var vao = geometry.__vaoCache[vaoId]; if (!vao) { var chunks = geometry.getBufferChunks(this); if (!chunks || !chunks.length) { // Empty mesh return; } var chunk = chunks[0]; var attributeBuffers = chunk.attributeBuffers; var indicesBuffer = chunk.indicesBuffer; var availableAttributes = []; var availableAttributeSymbols = []; for (var a = 0; a < attributeBuffers.length; a++) { var attributeBufferInfo = attributeBuffers[a]; var name = attributeBufferInfo.name; var semantic = attributeBufferInfo.semantic; var symbol; if (semantic) { var semanticInfo = shader.attributeSemantics[semantic]; symbol = semanticInfo && semanticInfo.symbol; } else { symbol = name; } if (symbol && program.attributes[symbol]) { availableAttributes.push(attributeBufferInfo); availableAttributeSymbols.push(symbol); } } vao = new VertexArrayObject( availableAttributes, availableAttributeSymbols, indicesBuffer ); if (isStatic) { geometry.__vaoCache[vaoId] = vao; } } var needsBindAttributes = true; // Create vertex object array cost a lot // So we don't use it on the dynamic object if (vaoExt && isStatic) { // Use vertex array object // http://blog.tojicode.com/2012/10/oesvertexarrayobject-extension.html if (vao.vao == null) { vao.vao = vaoExt.createVertexArrayOES(); } else { needsBindAttributes = false; } vaoExt.bindVertexArrayOES(vao.vao); } var availableAttributes = vao.availableAttributes; var indicesBuffer = vao.indicesBuffer; if (needsBindAttributes) { var locationList = program.enableAttributes(this, vao.availableAttributeSymbols, (vaoExt && isStatic && vao)); // Setting attributes; for (var a = 0; a < availableAttributes.length; a++) { var location = locationList[a]; if (location === -1) { continue; } var attributeBufferInfo = availableAttributes[a]; var buffer = attributeBufferInfo.buffer; var size = attributeBufferInfo.size; var glType = attributeBufferTypeMap[attributeBufferInfo.type] || _gl.FLOAT; _gl.bindBuffer(_gl.ARRAY_BUFFER, buffer); _gl.vertexAttribPointer(location, size, glType, false, 0, 0); } if (geometry.isUseIndices()) { _gl.bindBuffer(_gl.ELEMENT_ARRAY_BUFFER, indicesBuffer.buffer); } } return vao; }, renderPreZ: function (list, scene, camera) { var _gl = this.gl; var preZPassMaterial = this._prezMaterial || new Material({ shader: new Shader(Shader.source('clay.prez.vertex'), Shader.source('clay.prez.fragment')) }); this._prezMaterial = preZPassMaterial; _gl.colorMask(false, false, false, false); _gl.depthMask(true); // Status this.renderPass(list, camera, { ifRender: function (renderable) { return !renderable.ignorePreZ; }, isMaterialChanged: function (renderable, prevRenderable) { var matA = renderable.material; var matB = prevRenderable.material; return matA.get('diffuseMap') !== matB.get('diffuseMap') || (matA.get('alphaCutoff') || 0) !== (matB.get('alphaCutoff') || 0); }, getUniform: function (renderable, depthMaterial, symbol) { if (symbol === 'alphaMap') { return renderable.material.get('diffuseMap'); } else if (symbol === 'alphaCutoff') { if (renderable.material.isDefined('fragment', 'ALPHA_TEST') && renderable.material.get('diffuseMap') ) { var alphaCutoff = renderable.material.get('alphaCutoff'); return alphaCutoff || 0; } return 0; } else { return depthMaterial.get(symbol); } }, getMaterial: function () { return preZPassMaterial; }, sort: this.opaqueSortCompare }); _gl.colorMask(true, true, true, true); _gl.depthMask(true); }, /** * Dispose given scene, including all geometris, textures and shaders in the scene * @param {clay.Scene} scene */ disposeScene: function(scene) { this.disposeNode(scene, true, true); scene.dispose(); }, /** * Dispose given node, including all geometries, textures and shaders attached on it or its descendant * @param {clay.Node} node * @param {boolean} [disposeGeometry=false] If dispose the geometries used in the descendant mesh * @param {boolean} [disposeTexture=false] If dispose the textures used in the descendant mesh */ disposeNode: function(root, disposeGeometry, disposeTexture) { // Dettached from parent if (root.getParent()) { root.getParent().remove(root); } var disposedMap = {}; root.traverse(function(node) { var material = node.material; if (node.geometry && disposeGeometry) { node.geometry.dispose(this); } if (disposeTexture && material && !disposedMap[material.__uid__]) { var textureUniforms = material.getTextureUniforms(); for (var u = 0; u < textureUniforms.length; u++) { var uniformName = textureUniforms[u]; var val = material.uniforms[uniformName].value; var uniformType = material.uniforms[uniformName].type; if (!val) { continue; } if (uniformType === 't') { val.dispose && val.dispose(this); } else if (uniformType === 'tv') { for (var k = 0; k < val.length; k++) { if (val[k]) { val[k].dispose && val[k].dispose(this); } } } } disposedMap[material.__uid__] = true; } // Particle system and AmbientCubemap light need to dispose if (node.dispose) { node.dispose(this); } }, this); }, /** * Dispose given geometry * @param {clay.Geometry} geometry */ disposeGeometry: function(geometry) { geometry.dispose(this); }, /** * Dispose given texture * @param {clay.Texture} texture */ disposeTexture: function(texture) { texture.dispose(this); }, /** * Dispose given frame buffer * @param {clay.FrameBuffer} frameBuffer */ disposeFrameBuffer: function(frameBuffer) { frameBuffer.dispose(this); }, /** * Dispose renderer */ dispose: function () {}, /** * Convert screen coords to normalized device coordinates(NDC) * Screen coords can get from mouse event, it is positioned relative to canvas element * NDC can be used in ray casting with Camera.prototype.castRay methods * * @param {number} x * @param {number} y * @param {clay.Vector2} [out] * @return {clay.Vector2} */ screenToNDC: function(x, y, out) { if (!out) { out = new Vector2(); } // Invert y; y = this._height - y; var viewport = this.viewport; var arr = out.array; arr[0] = (x - viewport.x) / viewport.width; arr[0] = arr[0] * 2 - 1; arr[1] = (y - viewport.y) / viewport.height; arr[1] = arr[1] * 2 - 1; return out; } }); /** * Opaque renderables compare function * @param {clay.Renderable} x * @param {clay.Renderable} y * @return {boolean} * @static */ Renderer.opaqueSortCompare = Renderer.prototype.opaqueSortCompare = function(x, y) { // Priority renderOrder -> program -> material -> geometry if (x.renderOrder === y.renderOrder) { if (x.__program === y.__program) { if (x.material === y.material) { return x.geometry.__uid__ - y.geometry.__uid__; } return x.material.__uid__ - y.material.__uid__; } if (x.__program && y.__program) { return x.__program.__uid__ - y.__program.__uid__; } return 0; } return x.renderOrder - y.renderOrder; }; /** * Transparent renderables compare function * @param {clay.Renderable} a * @param {clay.Renderable} b * @return {boolean} * @static */ Renderer.transparentSortCompare = Renderer.prototype.transparentSortCompare = function(x, y) { // Priority renderOrder -> depth -> program -> material -> geometry if (x.renderOrder === y.renderOrder) { if (x.__depth === y.__depth) { if (x.__program === y.__program) { if (x.material === y.material) { return x.geometry.__uid__ - y.geometry.__uid__; } return x.material.__uid__ - y.material.__uid__; } if (x.__program && y.__program) { return x.__program.__uid__ - y.__program.__uid__; } return 0; } // Depth is negative // So farther object has smaller depth value return x.__depth - y.__depth; } return x.renderOrder - y.renderOrder; }; // Temporary variables var matrices = { IDENTITY: mat4Create(), WORLD: mat4Create(), VIEW: mat4Create(), PROJECTION: mat4Create(), WORLDVIEW: mat4Create(), VIEWPROJECTION: mat4Create(), WORLDVIEWPROJECTION: mat4Create(), WORLDINVERSE: mat4Create(), VIEWINVERSE: mat4Create(), PROJECTIONINVERSE: mat4Create(), WORLDVIEWINVERSE: mat4Create(), VIEWPROJECTIONINVERSE: mat4Create(), WORLDVIEWPROJECTIONINVERSE: mat4Create(), WORLDTRANSPOSE: mat4Create(), VIEWTRANSPOSE: mat4Create(), PROJECTIONTRANSPOSE: mat4Create(), WORLDVIEWTRANSPOSE: mat4Create(), VIEWPROJECTIONTRANSPOSE: mat4Create(), WORLDVIEWPROJECTIONTRANSPOSE: mat4Create(), WORLDINVERSETRANSPOSE: mat4Create(), VIEWINVERSETRANSPOSE: mat4Create(), PROJECTIONINVERSETRANSPOSE: mat4Create(), WORLDVIEWINVERSETRANSPOSE: mat4Create(), VIEWPROJECTIONINVERSETRANSPOSE: mat4Create(), WORLDVIEWPROJECTIONINVERSETRANSPOSE: mat4Create() }; /** * @name clay.Renderer.COLOR_BUFFER_BIT * @type {number} */ Renderer.COLOR_BUFFER_BIT = glenum.COLOR_BUFFER_BIT; /** * @name clay.Renderer.DEPTH_BUFFER_BIT * @type {number} */ Renderer.DEPTH_BUFFER_BIT = glenum.DEPTH_BUFFER_BIT; /** * @name clay.Renderer.STENCIL_BUFFER_BIT * @type {number} */ Renderer.STENCIL_BUFFER_BIT = glenum.STENCIL_BUFFER_BIT; /** * @constructor * @alias clay.Vector3 * @param {number} x * @param {number} y * @param {number} z */ var Vector3 = function(x, y, z) { x = x || 0; y = y || 0; z = z || 0; /** * Storage of Vector3, read and write of x, y, z will change the values in array * All methods also operate on the array instead of x, y, z components * @name array * @type {Float32Array} * @memberOf clay.Vector3# */ this.array = vec3.fromValues(x, y, z); /** * Dirty flag is used by the Node to determine * if the matrix is updated to latest * @name _dirty * @type {boolean} * @memberOf clay.Vector3# */ this._dirty = true; }; Vector3.prototype = { constructor: Vector3, /** * Add b to self * @param {clay.Vector3} b * @return {clay.Vector3} */ add: function (b) { vec3.add(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Set x, y and z components * @param {number} x * @param {number} y * @param {number} z * @return {clay.Vector3} */ set: function (x, y, z) { this.array[0] = x; this.array[1] = y; this.array[2] = z; this._dirty = true; return this; }, /** * Set x, y and z components from array * @param {Float32Array|number[]} arr * @return {clay.Vector3} */ setArray: function (arr) { this.array[0] = arr[0]; this.array[1] = arr[1]; this.array[2] = arr[2]; this._dirty = true; return this; }, /** * Clone a new Vector3 * @return {clay.Vector3} */ clone: function () { return new Vector3(this.x, this.y, this.z); }, /** * Copy from b * @param {clay.Vector3} b * @return {clay.Vector3} */ copy: function (b) { vec3.copy(this.array, b.array); this._dirty = true; return this; }, /** * Cross product of self and b, written to a Vector3 out * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {clay.Vector3} */ cross: function (a, b) { vec3.cross(this.array, a.array, b.array); this._dirty = true; return this; }, /** * Alias for distance * @param {clay.Vector3} b * @return {number} */ dist: function (b) { return vec3.dist(this.array, b.array); }, /** * Distance between self and b * @param {clay.Vector3} b * @return {number} */ distance: function (b) { return vec3.distance(this.array, b.array); }, /** * Alias for divide * @param {clay.Vector3} b * @return {clay.Vector3} */ div: function (b) { vec3.div(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Divide self by b * @param {clay.Vector3} b * @return {clay.Vector3} */ divide: function (b) { vec3.divide(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Dot product of self and b * @param {clay.Vector3} b * @return {number} */ dot: function (b) { return vec3.dot(this.array, b.array); }, /** * Alias of length * @return {number} */ len: function () { return vec3.len(this.array); }, /** * Calculate the length * @return {number} */ length: function () { return vec3.length(this.array); }, /** * Linear interpolation between a and b * @param {clay.Vector3} a * @param {clay.Vector3} b * @param {number} t * @return {clay.Vector3} */ lerp: function (a, b, t) { vec3.lerp(this.array, a.array, b.array, t); this._dirty = true; return this; }, /** * Minimum of self and b * @param {clay.Vector3} b * @return {clay.Vector3} */ min: function (b) { vec3.min(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Maximum of self and b * @param {clay.Vector3} b * @return {clay.Vector3} */ max: function (b) { vec3.max(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Alias for multiply * @param {clay.Vector3} b * @return {clay.Vector3} */ mul: function (b) { vec3.mul(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Mutiply self and b * @param {clay.Vector3} b * @return {clay.Vector3} */ multiply: function (b) { vec3.multiply(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Negate self * @return {clay.Vector3} */ negate: function () { vec3.negate(this.array, this.array); this._dirty = true; return this; }, /** * Normalize self * @return {clay.Vector3} */ normalize: function () { vec3.normalize(this.array, this.array); this._dirty = true; return this; }, /** * Generate random x, y, z components with a given scale * @param {number} scale * @return {clay.Vector3} */ random: function (scale) { vec3.random(this.array, scale); this._dirty = true; return this; }, /** * Scale self * @param {number} scale * @return {clay.Vector3} */ scale: function (s) { vec3.scale(this.array, this.array, s); this._dirty = true; return this; }, /** * Scale b and add to self * @param {clay.Vector3} b * @param {number} scale * @return {clay.Vector3} */ scaleAndAdd: function (b, s) { vec3.scaleAndAdd(this.array, this.array, b.array, s); this._dirty = true; return this; }, /** * Alias for squaredDistance * @param {clay.Vector3} b * @return {number} */ sqrDist: function (b) { return vec3.sqrDist(this.array, b.array); }, /** * Squared distance between self and b * @param {clay.Vector3} b * @return {number} */ squaredDistance: function (b) { return vec3.squaredDistance(this.array, b.array); }, /** * Alias for squaredLength * @return {number} */ sqrLen: function () { return vec3.sqrLen(this.array); }, /** * Squared length of self * @return {number} */ squaredLength: function () { return vec3.squaredLength(this.array); }, /** * Alias for subtract * @param {clay.Vector3} b * @return {clay.Vector3} */ sub: function (b) { vec3.sub(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Subtract b from self * @param {clay.Vector3} b * @return {clay.Vector3} */ subtract: function (b) { vec3.subtract(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Transform self with a Matrix3 m * @param {clay.Matrix3} m * @return {clay.Vector3} */ transformMat3: function (m) { vec3.transformMat3(this.array, this.array, m.array); this._dirty = true; return this; }, /** * Transform self with a Matrix4 m * @param {clay.Matrix4} m * @return {clay.Vector3} */ transformMat4: function (m) { vec3.transformMat4(this.array, this.array, m.array); this._dirty = true; return this; }, /** * Transform self with a Quaternion q * @param {clay.Quaternion} q * @return {clay.Vector3} */ transformQuat: function (q) { vec3.transformQuat(this.array, this.array, q.array); this._dirty = true; return this; }, /** * Trasnform self into projection space with m * @param {clay.Matrix4} m * @return {clay.Vector3} */ applyProjection: function (m) { var v = this.array; m = m.array; // Perspective projection if (m[15] === 0) { var w = -1 / v[2]; v[0] = m[0] * v[0] * w; v[1] = m[5] * v[1] * w; v[2] = (m[10] * v[2] + m[14]) * w; } else { v[0] = m[0] * v[0] + m[12]; v[1] = m[5] * v[1] + m[13]; v[2] = m[10] * v[2] + m[14]; } this._dirty = true; return this; }, eulerFromQuat: function(q, order) { Vector3.eulerFromQuat(this, q, order); }, eulerFromMat3: function (m, order) { Vector3.eulerFromMat3(this, m, order); }, toString: function() { return '[' + Array.prototype.join.call(this.array, ',') + ']'; }, toArray: function () { return Array.prototype.slice.call(this.array); } }; var defineProperty = Object.defineProperty; // Getter and Setter if (defineProperty) { var proto$1 = Vector3.prototype; /** * @name x * @type {number} * @memberOf clay.Vector3 * @instance */ defineProperty(proto$1, 'x', { get: function () { return this.array[0]; }, set: function (value) { this.array[0] = value; this._dirty = true; } }); /** * @name y * @type {number} * @memberOf clay.Vector3 * @instance */ defineProperty(proto$1, 'y', { get: function () { return this.array[1]; }, set: function (value) { this.array[1] = value; this._dirty = true; } }); /** * @name z * @type {number} * @memberOf clay.Vector3 * @instance */ defineProperty(proto$1, 'z', { get: function () { return this.array[2]; }, set: function (value) { this.array[2] = value; this._dirty = true; } }); } // Supply methods that are not in place /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {clay.Vector3} */ Vector3.add = function(out, a, b) { vec3.add(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector3} out * @param {number} x * @param {number} y * @param {number} z * @return {clay.Vector3} */ Vector3.set = function(out, x, y, z) { vec3.set(out.array, x, y, z); out._dirty = true; }; /** * @param {clay.Vector3} out * @param {clay.Vector3} b * @return {clay.Vector3} */ Vector3.copy = function(out, b) { vec3.copy(out.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {clay.Vector3} */ Vector3.cross = function(out, a, b) { vec3.cross(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {number} */ Vector3.dist = function(a, b) { return vec3.distance(a.array, b.array); }; /** * @function * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {number} */ Vector3.distance = Vector3.dist; /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {clay.Vector3} */ Vector3.div = function(out, a, b) { vec3.divide(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {clay.Vector3} */ Vector3.divide = Vector3.div; /** * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {number} */ Vector3.dot = function(a, b) { return vec3.dot(a.array, b.array); }; /** * @param {clay.Vector3} a * @return {number} */ Vector3.len = function(b) { return vec3.length(b.array); }; // Vector3.length = Vector3.len; /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {clay.Vector3} b * @param {number} t * @return {clay.Vector3} */ Vector3.lerp = function(out, a, b, t) { vec3.lerp(out.array, a.array, b.array, t); out._dirty = true; return out; }; /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {clay.Vector3} */ Vector3.min = function(out, a, b) { vec3.min(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {clay.Vector3} */ Vector3.max = function(out, a, b) { vec3.max(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {clay.Vector3} */ Vector3.mul = function(out, a, b) { vec3.multiply(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {clay.Vector3} */ Vector3.multiply = Vector3.mul; /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @return {clay.Vector3} */ Vector3.negate = function(out, a) { vec3.negate(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @return {clay.Vector3} */ Vector3.normalize = function(out, a) { vec3.normalize(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Vector3} out * @param {number} scale * @return {clay.Vector3} */ Vector3.random = function(out, scale) { vec3.random(out.array, scale); out._dirty = true; return out; }; /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {number} scale * @return {clay.Vector3} */ Vector3.scale = function(out, a, scale) { vec3.scale(out.array, a.array, scale); out._dirty = true; return out; }; /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {clay.Vector3} b * @param {number} scale * @return {clay.Vector3} */ Vector3.scaleAndAdd = function(out, a, b, scale) { vec3.scaleAndAdd(out.array, a.array, b.array, scale); out._dirty = true; return out; }; /** * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {number} */ Vector3.sqrDist = function(a, b) { return vec3.sqrDist(a.array, b.array); }; /** * @function * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {number} */ Vector3.squaredDistance = Vector3.sqrDist; /** * @param {clay.Vector3} a * @return {number} */ Vector3.sqrLen = function(a) { return vec3.sqrLen(a.array); }; /** * @function * @param {clay.Vector3} a * @return {number} */ Vector3.squaredLength = Vector3.sqrLen; /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {clay.Vector3} */ Vector3.sub = function(out, a, b) { vec3.subtract(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {clay.Vector3} */ Vector3.subtract = Vector3.sub; /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {Matrix3} m * @return {clay.Vector3} */ Vector3.transformMat3 = function(out, a, m) { vec3.transformMat3(out.array, a.array, m.array); out._dirty = true; return out; }; /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {clay.Matrix4} m * @return {clay.Vector3} */ Vector3.transformMat4 = function(out, a, m) { vec3.transformMat4(out.array, a.array, m.array); out._dirty = true; return out; }; /** * @param {clay.Vector3} out * @param {clay.Vector3} a * @param {clay.Quaternion} q * @return {clay.Vector3} */ Vector3.transformQuat = function(out, a, q) { vec3.transformQuat(out.array, a.array, q.array); out._dirty = true; return out; }; function clamp(val, min, max) { return val < min ? min : (val > max ? max : val); } var atan2 = Math.atan2; var asin = Math.asin; var abs = Math.abs; /** * Convert quaternion to euler angle * Quaternion must be normalized * From three.js */ Vector3.eulerFromQuat = function (out, q, order) { out._dirty = true; q = q.array; var target = out.array; var x = q[0], y = q[1], z = q[2], w = q[3]; var x2 = x * x; var y2 = y * y; var z2 = z * z; var w2 = w * w; var order = (order || 'XYZ').toUpperCase(); switch (order) { case 'XYZ': target[0] = atan2(2 * (x * w - y * z), (w2 - x2 - y2 + z2)); target[1] = asin(clamp(2 * (x * z + y * w), - 1, 1)); target[2] = atan2(2 * (z * w - x * y), (w2 + x2 - y2 - z2)); break; case 'YXZ': target[0] = asin(clamp(2 * (x * w - y * z), - 1, 1)); target[1] = atan2(2 * (x * z + y * w), (w2 - x2 - y2 + z2)); target[2] = atan2(2 * (x * y + z * w), (w2 - x2 + y2 - z2)); break; case 'ZXY': target[0] = asin(clamp(2 * (x * w + y * z), - 1, 1)); target[1] = atan2(2 * (y * w - z * x), (w2 - x2 - y2 + z2)); target[2] = atan2(2 * (z * w - x * y), (w2 - x2 + y2 - z2)); break; case 'ZYX': target[0] = atan2(2 * (x * w + z * y), (w2 - x2 - y2 + z2)); target[1] = asin(clamp(2 * (y * w - x * z), - 1, 1)); target[2] = atan2(2 * (x * y + z * w), (w2 + x2 - y2 - z2)); break; case 'YZX': target[0] = atan2(2 * (x * w - z * y), (w2 - x2 + y2 - z2)); target[1] = atan2(2 * (y * w - x * z), (w2 + x2 - y2 - z2)); target[2] = asin(clamp(2 * (x * y + z * w), - 1, 1)); break; case 'XZY': target[0] = atan2(2 * (x * w + y * z), (w2 - x2 + y2 - z2)); target[1] = atan2(2 * (x * z + y * w), (w2 + x2 - y2 - z2)); target[2] = asin(clamp(2 * (z * w - x * y), - 1, 1)); break; default: console.warn('Unkown order: ' + order); } return out; }; /** * Convert rotation matrix to euler angle * from three.js */ Vector3.eulerFromMat3 = function (out, m, order) { // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) var te = m.array; var m11 = te[0], m12 = te[3], m13 = te[6]; var m21 = te[1], m22 = te[4], m23 = te[7]; var m31 = te[2], m32 = te[5], m33 = te[8]; var target = out.array; var order = (order || 'XYZ').toUpperCase(); switch (order) { case 'XYZ': target[1] = asin(clamp(m13, -1, 1)); if (abs(m13) < 0.99999) { target[0] = atan2(-m23, m33); target[2] = atan2(-m12, m11); } else { target[0] = atan2(m32, m22); target[2] = 0; } break; case 'YXZ': target[0] = asin(-clamp(m23, -1, 1)); if (abs(m23) < 0.99999) { target[1] = atan2(m13, m33); target[2] = atan2(m21, m22); } else { target[1] = atan2(-m31, m11); target[2] = 0; } break; case 'ZXY': target[0] = asin(clamp(m32, -1, 1)); if (abs(m32) < 0.99999) { target[1] = atan2(-m31, m33); target[2] = atan2(-m12, m22); } else { target[1] = 0; target[2] = atan2(m21, m11); } break; case 'ZYX': target[1] = asin(-clamp(m31, -1, 1)); if (abs(m31) < 0.99999) { target[0] = atan2(m32, m33); target[2] = atan2(m21, m11); } else { target[0] = 0; target[2] = atan2(-m12, m22); } break; case 'YZX': target[2] = asin(clamp(m21, -1, 1)); if (abs(m21) < 0.99999) { target[0] = atan2(-m23, m22); target[1] = atan2(-m31, m11); } else { target[0] = 0; target[1] = atan2(m13, m33); } break; case 'XZY': target[2] = asin(-clamp(m12, -1, 1)); if (abs(m12) < 0.99999) { target[0] = atan2(m32, m22); target[1] = atan2(m13, m11); } else { target[0] = atan2(-m23, m33); target[1] = 0; } break; default: console.warn('Unkown order: ' + order); } out._dirty = true; return out; }; Object.defineProperties(Vector3, { /** * @type {clay.Vector3} * @readOnly * @memberOf clay.Vector3 */ POSITIVE_X: { get: function () { return new Vector3(1, 0, 0); } }, /** * @type {clay.Vector3} * @readOnly * @memberOf clay.Vector3 */ NEGATIVE_X: { get: function () { return new Vector3(-1, 0, 0); } }, /** * @type {clay.Vector3} * @readOnly * @memberOf clay.Vector3 */ POSITIVE_Y: { get: function () { return new Vector3(0, 1, 0); } }, /** * @type {clay.Vector3} * @readOnly * @memberOf clay.Vector3 */ NEGATIVE_Y: { get: function () { return new Vector3(0, -1, 0); } }, /** * @type {clay.Vector3} * @readOnly * @memberOf clay.Vector3 */ POSITIVE_Z: { get: function () { return new Vector3(0, 0, 1); } }, /** * @type {clay.Vector3} * @readOnly */ NEGATIVE_Z: { get: function () { return new Vector3(0, 0, -1); } }, /** * @type {clay.Vector3} * @readOnly * @memberOf clay.Vector3 */ UP: { get: function () { return new Vector3(0, 1, 0); } }, /** * @type {clay.Vector3} * @readOnly * @memberOf clay.Vector3 */ ZERO: { get: function () { return new Vector3(); } } }); /** * @constructor * @alias clay.Quaternion * @param {number} x * @param {number} y * @param {number} z * @param {number} w */ var Quaternion = function (x, y, z, w) { x = x || 0; y = y || 0; z = z || 0; w = w === undefined ? 1 : w; /** * Storage of Quaternion, read and write of x, y, z, w will change the values in array * All methods also operate on the array instead of x, y, z, w components * @name array * @type {Float32Array} * @memberOf clay.Quaternion# */ this.array = quat.fromValues(x, y, z, w); /** * Dirty flag is used by the Node to determine * if the matrix is updated to latest * @name _dirty * @type {boolean} * @memberOf clay.Quaternion# */ this._dirty = true; }; Quaternion.prototype = { constructor: Quaternion, /** * Add b to self * @param {clay.Quaternion} b * @return {clay.Quaternion} */ add: function (b) { quat.add(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Calculate the w component from x, y, z component * @return {clay.Quaternion} */ calculateW: function () { quat.calculateW(this.array, this.array); this._dirty = true; return this; }, /** * Set x, y and z components * @param {number} x * @param {number} y * @param {number} z * @param {number} w * @return {clay.Quaternion} */ set: function (x, y, z, w) { this.array[0] = x; this.array[1] = y; this.array[2] = z; this.array[3] = w; this._dirty = true; return this; }, /** * Set x, y, z and w components from array * @param {Float32Array|number[]} arr * @return {clay.Quaternion} */ setArray: function (arr) { this.array[0] = arr[0]; this.array[1] = arr[1]; this.array[2] = arr[2]; this.array[3] = arr[3]; this._dirty = true; return this; }, /** * Clone a new Quaternion * @return {clay.Quaternion} */ clone: function () { return new Quaternion(this.x, this.y, this.z, this.w); }, /** * Calculates the conjugate of self If the quaternion is normalized, * this function is faster than invert and produces the same result. * * @return {clay.Quaternion} */ conjugate: function () { quat.conjugate(this.array, this.array); this._dirty = true; return this; }, /** * Copy from b * @param {clay.Quaternion} b * @return {clay.Quaternion} */ copy: function (b) { quat.copy(this.array, b.array); this._dirty = true; return this; }, /** * Dot product of self and b * @param {clay.Quaternion} b * @return {number} */ dot: function (b) { return quat.dot(this.array, b.array); }, /** * Set from the given 3x3 rotation matrix * @param {clay.Matrix3} m * @return {clay.Quaternion} */ fromMat3: function (m) { quat.fromMat3(this.array, m.array); this._dirty = true; return this; }, /** * Set from the given 4x4 rotation matrix * The 4th column and 4th row will be droped * @param {clay.Matrix4} m * @return {clay.Quaternion} */ fromMat4: (function () { var m3 = mat3.create(); return function (m) { mat3.fromMat4(m3, m.array); // TODO Not like mat4, mat3 in glmatrix seems to be row-based mat3.transpose(m3, m3); quat.fromMat3(this.array, m3); this._dirty = true; return this; }; })(), /** * Set to identity quaternion * @return {clay.Quaternion} */ identity: function () { quat.identity(this.array); this._dirty = true; return this; }, /** * Invert self * @return {clay.Quaternion} */ invert: function () { quat.invert(this.array, this.array); this._dirty = true; return this; }, /** * Alias of length * @return {number} */ len: function () { return quat.len(this.array); }, /** * Calculate the length * @return {number} */ length: function () { return quat.length(this.array); }, /** * Linear interpolation between a and b * @param {clay.Quaternion} a * @param {clay.Quaternion} b * @param {number} t * @return {clay.Quaternion} */ lerp: function (a, b, t) { quat.lerp(this.array, a.array, b.array, t); this._dirty = true; return this; }, /** * Alias for multiply * @param {clay.Quaternion} b * @return {clay.Quaternion} */ mul: function (b) { quat.mul(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Alias for multiplyLeft * @param {clay.Quaternion} a * @return {clay.Quaternion} */ mulLeft: function (a) { quat.multiply(this.array, a.array, this.array); this._dirty = true; return this; }, /** * Mutiply self and b * @param {clay.Quaternion} b * @return {clay.Quaternion} */ multiply: function (b) { quat.multiply(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Mutiply a and self * Quaternion mutiply is not commutative, so the result of mutiplyLeft is different with multiply. * @param {clay.Quaternion} a * @return {clay.Quaternion} */ multiplyLeft: function (a) { quat.multiply(this.array, a.array, this.array); this._dirty = true; return this; }, /** * Normalize self * @return {clay.Quaternion} */ normalize: function () { quat.normalize(this.array, this.array); this._dirty = true; return this; }, /** * Rotate self by a given radian about X axis * @param {number} rad * @return {clay.Quaternion} */ rotateX: function (rad) { quat.rotateX(this.array, this.array, rad); this._dirty = true; return this; }, /** * Rotate self by a given radian about Y axis * @param {number} rad * @return {clay.Quaternion} */ rotateY: function (rad) { quat.rotateY(this.array, this.array, rad); this._dirty = true; return this; }, /** * Rotate self by a given radian about Z axis * @param {number} rad * @return {clay.Quaternion} */ rotateZ: function (rad) { quat.rotateZ(this.array, this.array, rad); this._dirty = true; return this; }, /** * Sets self to represent the shortest rotation from Vector3 a to Vector3 b. * a and b needs to be normalized * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {clay.Quaternion} */ rotationTo: function (a, b) { quat.rotationTo(this.array, a.array, b.array); this._dirty = true; return this; }, /** * Sets self with values corresponding to the given axes * @param {clay.Vector3} view * @param {clay.Vector3} right * @param {clay.Vector3} up * @return {clay.Quaternion} */ setAxes: function (view, right, up) { quat.setAxes(this.array, view.array, right.array, up.array); this._dirty = true; return this; }, /** * Sets self with a rotation axis and rotation angle * @param {clay.Vector3} axis * @param {number} rad * @return {clay.Quaternion} */ setAxisAngle: function (axis, rad) { quat.setAxisAngle(this.array, axis.array, rad); this._dirty = true; return this; }, /** * Perform spherical linear interpolation between a and b * @param {clay.Quaternion} a * @param {clay.Quaternion} b * @param {number} t * @return {clay.Quaternion} */ slerp: function (a, b, t) { quat.slerp(this.array, a.array, b.array, t); this._dirty = true; return this; }, /** * Alias for squaredLength * @return {number} */ sqrLen: function () { return quat.sqrLen(this.array); }, /** * Squared length of self * @return {number} */ squaredLength: function () { return quat.squaredLength(this.array); }, /** * Set from euler * @param {clay.Vector3} v * @param {String} order */ fromEuler: function (v, order) { return Quaternion.fromEuler(this, v, order); }, toString: function () { return '[' + Array.prototype.join.call(this.array, ',') + ']'; }, toArray: function () { return Array.prototype.slice.call(this.array); } }; var defineProperty$1 = Object.defineProperty; // Getter and Setter if (defineProperty$1) { var proto$2 = Quaternion.prototype; /** * @name x * @type {number} * @memberOf clay.Quaternion * @instance */ defineProperty$1(proto$2, 'x', { get: function () { return this.array[0]; }, set: function (value) { this.array[0] = value; this._dirty = true; } }); /** * @name y * @type {number} * @memberOf clay.Quaternion * @instance */ defineProperty$1(proto$2, 'y', { get: function () { return this.array[1]; }, set: function (value) { this.array[1] = value; this._dirty = true; } }); /** * @name z * @type {number} * @memberOf clay.Quaternion * @instance */ defineProperty$1(proto$2, 'z', { get: function () { return this.array[2]; }, set: function (value) { this.array[2] = value; this._dirty = true; } }); /** * @name w * @type {number} * @memberOf clay.Quaternion * @instance */ defineProperty$1(proto$2, 'w', { get: function () { return this.array[3]; }, set: function (value) { this.array[3] = value; this._dirty = true; } }); } // Supply methods that are not in place /** * @param {clay.Quaternion} out * @param {clay.Quaternion} a * @param {clay.Quaternion} b * @return {clay.Quaternion} */ Quaternion.add = function (out, a, b) { quat.add(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Quaternion} out * @param {number} x * @param {number} y * @param {number} z * @param {number} w * @return {clay.Quaternion} */ Quaternion.set = function (out, x, y, z, w) { quat.set(out.array, x, y, z, w); out._dirty = true; }; /** * @param {clay.Quaternion} out * @param {clay.Quaternion} b * @return {clay.Quaternion} */ Quaternion.copy = function (out, b) { quat.copy(out.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Quaternion} out * @param {clay.Quaternion} a * @return {clay.Quaternion} */ Quaternion.calculateW = function (out, a) { quat.calculateW(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Quaternion} out * @param {clay.Quaternion} a * @return {clay.Quaternion} */ Quaternion.conjugate = function (out, a) { quat.conjugate(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Quaternion} out * @return {clay.Quaternion} */ Quaternion.identity = function (out) { quat.identity(out.array); out._dirty = true; return out; }; /** * @param {clay.Quaternion} out * @param {clay.Quaternion} a * @return {clay.Quaternion} */ Quaternion.invert = function (out, a) { quat.invert(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Quaternion} a * @param {clay.Quaternion} b * @return {number} */ Quaternion.dot = function (a, b) { return quat.dot(a.array, b.array); }; /** * @param {clay.Quaternion} a * @return {number} */ Quaternion.len = function (a) { return quat.length(a.array); }; // Quaternion.length = Quaternion.len; /** * @param {clay.Quaternion} out * @param {clay.Quaternion} a * @param {clay.Quaternion} b * @param {number} t * @return {clay.Quaternion} */ Quaternion.lerp = function (out, a, b, t) { quat.lerp(out.array, a.array, b.array, t); out._dirty = true; return out; }; /** * @param {clay.Quaternion} out * @param {clay.Quaternion} a * @param {clay.Quaternion} b * @param {number} t * @return {clay.Quaternion} */ Quaternion.slerp = function (out, a, b, t) { quat.slerp(out.array, a.array, b.array, t); out._dirty = true; return out; }; /** * @param {clay.Quaternion} out * @param {clay.Quaternion} a * @param {clay.Quaternion} b * @return {clay.Quaternion} */ Quaternion.mul = function (out, a, b) { quat.multiply(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Quaternion} out * @param {clay.Quaternion} a * @param {clay.Quaternion} b * @return {clay.Quaternion} */ Quaternion.multiply = Quaternion.mul; /** * @param {clay.Quaternion} out * @param {clay.Quaternion} a * @param {number} rad * @return {clay.Quaternion} */ Quaternion.rotateX = function (out, a, rad) { quat.rotateX(out.array, a.array, rad); out._dirty = true; return out; }; /** * @param {clay.Quaternion} out * @param {clay.Quaternion} a * @param {number} rad * @return {clay.Quaternion} */ Quaternion.rotateY = function (out, a, rad) { quat.rotateY(out.array, a.array, rad); out._dirty = true; return out; }; /** * @param {clay.Quaternion} out * @param {clay.Quaternion} a * @param {number} rad * @return {clay.Quaternion} */ Quaternion.rotateZ = function (out, a, rad) { quat.rotateZ(out.array, a.array, rad); out._dirty = true; return out; }; /** * @param {clay.Quaternion} out * @param {clay.Vector3} axis * @param {number} rad * @return {clay.Quaternion} */ Quaternion.setAxisAngle = function (out, axis, rad) { quat.setAxisAngle(out.array, axis.array, rad); out._dirty = true; return out; }; /** * @param {clay.Quaternion} out * @param {clay.Quaternion} a * @return {clay.Quaternion} */ Quaternion.normalize = function (out, a) { quat.normalize(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Quaternion} a * @return {number} */ Quaternion.sqrLen = function (a) { return quat.sqrLen(a.array); }; /** * @function * @param {clay.Quaternion} a * @return {number} */ Quaternion.squaredLength = Quaternion.sqrLen; /** * @param {clay.Quaternion} out * @param {clay.Matrix3} m * @return {clay.Quaternion} */ Quaternion.fromMat3 = function (out, m) { quat.fromMat3(out.array, m.array); out._dirty = true; return out; }; /** * @param {clay.Quaternion} out * @param {clay.Vector3} view * @param {clay.Vector3} right * @param {clay.Vector3} up * @return {clay.Quaternion} */ Quaternion.setAxes = function (out, view, right, up) { quat.setAxes(out.array, view.array, right.array, up.array); out._dirty = true; return out; }; /** * @param {clay.Quaternion} out * @param {clay.Vector3} a * @param {clay.Vector3} b * @return {clay.Quaternion} */ Quaternion.rotationTo = function (out, a, b) { quat.rotationTo(out.array, a.array, b.array); out._dirty = true; return out; }; /** * Set quaternion from euler * @param {clay.Quaternion} out * @param {clay.Vector3} v * @param {String} order */ Quaternion.fromEuler = function (out, v, order) { out._dirty = true; v = v.array; var target = out.array; var c1 = Math.cos(v[0] / 2); var c2 = Math.cos(v[1] / 2); var c3 = Math.cos(v[2] / 2); var s1 = Math.sin(v[0] / 2); var s2 = Math.sin(v[1] / 2); var s3 = Math.sin(v[2] / 2); var order = (order || 'XYZ').toUpperCase(); // http://www.mathworks.com/matlabcentral/fileexchange/ // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ // content/SpinCalc.m switch (order) { case 'XYZ': target[0] = s1 * c2 * c3 + c1 * s2 * s3; target[1] = c1 * s2 * c3 - s1 * c2 * s3; target[2] = c1 * c2 * s3 + s1 * s2 * c3; target[3] = c1 * c2 * c3 - s1 * s2 * s3; break; case 'YXZ': target[0] = s1 * c2 * c3 + c1 * s2 * s3; target[1] = c1 * s2 * c3 - s1 * c2 * s3; target[2] = c1 * c2 * s3 - s1 * s2 * c3; target[3] = c1 * c2 * c3 + s1 * s2 * s3; break; case 'ZXY': target[0] = s1 * c2 * c3 - c1 * s2 * s3; target[1] = c1 * s2 * c3 + s1 * c2 * s3; target[2] = c1 * c2 * s3 + s1 * s2 * c3; target[3] = c1 * c2 * c3 - s1 * s2 * s3; break; case 'ZYX': target[0] = s1 * c2 * c3 - c1 * s2 * s3; target[1] = c1 * s2 * c3 + s1 * c2 * s3; target[2] = c1 * c2 * s3 - s1 * s2 * c3; target[3] = c1 * c2 * c3 + s1 * s2 * s3; break; case 'YZX': target[0] = s1 * c2 * c3 + c1 * s2 * s3; target[1] = c1 * s2 * c3 + s1 * c2 * s3; target[2] = c1 * c2 * s3 - s1 * s2 * c3; target[3] = c1 * c2 * c3 - s1 * s2 * s3; break; case 'XZY': target[0] = s1 * c2 * c3 - c1 * s2 * s3; target[1] = c1 * s2 * c3 - s1 * c2 * s3; target[2] = c1 * c2 * s3 + s1 * s2 * c3; target[3] = c1 * c2 * c3 + s1 * s2 * s3; break; } }; /** * @constructor * @alias clay.Matrix4 */ var Matrix4 = function() { this._axisX = new Vector3(); this._axisY = new Vector3(); this._axisZ = new Vector3(); /** * Storage of Matrix4 * @name array * @type {Float32Array} * @memberOf clay.Matrix4# */ this.array = mat4.create(); /** * @name _dirty * @type {boolean} * @memberOf clay.Matrix4# */ this._dirty = true; }; Matrix4.prototype = { constructor: Matrix4, /** * Set components from array * @param {Float32Array|number[]} arr */ setArray: function (arr) { for (var i = 0; i < this.array.length; i++) { this.array[i] = arr[i]; } this._dirty = true; return this; }, /** * Calculate the adjugate of self, in-place * @return {clay.Matrix4} */ adjoint: function() { mat4.adjoint(this.array, this.array); this._dirty = true; return this; }, /** * Clone a new Matrix4 * @return {clay.Matrix4} */ clone: function() { return (new Matrix4()).copy(this); }, /** * Copy from b * @param {clay.Matrix4} b * @return {clay.Matrix4} */ copy: function(a) { mat4.copy(this.array, a.array); this._dirty = true; return this; }, /** * Calculate matrix determinant * @return {number} */ determinant: function() { return mat4.determinant(this.array); }, /** * Set upper 3x3 part from quaternion * @param {clay.Quaternion} q * @return {clay.Matrix4} */ fromQuat: function(q) { mat4.fromQuat(this.array, q.array); this._dirty = true; return this; }, /** * Set from a quaternion rotation and a vector translation * @param {clay.Quaternion} q * @param {clay.Vector3} v * @return {clay.Matrix4} */ fromRotationTranslation: function(q, v) { mat4.fromRotationTranslation(this.array, q.array, v.array); this._dirty = true; return this; }, /** * Set from Matrix2d, it is used when converting a 2d shape to 3d space. * In 3d space it is equivalent to ranslate on xy plane and rotate about z axis * @param {clay.Matrix2d} m2d * @return {clay.Matrix4} */ fromMat2d: function(m2d) { Matrix4.fromMat2d(this, m2d); return this; }, /** * Set from frustum bounds * @param {number} left * @param {number} right * @param {number} bottom * @param {number} top * @param {number} near * @param {number} far * @return {clay.Matrix4} */ frustum: function (left, right, bottom, top, near, far) { mat4.frustum(this.array, left, right, bottom, top, near, far); this._dirty = true; return this; }, /** * Set to a identity matrix * @return {clay.Matrix4} */ identity: function() { mat4.identity(this.array); this._dirty = true; return this; }, /** * Invert self * @return {clay.Matrix4} */ invert: function() { mat4.invert(this.array, this.array); this._dirty = true; return this; }, /** * Set as a matrix with the given eye position, focal point, and up axis * @param {clay.Vector3} eye * @param {clay.Vector3} center * @param {clay.Vector3} up * @return {clay.Matrix4} */ lookAt: function(eye, center, up) { mat4.lookAt(this.array, eye.array, center.array, up.array); this._dirty = true; return this; }, /** * Alias for mutiply * @param {clay.Matrix4} b * @return {clay.Matrix4} */ mul: function(b) { mat4.mul(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Alias for multiplyLeft * @param {clay.Matrix4} a * @return {clay.Matrix4} */ mulLeft: function(a) { mat4.mul(this.array, a.array, this.array); this._dirty = true; return this; }, /** * Multiply self and b * @param {clay.Matrix4} b * @return {clay.Matrix4} */ multiply: function(b) { mat4.multiply(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Multiply a and self, a is on the left * @param {clay.Matrix3} a * @return {clay.Matrix3} */ multiplyLeft: function(a) { mat4.multiply(this.array, a.array, this.array); this._dirty = true; return this; }, /** * Set as a orthographic projection matrix * @param {number} left * @param {number} right * @param {number} bottom * @param {number} top * @param {number} near * @param {number} far * @return {clay.Matrix4} */ ortho: function(left, right, bottom, top, near, far) { mat4.ortho(this.array, left, right, bottom, top, near, far); this._dirty = true; return this; }, /** * Set as a perspective projection matrix * @param {number} fovy * @param {number} aspect * @param {number} near * @param {number} far * @return {clay.Matrix4} */ perspective: function(fovy, aspect, near, far) { mat4.perspective(this.array, fovy, aspect, near, far); this._dirty = true; return this; }, /** * Rotate self by rad about axis. * Equal to right-multiply a rotaion matrix * @param {number} rad * @param {clay.Vector3} axis * @return {clay.Matrix4} */ rotate: function(rad, axis) { mat4.rotate(this.array, this.array, rad, axis.array); this._dirty = true; return this; }, /** * Rotate self by a given radian about X axis. * Equal to right-multiply a rotaion matrix * @param {number} rad * @return {clay.Matrix4} */ rotateX: function(rad) { mat4.rotateX(this.array, this.array, rad); this._dirty = true; return this; }, /** * Rotate self by a given radian about Y axis. * Equal to right-multiply a rotaion matrix * @param {number} rad * @return {clay.Matrix4} */ rotateY: function(rad) { mat4.rotateY(this.array, this.array, rad); this._dirty = true; return this; }, /** * Rotate self by a given radian about Z axis. * Equal to right-multiply a rotaion matrix * @param {number} rad * @return {clay.Matrix4} */ rotateZ: function(rad) { mat4.rotateZ(this.array, this.array, rad); this._dirty = true; return this; }, /** * Scale self by s * Equal to right-multiply a scale matrix * @param {clay.Vector3} s * @return {clay.Matrix4} */ scale: function(v) { mat4.scale(this.array, this.array, v.array); this._dirty = true; return this; }, /** * Translate self by v. * Equal to right-multiply a translate matrix * @param {clay.Vector3} v * @return {clay.Matrix4} */ translate: function(v) { mat4.translate(this.array, this.array, v.array); this._dirty = true; return this; }, /** * Transpose self, in-place. * @return {clay.Matrix2} */ transpose: function() { mat4.transpose(this.array, this.array); this._dirty = true; return this; }, /** * Decompose a matrix to SRT * @param {clay.Vector3} [scale] * @param {clay.Quaternion} rotation * @param {clay.Vector} position * @see http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.matrix.decompose.aspx */ decomposeMatrix: (function() { var x = vec3.create(); var y = vec3.create(); var z = vec3.create(); var m3 = mat3.create(); return function(scale, rotation, position) { var el = this.array; vec3.set(x, el[0], el[1], el[2]); vec3.set(y, el[4], el[5], el[6]); vec3.set(z, el[8], el[9], el[10]); var sx = vec3.length(x); var sy = vec3.length(y); var sz = vec3.length(z); // if determine is negative, we need to invert one scale var det = this.determinant(); if (det < 0) { sx = -sx; } if (scale) { scale.set(sx, sy, sz); } position.set(el[12], el[13], el[14]); mat3.fromMat4(m3, el); // Not like mat4, mat3 in glmatrix seems to be row-based // Seems fixed in gl-matrix 2.2.2 // https://github.com/toji/gl-matrix/issues/114 // mat3.transpose(m3, m3); m3[0] /= sx; m3[1] /= sx; m3[2] /= sx; m3[3] /= sy; m3[4] /= sy; m3[5] /= sy; m3[6] /= sz; m3[7] /= sz; m3[8] /= sz; quat.fromMat3(rotation.array, m3); quat.normalize(rotation.array, rotation.array); rotation._dirty = true; position._dirty = true; }; })(), toString: function() { return '[' + Array.prototype.join.call(this.array, ',') + ']'; }, toArray: function () { return Array.prototype.slice.call(this.array); } }; var defineProperty$2 = Object.defineProperty; if (defineProperty$2) { var proto$3 = Matrix4.prototype; /** * Z Axis of local transform * @name z * @type {clay.Vector3} * @memberOf clay.Matrix4 * @instance */ defineProperty$2(proto$3, 'z', { get: function () { var el = this.array; this._axisZ.set(el[8], el[9], el[10]); return this._axisZ; }, set: function (v) { // TODO Here has a problem // If only set an item of vector will not work var el = this.array; v = v.array; el[8] = v[0]; el[9] = v[1]; el[10] = v[2]; this._dirty = true; } }); /** * Y Axis of local transform * @name y * @type {clay.Vector3} * @memberOf clay.Matrix4 * @instance */ defineProperty$2(proto$3, 'y', { get: function () { var el = this.array; this._axisY.set(el[4], el[5], el[6]); return this._axisY; }, set: function (v) { var el = this.array; v = v.array; el[4] = v[0]; el[5] = v[1]; el[6] = v[2]; this._dirty = true; } }); /** * X Axis of local transform * @name x * @type {clay.Vector3} * @memberOf clay.Matrix4 * @instance */ defineProperty$2(proto$3, 'x', { get: function () { var el = this.array; this._axisX.set(el[0], el[1], el[2]); return this._axisX; }, set: function (v) { var el = this.array; v = v.array; el[0] = v[0]; el[1] = v[1]; el[2] = v[2]; this._dirty = true; } }); } /** * @param {clay.Matrix4} out * @param {clay.Matrix4} a * @return {clay.Matrix4} */ Matrix4.adjoint = function(out, a) { mat4.adjoint(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix4} out * @param {clay.Matrix4} a * @return {clay.Matrix4} */ Matrix4.copy = function(out, a) { mat4.copy(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix4} a * @return {number} */ Matrix4.determinant = function(a) { return mat4.determinant(a.array); }; /** * @param {clay.Matrix4} out * @return {clay.Matrix4} */ Matrix4.identity = function(out) { mat4.identity(out.array); out._dirty = true; return out; }; /** * @param {clay.Matrix4} out * @param {number} left * @param {number} right * @param {number} bottom * @param {number} top * @param {number} near * @param {number} far * @return {clay.Matrix4} */ Matrix4.ortho = function(out, left, right, bottom, top, near, far) { mat4.ortho(out.array, left, right, bottom, top, near, far); out._dirty = true; return out; }; /** * @param {clay.Matrix4} out * @param {number} fovy * @param {number} aspect * @param {number} near * @param {number} far * @return {clay.Matrix4} */ Matrix4.perspective = function(out, fovy, aspect, near, far) { mat4.perspective(out.array, fovy, aspect, near, far); out._dirty = true; return out; }; /** * @param {clay.Matrix4} out * @param {clay.Vector3} eye * @param {clay.Vector3} center * @param {clay.Vector3} up * @return {clay.Matrix4} */ Matrix4.lookAt = function(out, eye, center, up) { mat4.lookAt(out.array, eye.array, center.array, up.array); out._dirty = true; return out; }; /** * @param {clay.Matrix4} out * @param {clay.Matrix4} a * @return {clay.Matrix4} */ Matrix4.invert = function(out, a) { mat4.invert(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix4} out * @param {clay.Matrix4} a * @param {clay.Matrix4} b * @return {clay.Matrix4} */ Matrix4.mul = function(out, a, b) { mat4.mul(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Matrix4} out * @param {clay.Matrix4} a * @param {clay.Matrix4} b * @return {clay.Matrix4} */ Matrix4.multiply = Matrix4.mul; /** * @param {clay.Matrix4} out * @param {clay.Quaternion} q * @return {clay.Matrix4} */ Matrix4.fromQuat = function(out, q) { mat4.fromQuat(out.array, q.array); out._dirty = true; return out; }; /** * @param {clay.Matrix4} out * @param {clay.Quaternion} q * @param {clay.Vector3} v * @return {clay.Matrix4} */ Matrix4.fromRotationTranslation = function(out, q, v) { mat4.fromRotationTranslation(out.array, q.array, v.array); out._dirty = true; return out; }; /** * @param {clay.Matrix4} m4 * @param {clay.Matrix2d} m2d * @return {clay.Matrix4} */ Matrix4.fromMat2d = function(m4, m2d) { m4._dirty = true; var m2d = m2d.array; var m4 = m4.array; m4[0] = m2d[0]; m4[4] = m2d[2]; m4[12] = m2d[4]; m4[1] = m2d[1]; m4[5] = m2d[3]; m4[13] = m2d[5]; return m4; }; /** * @param {clay.Matrix4} out * @param {clay.Matrix4} a * @param {number} rad * @param {clay.Vector3} axis * @return {clay.Matrix4} */ Matrix4.rotate = function(out, a, rad, axis) { mat4.rotate(out.array, a.array, rad, axis.array); out._dirty = true; return out; }; /** * @param {clay.Matrix4} out * @param {clay.Matrix4} a * @param {number} rad * @return {clay.Matrix4} */ Matrix4.rotateX = function(out, a, rad) { mat4.rotateX(out.array, a.array, rad); out._dirty = true; return out; }; /** * @param {clay.Matrix4} out * @param {clay.Matrix4} a * @param {number} rad * @return {clay.Matrix4} */ Matrix4.rotateY = function(out, a, rad) { mat4.rotateY(out.array, a.array, rad); out._dirty = true; return out; }; /** * @param {clay.Matrix4} out * @param {clay.Matrix4} a * @param {number} rad * @return {clay.Matrix4} */ Matrix4.rotateZ = function(out, a, rad) { mat4.rotateZ(out.array, a.array, rad); out._dirty = true; return out; }; /** * @param {clay.Matrix4} out * @param {clay.Matrix4} a * @param {clay.Vector3} v * @return {clay.Matrix4} */ Matrix4.scale = function(out, a, v) { mat4.scale(out.array, a.array, v.array); out._dirty = true; return out; }; /** * @param {clay.Matrix4} out * @param {clay.Matrix4} a * @return {clay.Matrix4} */ Matrix4.transpose = function(out, a) { mat4.transpose(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix4} out * @param {clay.Matrix4} a * @param {clay.Vector3} v * @return {clay.Matrix4} */ Matrix4.translate = function(out, a, v) { mat4.translate(out.array, a.array, v.array); out._dirty = true; return out; }; var vec3Set = vec3.set; var vec3Copy = vec3.copy; /** * Axis aligned bounding box * @constructor * @alias clay.BoundingBox * @param {clay.Vector3} [min] * @param {clay.Vector3} [max] */ var BoundingBox = function (min, max) { /** * Minimum coords of bounding box * @type {clay.Vector3} */ this.min = min || new Vector3(Infinity, Infinity, Infinity); /** * Maximum coords of bounding box * @type {clay.Vector3} */ this.max = max || new Vector3(-Infinity, -Infinity, -Infinity); this.vertices = null; }; BoundingBox.prototype = { constructor: BoundingBox, /** * Update min and max coords from a vertices array * @param {array} vertices */ updateFromVertices: function (vertices) { if (vertices.length > 0) { var min = this.min; var max = this.max; var minArr = min.array; var maxArr = max.array; vec3Copy(minArr, vertices[0]); vec3Copy(maxArr, vertices[0]); for (var i = 1; i < vertices.length; i++) { var vertex = vertices[i]; if (vertex[0] < minArr[0]) { minArr[0] = vertex[0]; } if (vertex[1] < minArr[1]) { minArr[1] = vertex[1]; } if (vertex[2] < minArr[2]) { minArr[2] = vertex[2]; } if (vertex[0] > maxArr[0]) { maxArr[0] = vertex[0]; } if (vertex[1] > maxArr[1]) { maxArr[1] = vertex[1]; } if (vertex[2] > maxArr[2]) { maxArr[2] = vertex[2]; } } min._dirty = true; max._dirty = true; } }, /** * Union operation with another bounding box * @param {clay.BoundingBox} bbox */ union: function (bbox) { var min = this.min; var max = this.max; vec3.min(min.array, min.array, bbox.min.array); vec3.max(max.array, max.array, bbox.max.array); min._dirty = true; max._dirty = true; return this; }, /** * Intersection operation with another bounding box * @param {clay.BoundingBox} bbox */ intersection: function (bbox) { var min = this.min; var max = this.max; vec3.max(min.array, min.array, bbox.min.array); vec3.min(max.array, max.array, bbox.max.array); min._dirty = true; max._dirty = true; return this; }, /** * If intersect with another bounding box * @param {clay.BoundingBox} bbox * @return {boolean} */ intersectBoundingBox: function (bbox) { var _min = this.min.array; var _max = this.max.array; var _min2 = bbox.min.array; var _max2 = bbox.max.array; return ! (_min[0] > _max2[0] || _min[1] > _max2[1] || _min[2] > _max2[2] || _max[0] < _min2[0] || _max[1] < _min2[1] || _max[2] < _min2[2]); }, /** * If contain another bounding box entirely * @param {clay.BoundingBox} bbox * @return {boolean} */ containBoundingBox: function (bbox) { var _min = this.min.array; var _max = this.max.array; var _min2 = bbox.min.array; var _max2 = bbox.max.array; return _min[0] <= _min2[0] && _min[1] <= _min2[1] && _min[2] <= _min2[2] && _max[0] >= _max2[0] && _max[1] >= _max2[1] && _max[2] >= _max2[2]; }, /** * If contain point entirely * @param {clay.Vector3} point * @return {boolean} */ containPoint: function (p) { var _min = this.min.array; var _max = this.max.array; var _p = p.array; return _min[0] <= _p[0] && _min[1] <= _p[1] && _min[2] <= _p[2] && _max[0] >= _p[0] && _max[1] >= _p[1] && _max[2] >= _p[2]; }, /** * If bounding box is finite */ isFinite: function () { var _min = this.min.array; var _max = this.max.array; return isFinite(_min[0]) && isFinite(_min[1]) && isFinite(_min[2]) && isFinite(_max[0]) && isFinite(_max[1]) && isFinite(_max[2]); }, /** * Apply an affine transform matrix to the bounding box * @param {clay.Matrix4} matrix */ applyTransform: function (matrix) { this.transformFrom(this, matrix); }, /** * Get from another bounding box and an affine transform matrix. * @param {clay.BoundingBox} source * @param {clay.Matrix4} matrix */ transformFrom: (function () { // http://dev.theomader.com/transform-bounding-boxes/ var xa = vec3.create(); var xb = vec3.create(); var ya = vec3.create(); var yb = vec3.create(); var za = vec3.create(); var zb = vec3.create(); return function (source, matrix) { var min = source.min.array; var max = source.max.array; var m = matrix.array; xa[0] = m[0] * min[0]; xa[1] = m[1] * min[0]; xa[2] = m[2] * min[0]; xb[0] = m[0] * max[0]; xb[1] = m[1] * max[0]; xb[2] = m[2] * max[0]; ya[0] = m[4] * min[1]; ya[1] = m[5] * min[1]; ya[2] = m[6] * min[1]; yb[0] = m[4] * max[1]; yb[1] = m[5] * max[1]; yb[2] = m[6] * max[1]; za[0] = m[8] * min[2]; za[1] = m[9] * min[2]; za[2] = m[10] * min[2]; zb[0] = m[8] * max[2]; zb[1] = m[9] * max[2]; zb[2] = m[10] * max[2]; min = this.min.array; max = this.max.array; min[0] = Math.min(xa[0], xb[0]) + Math.min(ya[0], yb[0]) + Math.min(za[0], zb[0]) + m[12]; min[1] = Math.min(xa[1], xb[1]) + Math.min(ya[1], yb[1]) + Math.min(za[1], zb[1]) + m[13]; min[2] = Math.min(xa[2], xb[2]) + Math.min(ya[2], yb[2]) + Math.min(za[2], zb[2]) + m[14]; max[0] = Math.max(xa[0], xb[0]) + Math.max(ya[0], yb[0]) + Math.max(za[0], zb[0]) + m[12]; max[1] = Math.max(xa[1], xb[1]) + Math.max(ya[1], yb[1]) + Math.max(za[1], zb[1]) + m[13]; max[2] = Math.max(xa[2], xb[2]) + Math.max(ya[2], yb[2]) + Math.max(za[2], zb[2]) + m[14]; this.min._dirty = true; this.max._dirty = true; return this; }; })(), /** * Apply a projection matrix to the bounding box * @param {clay.Matrix4} matrix */ applyProjection: function (matrix) { var min = this.min.array; var max = this.max.array; var m = matrix.array; // min in min z var v10 = min[0]; var v11 = min[1]; var v12 = min[2]; // max in min z var v20 = max[0]; var v21 = max[1]; var v22 = min[2]; // max in max z var v30 = max[0]; var v31 = max[1]; var v32 = max[2]; if (m[15] === 1) { // Orthographic projection min[0] = m[0] * v10 + m[12]; min[1] = m[5] * v11 + m[13]; max[2] = m[10] * v12 + m[14]; max[0] = m[0] * v30 + m[12]; max[1] = m[5] * v31 + m[13]; min[2] = m[10] * v32 + m[14]; } else { var w = -1 / v12; min[0] = m[0] * v10 * w; min[1] = m[5] * v11 * w; max[2] = (m[10] * v12 + m[14]) * w; w = -1 / v22; max[0] = m[0] * v20 * w; max[1] = m[5] * v21 * w; w = -1 / v32; min[2] = (m[10] * v32 + m[14]) * w; } this.min._dirty = true; this.max._dirty = true; return this; }, updateVertices: function () { var vertices = this.vertices; if (!vertices) { // Cube vertices vertices = []; for (var i = 0; i < 8; i++) { vertices[i] = vec3.fromValues(0, 0, 0); } /** * Eight coords of bounding box * @type {Float32Array[]} */ this.vertices = vertices; } var min = this.min.array; var max = this.max.array; //--- min z // min x vec3Set(vertices[0], min[0], min[1], min[2]); vec3Set(vertices[1], min[0], max[1], min[2]); // max x vec3Set(vertices[2], max[0], min[1], min[2]); vec3Set(vertices[3], max[0], max[1], min[2]); //-- max z vec3Set(vertices[4], min[0], min[1], max[2]); vec3Set(vertices[5], min[0], max[1], max[2]); vec3Set(vertices[6], max[0], min[1], max[2]); vec3Set(vertices[7], max[0], max[1], max[2]); return this; }, /** * Copy values from another bounding box * @param {clay.BoundingBox} bbox */ copy: function (bbox) { var min = this.min; var max = this.max; vec3Copy(min.array, bbox.min.array); vec3Copy(max.array, bbox.max.array); min._dirty = true; max._dirty = true; return this; }, /** * Clone a new bounding box * @return {clay.BoundingBox} */ clone: function () { var boundingBox = new BoundingBox(); boundingBox.copy(this); return boundingBox; } }; var nameId = 0; /** * @constructor clay.Node * @extends clay.core.Base */ var Node = Base.extend(/** @lends clay.Node# */{ /** * Scene node name * @type {string} */ name: '', /** * Position relative to its parent node. aka translation. * @type {clay.Vector3} */ position: null, /** * Rotation relative to its parent node. Represented by a quaternion * @type {clay.Quaternion} */ rotation: null, /** * Scale relative to its parent node * @type {clay.Vector3} */ scale: null, /** * Affine transform matrix relative to its root scene. * @type {clay.Matrix4} */ worldTransform: null, /** * Affine transform matrix relative to its parent node. * Composited with position, rotation and scale. * @type {clay.Matrix4} */ localTransform: null, /** * If the local transform is update from SRT(scale, rotation, translation, which is position here) each frame * @type {boolean} */ autoUpdateLocalTransform: true, /** * Parent of current scene node * @type {?clay.Node} * @private */ _parent: null, /** * The root scene mounted. Null if it is a isolated node * @type {?clay.Scene} * @private */ _scene: null, /** * @type {boolean} * @private */ _needsUpdateWorldTransform: true, /** * @type {boolean} * @private */ _inIterating: false, // Depth for transparent list sorting __depth: 0 }, function () { if (!this.name) { this.name = (this.type || 'NODE') + '_' + (nameId++); } if (!this.position) { this.position = new Vector3(); } if (!this.rotation) { this.rotation = new Quaternion(); } if (!this.scale) { this.scale = new Vector3(1, 1, 1); } this.worldTransform = new Matrix4(); this.localTransform = new Matrix4(); this._children = []; }, /**@lends clay.Node.prototype. */ { /** * @type {?clay.Vector3} * @instance */ target: null, /** * If node and its chilren invisible * @type {boolean} * @instance */ invisible: false, /** * If Node is a skinned mesh * @return {boolean} */ isSkinnedMesh: function () { return false; }, /** * Return true if it is a renderable scene node, like Mesh and ParticleSystem * @return {boolean} */ isRenderable: function () { return false; }, /** * Set the name of the scene node * @param {string} name */ setName: function (name) { var scene = this._scene; if (scene) { var nodeRepository = scene._nodeRepository; delete nodeRepository[this.name]; nodeRepository[name] = this; } this.name = name; }, /** * Add a child node * @param {clay.Node} node */ add: function (node) { var originalParent = node._parent; if (originalParent === this) { return; } if (originalParent) { originalParent.remove(node); } node._parent = this; this._children.push(node); var scene = this._scene; if (scene && scene !== node.scene) { node.traverse(this._addSelfToScene, this); } // Mark children needs update transform // In case child are remove and added again after parent moved node._needsUpdateWorldTransform = true; }, /** * Remove the given child scene node * @param {clay.Node} node */ remove: function (node) { var children = this._children; var idx = children.indexOf(node); if (idx < 0) { return; } children.splice(idx, 1); node._parent = null; if (this._scene) { node.traverse(this._removeSelfFromScene, this); } }, /** * Remove all children */ removeAll: function () { var children = this._children; for (var idx = 0; idx < children.length; idx++) { children[idx]._parent = null; if (this._scene) { children[idx].traverse(this._removeSelfFromScene, this); } } this._children = []; }, /** * Get the scene mounted * @return {clay.Scene} */ getScene: function () { return this._scene; }, /** * Get parent node * @return {clay.Scene} */ getParent: function () { return this._parent; }, _removeSelfFromScene: function (descendant) { descendant._scene.removeFromScene(descendant); descendant._scene = null; }, _addSelfToScene: function (descendant) { this._scene.addToScene(descendant); descendant._scene = this._scene; }, /** * Return true if it is ancestor of the given scene node * @param {clay.Node} node */ isAncestor: function (node) { var parent = node._parent; while(parent) { if (parent === this) { return true; } parent = parent._parent; } return false; }, /** * Get a new created array of all children nodes * @return {clay.Node[]} */ children: function () { return this._children.slice(); }, /** * Get child scene node at given index. * @param {number} idx * @return {clay.Node} */ childAt: function (idx) { return this._children[idx]; }, /** * Get first child with the given name * @param {string} name * @return {clay.Node} */ getChildByName: function (name) { var children = this._children; for (var i = 0; i < children.length; i++) { if (children[i].name === name) { return children[i]; } } }, /** * Get first descendant have the given name * @param {string} name * @return {clay.Node} */ getDescendantByName: function (name) { var children = this._children; for (var i = 0; i < children.length; i++) { var child = children[i]; if (child.name === name) { return child; } else { var res = child.getDescendantByName(name); if (res) { return res; } } } }, /** * Query descendant node by path * @param {string} path * @return {clay.Node} * @example * node.queryNode('root/parent/child'); */ queryNode: function (path) { if (!path) { return; } // TODO Name have slash ? var pathArr = path.split('/'); var current = this; for (var i = 0; i < pathArr.length; i++) { var name = pathArr[i]; // Skip empty if (!name) { continue; } var found = false; var children = current._children; for (var j = 0; j < children.length; j++) { var child = children[j]; if (child.name === name) { current = child; found = true; break; } } // Early return if not found if (!found) { return; } } return current; }, /** * Get query path, relative to rootNode(default is scene) * @param {clay.Node} [rootNode] * @return {string} */ getPath: function (rootNode) { if (!this._parent) { return '/'; } var current = this._parent; var path = this.name; while (current._parent) { path = current.name + '/' + path; if (current._parent == rootNode) { break; } current = current._parent; } if (!current._parent && rootNode) { return null; } return path; }, /** * Depth first traverse all its descendant scene nodes. * * **WARN** Don't do `add`, `remove` operation in the callback during traverse. * @param {Function} callback * @param {Node} [context] */ traverse: function (callback, context) { callback.call(context, this); var _children = this._children; for(var i = 0, len = _children.length; i < len; i++) { _children[i].traverse(callback, context); } }, /** * Traverse all children nodes. * * **WARN** DON'T do `add`, `remove` operation in the callback during iteration. * * @param {Function} callback * @param {Node} [context] */ eachChild: function (callback, context) { var _children = this._children; for(var i = 0, len = _children.length; i < len; i++) { var child = _children[i]; callback.call(context, child, i); } }, /** * Set the local transform and decompose to SRT * @param {clay.Matrix4} matrix */ setLocalTransform: function (matrix) { mat4.copy(this.localTransform.array, matrix.array); this.decomposeLocalTransform(); }, /** * Decompose the local transform to SRT */ decomposeLocalTransform: function (keepScale) { var scale = !keepScale ? this.scale: null; this.localTransform.decomposeMatrix(scale, this.rotation, this.position); }, /** * Set the world transform and decompose to SRT * @param {clay.Matrix4} matrix */ setWorldTransform: function (matrix) { mat4.copy(this.worldTransform.array, matrix.array); this.decomposeWorldTransform(); }, /** * Decompose the world transform to SRT * @function */ decomposeWorldTransform: (function () { var tmp = mat4.create(); return function (keepScale) { var localTransform = this.localTransform; var worldTransform = this.worldTransform; // Assume world transform is updated if (this._parent) { mat4.invert(tmp, this._parent.worldTransform.array); mat4.multiply(localTransform.array, tmp, worldTransform.array); } else { mat4.copy(localTransform.array, worldTransform.array); } var scale = !keepScale ? this.scale: null; localTransform.decomposeMatrix(scale, this.rotation, this.position); }; })(), transformNeedsUpdate: function () { return this.position._dirty || this.rotation._dirty || this.scale._dirty; }, /** * Update local transform from SRT * Notice that local transform will not be updated if _dirty mark of position, rotation, scale is all false */ updateLocalTransform: function () { var position = this.position; var rotation = this.rotation; var scale = this.scale; if (this.transformNeedsUpdate()) { var m = this.localTransform.array; // Transform order, scale->rotation->position mat4.fromRotationTranslation(m, rotation.array, position.array); mat4.scale(m, m, scale.array); rotation._dirty = false; scale._dirty = false; position._dirty = false; this._needsUpdateWorldTransform = true; } }, /** * Update world transform, assume its parent world transform have been updated * @private */ _updateWorldTransformTopDown: function () { var localTransform = this.localTransform.array; var worldTransform = this.worldTransform.array; if (this._parent) { mat4.multiplyAffine( worldTransform, this._parent.worldTransform.array, localTransform ); } else { mat4.copy(worldTransform, localTransform); } }, /** * Update world transform before whole scene is updated. */ updateWorldTransform: function () { // Find the root node which transform needs update; var rootNodeIsDirty = this; while (rootNodeIsDirty && rootNodeIsDirty.getParent() && rootNodeIsDirty.getParent().transformNeedsUpdate() ) { rootNodeIsDirty = rootNodeIsDirty.getParent(); } rootNodeIsDirty.update(); }, /** * Update local transform and world transform recursively * @param {boolean} forceUpdateWorld */ update: function (forceUpdateWorld) { if (this.autoUpdateLocalTransform) { this.updateLocalTransform(); } else { // Transform is manually setted forceUpdateWorld = true; } if (forceUpdateWorld || this._needsUpdateWorldTransform) { this._updateWorldTransformTopDown(); forceUpdateWorld = true; this._needsUpdateWorldTransform = false; } var children = this._children; for(var i = 0, len = children.length; i < len; i++) { children[i].update(forceUpdateWorld); } }, /** * Get bounding box of node * @param {Function} [filter] * @param {clay.BoundingBox} [out] * @return {clay.BoundingBox} */ // TODO Skinning getBoundingBox: (function () { function defaultFilter (el) { return !el.invisible && el.geometry; } var tmpBBox = new BoundingBox(); var tmpMat4 = new Matrix4(); var invWorldTransform = new Matrix4(); return function (filter, out) { out = out || new BoundingBox(); filter = filter || defaultFilter; if (this._parent) { Matrix4.invert(invWorldTransform, this._parent.worldTransform); } else { Matrix4.identity(invWorldTransform); } this.traverse(function (mesh) { if (mesh.geometry && mesh.geometry.boundingBox) { tmpBBox.copy(mesh.geometry.boundingBox); Matrix4.multiply(tmpMat4, invWorldTransform, mesh.worldTransform); tmpBBox.applyTransform(tmpMat4); out.union(tmpBBox); } }, this, defaultFilter); return out; }; })(), /** * Get world position, extracted from world transform * @param {clay.Vector3} [out] * @return {clay.Vector3} */ getWorldPosition: function (out) { // PENDING if (this.transformNeedsUpdate()) { this.updateWorldTransform(); } var m = this.worldTransform.array; if (out) { var arr = out.array; arr[0] = m[12]; arr[1] = m[13]; arr[2] = m[14]; return out; } else { return new Vector3(m[12], m[13], m[14]); } }, /** * Clone a new node * @return {Node} */ clone: function () { var node = new this.constructor(); var children = this._children; node.setName(this.name); node.position.copy(this.position); node.rotation.copy(this.rotation); node.scale.copy(this.scale); for (var i = 0; i < children.length; i++) { node.add(children[i].clone()); } return node; }, /** * Rotate the node around a axis by angle degrees, axis passes through point * @param {clay.Vector3} point Center point * @param {clay.Vector3} axis Center axis * @param {number} angle Rotation angle * @see http://docs.unity3d.com/Documentation/ScriptReference/Transform.RotateAround.html * @function */ rotateAround: (function () { var v = new Vector3(); var RTMatrix = new Matrix4(); // TODO improve performance return function (point, axis, angle) { v.copy(this.position).subtract(point); var localTransform = this.localTransform; localTransform.identity(); // parent node localTransform.translate(point); localTransform.rotate(angle, axis); RTMatrix.fromRotationTranslation(this.rotation, v); localTransform.multiply(RTMatrix); localTransform.scale(this.scale); this.decomposeLocalTransform(); this._needsUpdateWorldTransform = true; }; })(), /** * @param {clay.Vector3} target * @param {clay.Vector3} [up] * @see http://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml * @function */ lookAt: (function () { var m = new Matrix4(); return function (target, up) { m.lookAt(this.position, target, up || this.localTransform.y).invert(); this.setLocalTransform(m); this.target = target; }; })() }); var calcAmbientSHLightEssl = "vec3 calcAmbientSHLight(int idx, vec3 N) {\n int offset = 9 * idx;\n return ambientSHLightCoefficients[0]\n + ambientSHLightCoefficients[1] * N.x\n + ambientSHLightCoefficients[2] * N.y\n + ambientSHLightCoefficients[3] * N.z\n + ambientSHLightCoefficients[4] * N.x * N.z\n + ambientSHLightCoefficients[5] * N.z * N.y\n + ambientSHLightCoefficients[6] * N.y * N.x\n + ambientSHLightCoefficients[7] * (3.0 * N.z * N.z - 1.0)\n + ambientSHLightCoefficients[8] * (N.x * N.x - N.y * N.y);\n}"; var uniformVec3Prefix = 'uniform vec3 '; var uniformFloatPrefix = 'uniform float '; var exportHeaderPrefix = '@export clay.header.'; var exportEnd = '@end'; var unconfigurable = ':unconfigurable;'; var lightEssl = [ exportHeaderPrefix + 'directional_light', uniformVec3Prefix + 'directionalLightDirection[DIRECTIONAL_LIGHT_COUNT]' + unconfigurable, uniformVec3Prefix + 'directionalLightColor[DIRECTIONAL_LIGHT_COUNT]' + unconfigurable, exportEnd, exportHeaderPrefix + 'ambient_light', uniformVec3Prefix + 'ambientLightColor[AMBIENT_LIGHT_COUNT]' + unconfigurable, exportEnd, exportHeaderPrefix + 'ambient_sh_light', uniformVec3Prefix + 'ambientSHLightColor[AMBIENT_SH_LIGHT_COUNT]' + unconfigurable, uniformVec3Prefix + 'ambientSHLightCoefficients[AMBIENT_SH_LIGHT_COUNT * 9]' + unconfigurable, calcAmbientSHLightEssl, exportEnd, exportHeaderPrefix + 'ambient_cubemap_light', uniformVec3Prefix + 'ambientCubemapLightColor[AMBIENT_CUBEMAP_LIGHT_COUNT]' + unconfigurable, 'uniform samplerCube ambientCubemapLightCubemap[AMBIENT_CUBEMAP_LIGHT_COUNT]' + unconfigurable, 'uniform sampler2D ambientCubemapLightBRDFLookup[AMBIENT_CUBEMAP_LIGHT_COUNT]' + unconfigurable, exportEnd, exportHeaderPrefix + 'point_light', uniformVec3Prefix + 'pointLightPosition[POINT_LIGHT_COUNT]' + unconfigurable, uniformFloatPrefix + 'pointLightRange[POINT_LIGHT_COUNT]' + unconfigurable, uniformVec3Prefix + 'pointLightColor[POINT_LIGHT_COUNT]' + unconfigurable, exportEnd, exportHeaderPrefix + 'spot_light', uniformVec3Prefix + 'spotLightPosition[SPOT_LIGHT_COUNT]' + unconfigurable, uniformVec3Prefix + 'spotLightDirection[SPOT_LIGHT_COUNT]' + unconfigurable, uniformFloatPrefix + 'spotLightRange[SPOT_LIGHT_COUNT]' + unconfigurable, uniformFloatPrefix + 'spotLightUmbraAngleCosine[SPOT_LIGHT_COUNT]' + unconfigurable, uniformFloatPrefix + 'spotLightPenumbraAngleCosine[SPOT_LIGHT_COUNT]' + unconfigurable, uniformFloatPrefix + 'spotLightFalloffFactor[SPOT_LIGHT_COUNT]' + unconfigurable, uniformVec3Prefix + 'spotLightColor[SPOT_LIGHT_COUNT]' + unconfigurable, exportEnd ].join('\n'); Shader['import'](lightEssl); /** * @constructor clay.Light * @extends clay.Node */ var Light = Node.extend(function(){ return /** @lends clay.Light# */ { /** * Light RGB color * @type {number[]} */ color: [1, 1, 1], /** * Light intensity * @type {number} */ intensity: 1.0, // Config for shadow map /** * If light cast shadow * @type {boolean} */ castShadow: true, /** * Shadow map size * @type {number} */ shadowResolution: 512, /** * Light group, shader with same `lightGroup` will be affected * * Only useful in forward rendering * @type {number} */ group: 0 }; }, /** @lends clay.Light.prototype. */ { /** * Light type * @type {string} * @memberOf clay.Light# */ type: '', /** * @return {clay.Light} * @memberOf clay.Light.prototype */ clone: function() { var light = Node.prototype.clone.call(this); light.color = Array.prototype.slice.call(this.color); light.intensity = this.intensity; light.castShadow = this.castShadow; light.shadowResolution = this.shadowResolution; return light; } }); /** * @constructor * @alias clay.Plane * @param {clay.Vector3} [normal] * @param {number} [distance] */ var Plane$1 = function(normal, distance) { /** * Normal of the plane * @type {clay.Vector3} */ this.normal = normal || new Vector3(0, 1, 0); /** * Constant of the plane equation, used as distance to the origin * @type {number} */ this.distance = distance || 0; }; Plane$1.prototype = { constructor: Plane$1, /** * Distance from a given point to the plane * @param {clay.Vector3} point * @return {number} */ distanceToPoint: function(point) { return vec3.dot(point.array, this.normal.array) - this.distance; }, /** * Calculate the projection point on the plane * @param {clay.Vector3} point * @param {clay.Vector3} out * @return {clay.Vector3} */ projectPoint: function(point, out) { if (!out) { out = new Vector3(); } var d = this.distanceToPoint(point); vec3.scaleAndAdd(out.array, point.array, this.normal.array, -d); out._dirty = true; return out; }, /** * Normalize the plane's normal and calculate the distance */ normalize: function() { var invLen = 1 / vec3.len(this.normal.array); vec3.scale(this.normal.array, invLen); this.distance *= invLen; }, /** * If the plane intersect a frustum * @param {clay.Frustum} Frustum * @return {boolean} */ intersectFrustum: function(frustum) { // Check if all coords of frustum is on plane all under plane var coords = frustum.vertices; var normal = this.normal.array; var onPlane = vec3.dot(coords[0].array, normal) > this.distance; for (var i = 1; i < 8; i++) { if ((vec3.dot(coords[i].array, normal) > this.distance) != onPlane) { return true; } } }, /** * Calculate the intersection point between plane and a given line * @function * @param {clay.Vector3} start start point of line * @param {clay.Vector3} end end point of line * @param {clay.Vector3} [out] * @return {clay.Vector3} */ intersectLine: (function() { var rd = vec3.create(); return function(start, end, out) { var d0 = this.distanceToPoint(start); var d1 = this.distanceToPoint(end); if ((d0 > 0 && d1 > 0) || (d0 < 0 && d1 < 0)) { return null; } // Ray intersection var pn = this.normal.array; var d = this.distance; var ro = start.array; // direction vec3.sub(rd, end.array, start.array); vec3.normalize(rd, rd); var divider = vec3.dot(pn, rd); // ray is parallel to the plane if (divider === 0) { return null; } if (!out) { out = new Vector3(); } var t = (vec3.dot(pn, ro) - d) / divider; vec3.scaleAndAdd(out.array, ro, rd, -t); out._dirty = true; return out; }; })(), /** * Apply an affine transform matrix to plane * @function * @return {clay.Matrix4} */ applyTransform: (function() { var inverseTranspose = mat4.create(); var normalv4 = vec4.create(); var pointv4 = vec4.create(); pointv4[3] = 1; return function(m4) { m4 = m4.array; // Transform point on plane vec3.scale(pointv4, this.normal.array, this.distance); vec4.transformMat4(pointv4, pointv4, m4); this.distance = vec3.dot(pointv4, this.normal.array); // Transform plane normal mat4.invert(inverseTranspose, m4); mat4.transpose(inverseTranspose, inverseTranspose); normalv4[3] = 0; vec3.copy(normalv4, this.normal.array); vec4.transformMat4(normalv4, normalv4, inverseTranspose); vec3.copy(this.normal.array, normalv4); }; })(), /** * Copy from another plane * @param {clay.Vector3} plane */ copy: function(plane) { vec3.copy(this.normal.array, plane.normal.array); this.normal._dirty = true; this.distance = plane.distance; }, /** * Clone a new plane * @return {clay.Plane} */ clone: function() { var plane = new Plane$1(); plane.copy(this); return plane; } }; var vec3Set$1 = vec3.set; var vec3Copy$1 = vec3.copy; var vec3TranformMat4 = vec3.transformMat4; var mathMin = Math.min; var mathMax = Math.max; /** * @constructor * @alias clay.Frustum */ var Frustum = function() { /** * Eight planes to enclose the frustum * @type {clay.Plane[]} */ this.planes = []; for (var i = 0; i < 6; i++) { this.planes.push(new Plane$1()); } /** * Bounding box of frustum * @type {clay.BoundingBox} */ this.boundingBox = new BoundingBox(); /** * Eight vertices of frustum * @type {Float32Array[]} */ this.vertices = []; for (var i = 0; i < 8; i++) { this.vertices[i] = vec3.fromValues(0, 0, 0); } }; Frustum.prototype = { // http://web.archive.org/web/20120531231005/http://crazyjoke.free.fr/doc/3D/plane%20extraction.pdf /** * Set frustum from a projection matrix * @param {clay.Matrix4} projectionMatrix */ setFromProjection: function(projectionMatrix) { var planes = this.planes; var m = projectionMatrix.array; var m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3]; var m4 = m[4], m5 = m[5], m6 = m[6], m7 = m[7]; var m8 = m[8], m9 = m[9], m10 = m[10], m11 = m[11]; var m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15]; // Update planes vec3Set$1(planes[0].normal.array, m3 - m0, m7 - m4, m11 - m8); planes[0].distance = -(m15 - m12); planes[0].normalize(); vec3Set$1(planes[1].normal.array, m3 + m0, m7 + m4, m11 + m8); planes[1].distance = -(m15 + m12); planes[1].normalize(); vec3Set$1(planes[2].normal.array, m3 + m1, m7 + m5, m11 + m9); planes[2].distance = -(m15 + m13); planes[2].normalize(); vec3Set$1(planes[3].normal.array, m3 - m1, m7 - m5, m11 - m9); planes[3].distance = -(m15 - m13); planes[3].normalize(); vec3Set$1(planes[4].normal.array, m3 - m2, m7 - m6, m11 - m10); planes[4].distance = -(m15 - m14); planes[4].normalize(); vec3Set$1(planes[5].normal.array, m3 + m2, m7 + m6, m11 + m10); planes[5].distance = -(m15 + m14); planes[5].normalize(); // Perspective projection var boundingBox = this.boundingBox; var vertices = this.vertices; if (m15 === 0) { var aspect = m5 / m0; var zNear = -m14 / (m10 - 1); var zFar = -m14 / (m10 + 1); var farY = -zFar / m5; var nearY = -zNear / m5; // Update bounding box boundingBox.min.set(-farY * aspect, -farY, zFar); boundingBox.max.set(farY * aspect, farY, zNear); // update vertices //--- min z // min x vec3Set$1(vertices[0], -farY * aspect, -farY, zFar); vec3Set$1(vertices[1], -farY * aspect, farY, zFar); // max x vec3Set$1(vertices[2], farY * aspect, -farY, zFar); vec3Set$1(vertices[3], farY * aspect, farY, zFar); //-- max z vec3Set$1(vertices[4], -nearY * aspect, -nearY, zNear); vec3Set$1(vertices[5], -nearY * aspect, nearY, zNear); vec3Set$1(vertices[6], nearY * aspect, -nearY, zNear); vec3Set$1(vertices[7], nearY * aspect, nearY, zNear); } else { // Orthographic projection var left = (-1 - m12) / m0; var right = (1 - m12) / m0; var top = (1 - m13) / m5; var bottom = (-1 - m13) / m5; var near = (-1 - m14) / m10; var far = (1 - m14) / m10; boundingBox.min.set(Math.min(left, right), Math.min(bottom, top), Math.min(far, near)); boundingBox.max.set(Math.max(right, left), Math.max(top, bottom), Math.max(near, far)); var min = boundingBox.min.array; var max = boundingBox.max.array; //--- min z // min x vec3Set$1(vertices[0], min[0], min[1], min[2]); vec3Set$1(vertices[1], min[0], max[1], min[2]); // max x vec3Set$1(vertices[2], max[0], min[1], min[2]); vec3Set$1(vertices[3], max[0], max[1], min[2]); //-- max z vec3Set$1(vertices[4], min[0], min[1], max[2]); vec3Set$1(vertices[5], min[0], max[1], max[2]); vec3Set$1(vertices[6], max[0], min[1], max[2]); vec3Set$1(vertices[7], max[0], max[1], max[2]); } }, /** * Apply a affine transform matrix and set to the given bounding box * @function * @param {clay.BoundingBox} * @param {clay.Matrix4} * @return {clay.BoundingBox} */ getTransformedBoundingBox: (function() { var tmpVec3 = vec3.create(); return function(bbox, matrix) { var vertices = this.vertices; var m4 = matrix.array; var min = bbox.min; var max = bbox.max; var minArr = min.array; var maxArr = max.array; var v = vertices[0]; vec3TranformMat4(tmpVec3, v, m4); vec3Copy$1(minArr, tmpVec3); vec3Copy$1(maxArr, tmpVec3); for (var i = 1; i < 8; i++) { v = vertices[i]; vec3TranformMat4(tmpVec3, v, m4); minArr[0] = mathMin(tmpVec3[0], minArr[0]); minArr[1] = mathMin(tmpVec3[1], minArr[1]); minArr[2] = mathMin(tmpVec3[2], minArr[2]); maxArr[0] = mathMax(tmpVec3[0], maxArr[0]); maxArr[1] = mathMax(tmpVec3[1], maxArr[1]); maxArr[2] = mathMax(tmpVec3[2], maxArr[2]); } min._dirty = true; max._dirty = true; return bbox; }; }) () }; var EPSILON$1 = 1e-5; /** * @constructor * @alias clay.Ray * @param {clay.Vector3} [origin] * @param {clay.Vector3} [direction] */ var Ray = function (origin, direction) { /** * @type {clay.Vector3} */ this.origin = origin || new Vector3(); /** * @type {clay.Vector3} */ this.direction = direction || new Vector3(); }; Ray.prototype = { constructor: Ray, // http://www.siggraph.org/education/materials/HyperGraph/raytrace/rayplane_intersection.htm /** * Calculate intersection point between ray and a give plane * @param {clay.Plane} plane * @param {clay.Vector3} [out] * @return {clay.Vector3} */ intersectPlane: function (plane, out) { var pn = plane.normal.array; var d = plane.distance; var ro = this.origin.array; var rd = this.direction.array; var divider = vec3.dot(pn, rd); // ray is parallel to the plane if (divider === 0) { return null; } if (!out) { out = new Vector3(); } var t = (vec3.dot(pn, ro) - d) / divider; vec3.scaleAndAdd(out.array, ro, rd, -t); out._dirty = true; return out; }, /** * Mirror the ray against plane * @param {clay.Plane} plane */ mirrorAgainstPlane: function (plane) { // Distance to plane var d = vec3.dot(plane.normal.array, this.direction.array); vec3.scaleAndAdd(this.direction.array, this.direction.array, plane.normal.array, -d * 2); this.direction._dirty = true; }, distanceToPoint: (function () { var v = vec3.create(); return function (point) { vec3.sub(v, point, this.origin.array); // Distance from projection point to origin var b = vec3.dot(v, this.direction.array); if (b < 0) { return vec3.distance(this.origin.array, point); } // Squared distance from center to origin var c2 = vec3.lenSquared(v); // Squared distance from center to projection point return Math.sqrt(c2 - b * b); }; })(), /** * Calculate intersection point between ray and sphere * @param {clay.Vector3} center * @param {number} radius * @param {clay.Vector3} out * @return {clay.Vector3} */ intersectSphere: (function () { var v = vec3.create(); return function (center, radius, out) { var origin = this.origin.array; var direction = this.direction.array; center = center.array; vec3.sub(v, center, origin); // Distance from projection point to origin var b = vec3.dot(v, direction); // Squared distance from center to origin var c2 = vec3.squaredLength(v); // Squared distance from center to projection point var d2 = c2 - b * b; var r2 = radius * radius; // No intersection if (d2 > r2) { return; } var a = Math.sqrt(r2 - d2); // First intersect point var t0 = b - a; // Second intersect point var t1 = b + a; if (!out) { out = new Vector3(); } if (t0 < 0) { if (t1 < 0) { return null; } else { vec3.scaleAndAdd(out.array, origin, direction, t1); return out; } } else { vec3.scaleAndAdd(out.array, origin, direction, t0); return out; } }; })(), // http://www.scratchapixel.com/lessons/3d-basic-lessons/lesson-7-intersecting-simple-shapes/ray-box-intersection/ /** * Calculate intersection point between ray and bounding box * @param {clay.BoundingBox} bbox * @param {clay.Vector3} * @return {clay.Vector3} */ intersectBoundingBox: function (bbox, out) { var dir = this.direction.array; var origin = this.origin.array; var min = bbox.min.array; var max = bbox.max.array; var invdirx = 1 / dir[0]; var invdiry = 1 / dir[1]; var invdirz = 1 / dir[2]; var tmin, tmax, tymin, tymax, tzmin, tzmax; if (invdirx >= 0) { tmin = (min[0] - origin[0]) * invdirx; tmax = (max[0] - origin[0]) * invdirx; } else { tmax = (min[0] - origin[0]) * invdirx; tmin = (max[0] - origin[0]) * invdirx; } if (invdiry >= 0) { tymin = (min[1] - origin[1]) * invdiry; tymax = (max[1] - origin[1]) * invdiry; } else { tymax = (min[1] - origin[1]) * invdiry; tymin = (max[1] - origin[1]) * invdiry; } if ((tmin > tymax) || (tymin > tmax)) { return null; } if (tymin > tmin || tmin !== tmin) { tmin = tymin; } if (tymax < tmax || tmax !== tmax) { tmax = tymax; } if (invdirz >= 0) { tzmin = (min[2] - origin[2]) * invdirz; tzmax = (max[2] - origin[2]) * invdirz; } else { tzmax = (min[2] - origin[2]) * invdirz; tzmin = (max[2] - origin[2]) * invdirz; } if ((tmin > tzmax) || (tzmin > tmax)) { return null; } if (tzmin > tmin || tmin !== tmin) { tmin = tzmin; } if (tzmax < tmax || tmax !== tmax) { tmax = tzmax; } if (tmax < 0) { return null; } var t = tmin >= 0 ? tmin : tmax; if (!out) { out = new Vector3(); } vec3.scaleAndAdd(out.array, origin, dir, t); return out; }, // http://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm /** * Calculate intersection point between ray and three triangle vertices * @param {clay.Vector3} a * @param {clay.Vector3} b * @param {clay.Vector3} c * @param {boolean} singleSided, CW triangle will be ignored * @param {clay.Vector3} [out] * @param {clay.Vector3} [barycenteric] barycentric coords * @return {clay.Vector3} */ intersectTriangle: (function () { var eBA = vec3.create(); var eCA = vec3.create(); var AO = vec3.create(); var vCross = vec3.create(); return function (a, b, c, singleSided, out, barycenteric) { var dir = this.direction.array; var origin = this.origin.array; a = a.array; b = b.array; c = c.array; vec3.sub(eBA, b, a); vec3.sub(eCA, c, a); vec3.cross(vCross, eCA, dir); var det = vec3.dot(eBA, vCross); if (singleSided) { if (det > -EPSILON$1) { return null; } } else { if (det > -EPSILON$1 && det < EPSILON$1) { return null; } } vec3.sub(AO, origin, a); var u = vec3.dot(vCross, AO) / det; if (u < 0 || u > 1) { return null; } vec3.cross(vCross, eBA, AO); var v = vec3.dot(dir, vCross) / det; if (v < 0 || v > 1 || (u + v > 1)) { return null; } vec3.cross(vCross, eBA, eCA); var t = -vec3.dot(AO, vCross) / det; if (t < 0) { return null; } if (!out) { out = new Vector3(); } if (barycenteric) { Vector3.set(barycenteric, (1 - u - v), u, v); } vec3.scaleAndAdd(out.array, origin, dir, t); return out; }; })(), /** * Apply an affine transform matrix to the ray * @return {clay.Matrix4} matrix */ applyTransform: function (matrix) { Vector3.add(this.direction, this.direction, this.origin); Vector3.transformMat4(this.origin, this.origin, matrix); Vector3.transformMat4(this.direction, this.direction, matrix); Vector3.sub(this.direction, this.direction, this.origin); Vector3.normalize(this.direction, this.direction); }, /** * Copy values from another ray * @param {clay.Ray} ray */ copy: function (ray) { Vector3.copy(this.origin, ray.origin); Vector3.copy(this.direction, ray.direction); }, /** * Clone a new ray * @return {clay.Ray} */ clone: function () { var ray = new Ray(); ray.copy(this); return ray; } }; /** * @constructor clay.Camera * @extends clay.Node */ var Camera = Node.extend(function () { return /** @lends clay.Camera# */ { /** * Camera projection matrix * @type {clay.Matrix4} */ projectionMatrix: new Matrix4(), /** * Inverse of camera projection matrix * @type {clay.Matrix4} */ invProjectionMatrix: new Matrix4(), /** * View matrix, equal to inverse of camera's world matrix * @type {clay.Matrix4} */ viewMatrix: new Matrix4(), /** * Camera frustum in view space * @type {clay.Frustum} */ frustum: new Frustum() }; }, function () { this.update(true); }, /** @lends clay.Camera.prototype */ { update: function (force) { Node.prototype.update.call(this, force); Matrix4.invert(this.viewMatrix, this.worldTransform); this.updateProjectionMatrix(); Matrix4.invert(this.invProjectionMatrix, this.projectionMatrix); this.frustum.setFromProjection(this.projectionMatrix); }, /** * Set camera view matrix */ setViewMatrix: function (viewMatrix) { Matrix4.copy(this.viewMatrix, viewMatrix); Matrix4.invert(this.worldTransform, viewMatrix); this.decomposeWorldTransform(); }, /** * Decompose camera projection matrix */ decomposeProjectionMatrix: function () {}, /** * Set camera projection matrix * @param {clay.Matrix4} projectionMatrix */ setProjectionMatrix: function (projectionMatrix) { Matrix4.copy(this.projectionMatrix, projectionMatrix); Matrix4.invert(this.invProjectionMatrix, projectionMatrix); this.decomposeProjectionMatrix(); }, /** * Update projection matrix, called after update */ updateProjectionMatrix: function () {}, /** * Cast a picking ray from camera near plane to far plane * @function * @param {clay.Vector2} ndc * @param {clay.Ray} [out] * @return {clay.Ray} */ castRay: (function () { var v4 = vec4.create(); return function (ndc, out) { var ray = out !== undefined ? out : new Ray(); var x = ndc.array[0]; var y = ndc.array[1]; vec4.set(v4, x, y, -1, 1); vec4.transformMat4(v4, v4, this.invProjectionMatrix.array); vec4.transformMat4(v4, v4, this.worldTransform.array); vec3.scale(ray.origin.array, v4, 1 / v4[3]); vec4.set(v4, x, y, 1, 1); vec4.transformMat4(v4, v4, this.invProjectionMatrix.array); vec4.transformMat4(v4, v4, this.worldTransform.array); vec3.scale(v4, v4, 1 / v4[3]); vec3.sub(ray.direction.array, v4, ray.origin.array); vec3.normalize(ray.direction.array, ray.direction.array); ray.direction._dirty = true; ray.origin._dirty = true; return ray; }; })(), /** * @function * @name clone * @return {clay.Camera} * @memberOf clay.Camera.prototype */ }); var IDENTITY = mat4.create(); var WORLDVIEW = mat4.create(); var programKeyCache$1 = {}; function getProgramKey$1(lightNumbers) { var defineStr = []; var lightTypes = Object.keys(lightNumbers); lightTypes.sort(); for (var i = 0; i < lightTypes.length; i++) { var lightType = lightTypes[i]; defineStr.push(lightType + ' ' + lightNumbers[lightType]); } var key = defineStr.join('\n'); if (programKeyCache$1[key]) { return programKeyCache$1[key]; } var id = util$1.genGUID(); programKeyCache$1[key] = id; return id; } function RenderList() { this.opaque = []; this.transparent = []; this._opaqueCount = 0; this._transparentCount = 0; } RenderList.prototype.startCount = function () { this._opaqueCount = 0; this._transparentCount = 0; }; RenderList.prototype.add = function (object, isTransparent) { if (isTransparent) { this.transparent[this._transparentCount++] = object; } else { this.opaque[this._opaqueCount++] = object; } }; RenderList.prototype.endCount = function () { this.transparent.length = this._transparentCount; this.opaque.length = this._opaqueCount; }; /** * @typedef {Object} clay.Scene.RenderList * @property {Array.} opaque * @property {Array.} transparent */ /** * @constructor clay.Scene * @extends clay.Node */ var Scene = Node.extend(function () { return /** @lends clay.Scene# */ { /** * Global material of scene * @type {clay.Material} */ material: null, lights: [], /** * Scene bounding box in view space. * Used when camera needs to adujst the near and far plane automatically * so that the view frustum contains the visible objects as tightly as possible. * Notice: * It is updated after rendering (in the step of frustum culling passingly). So may be not so accurate, but saves a lot of calculation * * @type {clay.BoundingBox} */ viewBoundingBoxLastFrame: new BoundingBox(), // Uniforms for shadow map. shadowUniforms: {}, _cameraList: [], // Properties to save the light information in the scene // Will be set in the render function _lightUniforms: {}, _previousLightNumber: {}, _lightNumber: { // groupId: { // POINT_LIGHT: 0, // DIRECTIONAL_LIGHT: 0, // SPOT_LIGHT: 0, // AMBIENT_LIGHT: 0, // AMBIENT_SH_LIGHT: 0 // } }, _lightProgramKeys: {}, _nodeRepository: {}, _renderLists: new LRU$1(20) }; }, function () { this._scene = this; }, /** @lends clay.Scene.prototype. */ { // Add node to scene addToScene: function (node) { if (node instanceof Camera) { if (this._cameraList.length > 0) { console.warn('Found multiple camera in one scene. Use the fist one.'); } this._cameraList.push(node); } else if (node instanceof Light) { this.lights.push(node); } if (node.name) { this._nodeRepository[node.name] = node; } }, // Remove node from scene removeFromScene: function (node) { var idx; if (node instanceof Camera) { idx = this._cameraList.indexOf(node); if (idx >= 0) { this._cameraList.splice(idx, 1); } } else if (node instanceof Light) { idx = this.lights.indexOf(node); if (idx >= 0) { this.lights.splice(idx, 1); } } if (node.name) { delete this._nodeRepository[node.name]; } }, /** * Get node by name * @param {string} name * @return {Node} * @DEPRECATED */ getNode: function (name) { return this._nodeRepository[name]; }, /** * Set main camera of the scene. * @param {claygl.Camera} camera */ setMainCamera: function (camera) { var idx = this._cameraList.indexOf(camera); if (idx >= 0) { this._cameraList.splice(idx, 1); } this._cameraList.unshift(camera); }, /** * Get main camera of the scene. */ getMainCamera: function () { return this._cameraList[0]; }, getLights: function () { return this.lights; }, updateLights: function () { var lights = this.lights; this._previousLightNumber = this._lightNumber; var lightNumber = {}; for (var i = 0; i < lights.length; i++) { var light = lights[i]; if (light.invisible) { continue; } var group = light.group; if (!lightNumber[group]) { lightNumber[group] = {}; } // User can use any type of light lightNumber[group][light.type] = lightNumber[group][light.type] || 0; lightNumber[group][light.type]++; } this._lightNumber = lightNumber; for (var groupId in lightNumber) { this._lightProgramKeys[groupId] = getProgramKey$1(lightNumber[groupId]); } this._updateLightUniforms(); }, /** * Clone a node and it's children, including mesh, camera, light, etc. * Unlike using `Node#clone`. It will clone skeleton and remap the joints. Material will also be cloned. * * @param {clay.Node} node * @return {clay.Node} */ cloneNode: function (node) { var newNode = node.clone(); var clonedNodesMap = {}; function buildNodesMap(sNode, tNode) { clonedNodesMap[sNode.__uid__] = tNode; for (var i = 0; i < sNode._children.length; i++) { var sChild = sNode._children[i]; var tChild = tNode._children[i]; buildNodesMap(sChild, tChild); } } buildNodesMap(node, newNode); newNode.traverse(function (newChild) { if (newChild.skeleton) { newChild.skeleton = newChild.skeleton.clone(clonedNodesMap); } if (newChild.material) { newChild.material = newChild.material.clone(); } }); return newNode; }, /** * Traverse the scene and add the renderable object to the render list. * It needs camera for the frustum culling. * * @param {clay.Camera} camera * @param {boolean} updateSceneBoundingBox * @return {clay.Scene.RenderList} */ updateRenderList: function (camera, updateSceneBoundingBox) { var id = camera.__uid__; var renderList = this._renderLists.get(id); if (!renderList) { renderList = new RenderList(); this._renderLists.put(id, renderList); } renderList.startCount(); if (updateSceneBoundingBox) { this.viewBoundingBoxLastFrame.min.set(Infinity, Infinity, Infinity); this.viewBoundingBoxLastFrame.max.set(-Infinity, -Infinity, -Infinity); } var sceneMaterialTransparent = this.material && this.material.transparent || false; this._doUpdateRenderList(this, camera, sceneMaterialTransparent, renderList, updateSceneBoundingBox); renderList.endCount(); return renderList; }, /** * Get render list. Used after {@link clay.Scene#updateRenderList} * @param {clay.Camera} camera * @return {clay.Scene.RenderList} */ getRenderList: function (camera) { return this._renderLists.get(camera.__uid__); }, _doUpdateRenderList: function (parent, camera, sceneMaterialTransparent, renderList, updateSceneBoundingBox) { if (parent.invisible) { return; } // TODO Optimize for (var i = 0; i < parent._children.length; i++) { var child = parent._children[i]; if (child.isRenderable()) { // Frustum culling var worldM = child.isSkinnedMesh() ? IDENTITY : child.worldTransform.array; var geometry = child.geometry; mat4.multiplyAffine(WORLDVIEW, camera.viewMatrix.array, worldM); if (updateSceneBoundingBox && !geometry.boundingBox || !this.isFrustumCulled(child, camera, WORLDVIEW)) { renderList.add(child, child.material.transparent || sceneMaterialTransparent); } } if (child._children.length > 0) { this._doUpdateRenderList(child, camera, sceneMaterialTransparent, renderList, updateSceneBoundingBox); } } }, /** * If an scene object is culled by camera frustum * * Object can be a renderable or a light * * @param {clay.Node} object * @param {clay.Camera} camera * @param {Array.} worldViewMat represented with array * @param {Array.} projectionMat represented with array */ isFrustumCulled: (function () { // Frustum culling // http://www.cse.chalmers.se/~uffe/vfc_bbox.pdf var cullingBoundingBox = new BoundingBox(); var cullingMatrix = new Matrix4(); return function(object, camera, worldViewMat) { // Bounding box can be a property of object(like light) or renderable.geometry // PENDING var geoBBox = object.boundingBox; if (!geoBBox) { if (object.skeleton && object.skeleton.boundingBox) { geoBBox = object.skeleton.boundingBox; } else { geoBBox = object.geometry.boundingBox; } } if (!geoBBox) { return false; } cullingMatrix.array = worldViewMat; cullingBoundingBox.transformFrom(geoBBox, cullingMatrix); // Passingly update the scene bounding box // FIXME exclude very large mesh like ground plane or terrain ? // FIXME Only rendererable which cast shadow ? // FIXME boundingBox becomes much larger after transformd. if (object.castShadow) { this.viewBoundingBoxLastFrame.union(cullingBoundingBox); } // Ignore frustum culling if object is skinned mesh. if (object.frustumCulling) { if (!cullingBoundingBox.intersectBoundingBox(camera.frustum.boundingBox)) { return true; } cullingMatrix.array = camera.projectionMatrix.array; if ( cullingBoundingBox.max.array[2] > 0 && cullingBoundingBox.min.array[2] < 0 ) { // Clip in the near plane cullingBoundingBox.max.array[2] = -1e-20; } cullingBoundingBox.applyProjection(cullingMatrix); var min = cullingBoundingBox.min.array; var max = cullingBoundingBox.max.array; if ( max[0] < -1 || min[0] > 1 || max[1] < -1 || min[1] > 1 || max[2] < -1 || min[2] > 1 ) { return true; } } return false; }; })(), _updateLightUniforms: function () { var lights = this.lights; // Put the light cast shadow before the light not cast shadow lights.sort(lightSortFunc); var lightUniforms = this._lightUniforms; for (var group in lightUniforms) { for (var symbol in lightUniforms[group]) { lightUniforms[group][symbol].value.length = 0; } } for (var i = 0; i < lights.length; i++) { var light = lights[i]; if (light.invisible) { continue; } var group = light.group; for (var symbol in light.uniformTemplates) { var uniformTpl = light.uniformTemplates[symbol]; var value = uniformTpl.value(light); if (value == null) { continue; } if (!lightUniforms[group]) { lightUniforms[group] = {}; } if (!lightUniforms[group][symbol]) { lightUniforms[group][symbol] = { type: '', value: [] }; } var lu = lightUniforms[group][symbol]; lu.type = uniformTpl.type + 'v'; switch (uniformTpl.type) { case '1i': case '1f': case 't': lu.value.push(value); break; case '2f': case '3f': case '4f': for (var j = 0; j < value.length; j++) { lu.value.push(value[j]); } break; default: console.error('Unkown light uniform type ' + uniformTpl.type); } } } }, getLightGroups: function () { var lightGroups = []; for (var groupId in this._lightNumber) { lightGroups.push(groupId); } return lightGroups; }, getNumberChangedLightGroups: function () { var lightGroups = []; for (var groupId in this._lightNumber) { if (this.isLightNumberChanged(groupId)) { lightGroups.push(groupId); } } return lightGroups; }, // Determine if light group is different with since last frame // Used to determine whether to update shader and scene's uniforms in Renderer.render isLightNumberChanged: function (lightGroup) { var prevLightNumber = this._previousLightNumber; var currentLightNumber = this._lightNumber; // PENDING Performance for (var type in currentLightNumber[lightGroup]) { if (!prevLightNumber[lightGroup]) { return true; } if (currentLightNumber[lightGroup][type] !== prevLightNumber[lightGroup][type]) { return true; } } for (var type in prevLightNumber[lightGroup]) { if (!currentLightNumber[lightGroup]) { return true; } if (currentLightNumber[lightGroup][type] !== prevLightNumber[lightGroup][type]) { return true; } } return false; }, getLightsNumbers: function (lightGroup) { return this._lightNumber[lightGroup]; }, getProgramKey: function (lightGroup) { return this._lightProgramKeys[lightGroup]; }, setLightUniforms: (function () { function setUniforms(uniforms, program, renderer) { for (var symbol in uniforms) { var lu = uniforms[symbol]; if (lu.type === 'tv') { if (!program.hasUniform(symbol)) { continue; } var texSlots = []; for (var i = 0; i < lu.value.length; i++) { var texture = lu.value[i]; var slot = program.takeCurrentTextureSlot(renderer, texture); texSlots.push(slot); } program.setUniform(renderer.gl, '1iv', symbol, texSlots); } else { program.setUniform(renderer.gl, lu.type, symbol, lu.value); } } } return function (program, lightGroup, renderer) { setUniforms(this._lightUniforms[lightGroup], program, renderer); // Set shadows setUniforms(this.shadowUniforms, program, renderer); }; })(), /** * Dispose self, clear all the scene objects * But resources of gl like texuture, shader will not be disposed. * Mostly you should use disposeScene method in Renderer to do dispose. */ dispose: function () { this.material = null; this._opaqueList = []; this._transparentList = []; this.lights = []; this._lightUniforms = {}; this._lightNumber = {}; this._nodeRepository = {}; } }); function lightSortFunc(a, b) { if (b.castShadow && !a.castShadow) { return true; } } var DIRTY_PREFIX = '__dt__'; var Cache = function () { this._contextId = 0; this._caches = []; this._context = {}; }; Cache.prototype = { use: function (contextId, documentSchema) { var caches = this._caches; if (!caches[contextId]) { caches[contextId] = {}; if (documentSchema) { caches[contextId] = documentSchema(); } } this._contextId = contextId; this._context = caches[contextId]; }, put: function (key, value) { this._context[key] = value; }, get: function (key) { return this._context[key]; }, dirty: function (field) { field = field || ''; var key = DIRTY_PREFIX + field; this.put(key, true); }, dirtyAll: function (field) { field = field || ''; var key = DIRTY_PREFIX + field; var caches = this._caches; for (var i = 0; i < caches.length; i++) { if (caches[i]) { caches[i][key] = true; } } }, fresh: function (field) { field = field || ''; var key = DIRTY_PREFIX + field; this.put(key, false); }, freshAll: function (field) { field = field || ''; var key = DIRTY_PREFIX + field; var caches = this._caches; for (var i = 0; i < caches.length; i++) { if (caches[i]) { caches[i][key] = false; } } }, isDirty: function (field) { field = field || ''; var key = DIRTY_PREFIX + field; var context = this._context; return !context.hasOwnProperty(key) || context[key] === true; }, deleteContext: function (contextId) { delete this._caches[contextId]; this._context = {}; }, delete: function (key) { delete this._context[key]; }, clearAll: function () { this._caches = {}; }, getContext: function () { return this._context; }, eachContext : function (cb, context) { var keys = Object.keys(this._caches); keys.forEach(function (key) { cb && cb.call(context, key); }); }, miss: function (key) { return ! this._context.hasOwnProperty(key); } }; Cache.prototype.constructor = Cache; function getArrayCtorByType (type) { return ({ 'byte': vendor.Int8Array, 'ubyte': vendor.Uint8Array, 'short': vendor.Int16Array, 'ushort': vendor.Uint16Array })[type] || vendor.Float32Array; } function makeAttrKey(attrName) { return 'attr_' + attrName; } /** * GeometryBase attribute * @alias clay.GeometryBase.Attribute * @constructor */ function Attribute$1(name, type, size, semantic) { /** * Attribute name * @type {string} */ this.name = name; /** * Attribute type * Possible values: * + `'byte'` * + `'ubyte'` * + `'short'` * + `'ushort'` * + `'float'` Most commonly used. * @type {string} */ this.type = type; /** * Size of attribute component. 1 - 4. * @type {number} */ this.size = size; /** * Semantic of this attribute. * Possible values: * + `'POSITION'` * + `'NORMAL'` * + `'BINORMAL'` * + `'TANGENT'` * + `'TEXCOORD'` * + `'TEXCOORD_0'` * + `'TEXCOORD_1'` * + `'COLOR'` * + `'JOINT'` * + `'WEIGHT'` * * In shader, attribute with same semantic will be automatically mapped. For example: * ```glsl * attribute vec3 pos: POSITION * ``` * will use the attribute value with semantic POSITION in geometry, no matter what name it used. * @type {string} */ this.semantic = semantic || ''; /** * Value of the attribute. * @type {TypedArray} */ this.value = null; // Init getter setter switch (size) { case 1: this.get = function (idx) { return this.value[idx]; }; this.set = function (idx, value) { this.value[idx] = value; }; // Copy from source to target this.copy = function (target, source) { this.value[target] = this.value[target]; }; break; case 2: this.get = function (idx, out) { var arr = this.value; out[0] = arr[idx * 2]; out[1] = arr[idx * 2 + 1]; return out; }; this.set = function (idx, val) { var arr = this.value; arr[idx * 2] = val[0]; arr[idx * 2 + 1] = val[1]; }; this.copy = function (target, source) { var arr = this.value; source *= 2; target *= 2; arr[target] = arr[source]; arr[target + 1] = arr[source + 1]; }; break; case 3: this.get = function (idx, out) { var idx3 = idx * 3; var arr = this.value; out[0] = arr[idx3]; out[1] = arr[idx3 + 1]; out[2] = arr[idx3 + 2]; return out; }; this.set = function (idx, val) { var idx3 = idx * 3; var arr = this.value; arr[idx3] = val[0]; arr[idx3 + 1] = val[1]; arr[idx3 + 2] = val[2]; }; this.copy = function (target, source) { var arr = this.value; source *= 3; target *= 3; arr[target] = arr[source]; arr[target + 1] = arr[source + 1]; arr[target + 2] = arr[source + 2]; }; break; case 4: this.get = function (idx, out) { var arr = this.value; var idx4 = idx * 4; out[0] = arr[idx4]; out[1] = arr[idx4 + 1]; out[2] = arr[idx4 + 2]; out[3] = arr[idx4 + 3]; return out; }; this.set = function (idx, val) { var arr = this.value; var idx4 = idx * 4; arr[idx4] = val[0]; arr[idx4 + 1] = val[1]; arr[idx4 + 2] = val[2]; arr[idx4 + 3] = val[3]; }; this.copy = function (target, source) { var arr = this.value; source *= 4; target *= 4; // copyWithin is extremely slow arr[target] = arr[source]; arr[target + 1] = arr[source + 1]; arr[target + 2] = arr[source + 2]; arr[target + 3] = arr[source + 3]; }; } } /** * Set item value at give index. Second parameter val is number if size is 1 * @function * @name clay.GeometryBase.Attribute#set * @param {number} idx * @param {number[]|number} val * @example * geometry.getAttribute('position').set(0, [1, 1, 1]); */ /** * Get item value at give index. Second parameter out is no need if size is 1 * @function * @name clay.GeometryBase.Attribute#set * @param {number} idx * @param {number[]} [out] * @example * geometry.getAttribute('position').get(0, out); */ /** * Initialize attribute with given vertex count * @param {number} nVertex */ Attribute$1.prototype.init = function (nVertex) { if (!this.value || this.value.length != nVertex * this.size) { var ArrayConstructor = getArrayCtorByType(this.type); this.value = new ArrayConstructor(nVertex * this.size); } }; /** * Initialize attribute with given array. Which can be 1 dimensional or 2 dimensional * @param {Array} array * @example * geometry.getAttribute('position').fromArray( * [-1, 0, 0, 1, 0, 0, 0, 1, 0] * ); * geometry.getAttribute('position').fromArray( * [ [-1, 0, 0], [1, 0, 0], [0, 1, 0] ] * ); */ Attribute$1.prototype.fromArray = function (array) { var ArrayConstructor = getArrayCtorByType(this.type); var value; // Convert 2d array to flat if (array[0] && (array[0].length)) { var n = 0; var size = this.size; value = new ArrayConstructor(array.length * size); for (var i = 0; i < array.length; i++) { for (var j = 0; j < size; j++) { value[n++] = array[i][j]; } } } else { value = new ArrayConstructor(array); } this.value = value; }; Attribute$1.prototype.clone = function(copyValue) { var ret = new Attribute$1(this.name, this.type, this.size, this.semantic); // FIXME if (copyValue) { console.warn('todo'); } return ret; }; function AttributeBuffer(name, type, buffer, size, semantic) { this.name = name; this.type = type; this.buffer = buffer; this.size = size; this.semantic = semantic; // To be set in mesh // symbol in the shader this.symbol = ''; // Needs remove flag this.needsRemove = false; } function IndicesBuffer(buffer) { this.buffer = buffer; this.count = 0; } /** * Base of all geometry. Use {@link clay.Geometry} for common 3D usage. * @constructor clay.GeometryBase * @extends clay.core.Base */ var GeometryBase = Base.extend(function () { return /** @lends clay.GeometryBase# */ { /** * Attributes of geometry. * @type {Object.} */ attributes: {}, /** * Indices of geometry. * @type {Uint16Array|Uint32Array} */ indices: null, /** * Is vertices data dynamically updated. * Attributes value can't be changed after first render if dyanmic is false. * @type {boolean} */ dynamic: true, _enabledAttributes: null, // PENDING // Init it here to avoid deoptimization when it's assigned in application dynamically __used: 0 }; }, function() { // Use cache this._cache = new Cache(); this._attributeList = Object.keys(this.attributes); this.__vaoCache = {}; }, /** @lends clay.GeometryBase.prototype */ { /** * Main attribute will be used to count vertex number * @type {string} */ mainAttribute: '', /** * User defined picking algorithm instead of default * triangle ray intersection * x, y are NDC. * ```typescript * (x, y, renderer, camera, renderable, out) => boolean * ``` * @type {?Function} */ pick: null, /** * User defined ray picking algorithm instead of default * triangle ray intersection * ```typescript * (ray: clay.Ray, renderable: clay.Renderable, out: Array) => boolean * ``` * @type {?Function} */ pickByRay: null, /** * Mark attributes and indices in geometry needs to update. * Usually called after you change the data in attributes. */ dirty: function () { var enabledAttributes = this.getEnabledAttributes(); for (var i = 0; i < enabledAttributes.length; i++) { this.dirtyAttribute(enabledAttributes[i]); } this.dirtyIndices(); this._enabledAttributes = null; this._cache.dirty('any'); }, /** * Mark the indices needs to update. */ dirtyIndices: function () { this._cache.dirtyAll('indices'); }, /** * Mark the attributes needs to update. * @param {string} [attrName] */ dirtyAttribute: function (attrName) { this._cache.dirtyAll(makeAttrKey(attrName)); this._cache.dirtyAll('attributes'); }, /** * Get indices of triangle at given index. * @param {number} idx * @param {Array.} out * @return {Array.} */ getTriangleIndices: function (idx, out) { if (idx < this.triangleCount && idx >= 0) { if (!out) { out = []; } var indices = this.indices; out[0] = indices[idx * 3]; out[1] = indices[idx * 3 + 1]; out[2] = indices[idx * 3 + 2]; return out; } }, /** * Set indices of triangle at given index. * @param {number} idx * @param {Array.} arr */ setTriangleIndices: function (idx, arr) { var indices = this.indices; indices[idx * 3] = arr[0]; indices[idx * 3 + 1] = arr[1]; indices[idx * 3 + 2] = arr[2]; }, isUseIndices: function () { return !!this.indices; }, /** * Initialize indices from an array. * @param {Array} array */ initIndicesFromArray: function (array) { var value; var ArrayConstructor = this.vertexCount > 0xffff ? vendor.Uint32Array : vendor.Uint16Array; // Convert 2d array to flat if (array[0] && (array[0].length)) { var n = 0; var size = 3; value = new ArrayConstructor(array.length * size); for (var i = 0; i < array.length; i++) { for (var j = 0; j < size; j++) { value[n++] = array[i][j]; } } } else { value = new ArrayConstructor(array); } this.indices = value; }, /** * Create a new attribute * @param {string} name * @param {string} type * @param {number} size * @param {string} [semantic] */ createAttribute: function (name, type, size, semantic) { var attrib = new Attribute$1(name, type, size, semantic); if (this.attributes[name]) { this.removeAttribute(name); } this.attributes[name] = attrib; this._attributeList.push(name); return attrib; }, /** * Remove attribute * @param {string} name */ removeAttribute: function (name) { var attributeList = this._attributeList; var idx = attributeList.indexOf(name); if (idx >= 0) { attributeList.splice(idx, 1); delete this.attributes[name]; return true; } return false; }, /** * Get attribute * @param {string} name * @return {clay.GeometryBase.Attribute} */ getAttribute: function (name) { return this.attributes[name]; }, /** * Get enabled attributes name list * Attribute which has the same vertex number with position is treated as a enabled attribute * @return {string[]} */ getEnabledAttributes: function () { var enabledAttributes = this._enabledAttributes; var attributeList = this._attributeList; // Cache if (enabledAttributes) { return enabledAttributes; } var result = []; var nVertex = this.vertexCount; for (var i = 0; i < attributeList.length; i++) { var name = attributeList[i]; var attrib = this.attributes[name]; if (attrib.value) { if (attrib.value.length === nVertex * attrib.size) { result.push(name); } } } this._enabledAttributes = result; return result; }, getBufferChunks: function (renderer) { var cache = this._cache; cache.use(renderer.__uid__); var isAttributesDirty = cache.isDirty('attributes'); var isIndicesDirty = cache.isDirty('indices'); if (isAttributesDirty || isIndicesDirty) { this._updateBuffer(renderer.gl, isAttributesDirty, isIndicesDirty); var enabledAttributes = this.getEnabledAttributes(); for (var i = 0; i < enabledAttributes.length; i++) { cache.fresh(makeAttrKey(enabledAttributes[i])); } cache.fresh('attributes'); cache.fresh('indices'); } cache.fresh('any'); return cache.get('chunks'); }, _updateBuffer: function (_gl, isAttributesDirty, isIndicesDirty) { var cache = this._cache; var chunks = cache.get('chunks'); var firstUpdate = false; if (!chunks) { chunks = []; // Intialize chunks[0] = { attributeBuffers: [], indicesBuffer: null }; cache.put('chunks', chunks); firstUpdate = true; } var chunk = chunks[0]; var attributeBuffers = chunk.attributeBuffers; var indicesBuffer = chunk.indicesBuffer; if (isAttributesDirty || firstUpdate) { var attributeList = this.getEnabledAttributes(); var attributeBufferMap = {}; if (!firstUpdate) { for (var i = 0; i < attributeBuffers.length; i++) { attributeBufferMap[attributeBuffers[i].name] = attributeBuffers[i]; } } // FIXME If some attributes removed for (var k = 0; k < attributeList.length; k++) { var name = attributeList[k]; var attribute = this.attributes[name]; var bufferInfo; if (!firstUpdate) { bufferInfo = attributeBufferMap[name]; } var buffer; if (bufferInfo) { buffer = bufferInfo.buffer; } else { buffer = _gl.createBuffer(); } if (cache.isDirty(makeAttrKey(name))) { // Only update when they are dirty. // TODO: Use BufferSubData? _gl.bindBuffer(_gl.ARRAY_BUFFER, buffer); _gl.bufferData(_gl.ARRAY_BUFFER, attribute.value, this.dynamic ? glenum.DYNAMIC_DRAW : glenum.STATIC_DRAW); } attributeBuffers[k] = new AttributeBuffer(name, attribute.type, buffer, attribute.size, attribute.semantic); } // Remove unused attributes buffers. // PENDING for (var i = k; i < attributeBuffers.length; i++) { _gl.deleteBuffer(attributeBuffers[i].buffer); } attributeBuffers.length = k; } if (this.isUseIndices() && (isIndicesDirty || firstUpdate)) { if (!indicesBuffer) { indicesBuffer = new IndicesBuffer(_gl.createBuffer()); chunk.indicesBuffer = indicesBuffer; } indicesBuffer.count = this.indices.length; _gl.bindBuffer(_gl.ELEMENT_ARRAY_BUFFER, indicesBuffer.buffer); _gl.bufferData(_gl.ELEMENT_ARRAY_BUFFER, this.indices, this.dynamic ? glenum.DYNAMIC_DRAW : glenum.STATIC_DRAW); } }, /** * Dispose geometry data in GL context. * @param {clay.Renderer} renderer */ dispose: function (renderer) { var cache = this._cache; cache.use(renderer.__uid__); var chunks = cache.get('chunks'); if (chunks) { for (var c = 0; c < chunks.length; c++) { var chunk = chunks[c]; for (var k = 0; k < chunk.attributeBuffers.length; k++) { var attribs = chunk.attributeBuffers[k]; renderer.gl.deleteBuffer(attribs.buffer); } if (chunk.indicesBuffer) { renderer.gl.deleteBuffer(chunk.indicesBuffer.buffer); } } } if (this.__vaoCache) { var vaoExt = renderer.getGLExtension('OES_vertex_array_object'); for (var id in this.__vaoCache) { var vao = this.__vaoCache[id].vao; if (vao) { vaoExt.deleteVertexArrayOES(vao); } } } this.__vaoCache = {}; cache.deleteContext(renderer.__uid__); } }); if (Object.defineProperty) { /** * @name clay.GeometryBase#vertexCount * @type {number} * @readOnly */ Object.defineProperty(GeometryBase.prototype, 'vertexCount', { enumerable: false, get: function () { var mainAttribute = this.attributes[this.mainAttribute]; if (!mainAttribute) { mainAttribute = this.attributes[this._attributeList[0]]; } if (!mainAttribute || !mainAttribute.value) { return 0; } return mainAttribute.value.length / mainAttribute.size; } }); /** * @name clay.GeometryBase#triangleCount * @type {number} * @readOnly */ Object.defineProperty(GeometryBase.prototype, 'triangleCount', { enumerable: false, get: function () { var indices = this.indices; if (!indices) { return 0; } else { return indices.length / 3; } } }); } GeometryBase.STATIC_DRAW = glenum.STATIC_DRAW; GeometryBase.DYNAMIC_DRAW = glenum.DYNAMIC_DRAW; GeometryBase.STREAM_DRAW = glenum.STREAM_DRAW; GeometryBase.AttributeBuffer = AttributeBuffer; GeometryBase.IndicesBuffer = IndicesBuffer; GeometryBase.Attribute = Attribute$1; var vec3Create = vec3.create; var vec3Add = vec3.add; var vec3Set$2 = vec3.set; var Attribute = GeometryBase.Attribute; /** * Geometry in ClayGL contains vertex attributes of mesh. These vertex attributes will be finally provided to the {@link clay.Shader}. * Different {@link clay.Shader} needs different attributes. Here is a list of attributes used in the builtin shaders. * * + position: `clay.basic`, `clay.lambert`, `clay.standard` * + texcoord0: `clay.basic`, `clay.lambert`, `clay.standard` * + color: `clay.basic`, `clay.lambert`, `clay.standard` * + weight: `clay.basic`, `clay.lambert`, `clay.standard` * + joint: `clay.basic`, `clay.lambert`, `clay.standard` * + normal: `clay.lambert`, `clay.standard` * + tangent: `clay.standard` * * #### Create a procedural geometry * * ClayGL provides a couple of builtin procedural geometries. Inlcuding: * * + {@link clay.geometry.Cube} * + {@link clay.geometry.Sphere} * + {@link clay.geometry.Plane} * + {@link clay.geometry.Cylinder} * + {@link clay.geometry.Cone} * + {@link clay.geometry.ParametricSurface} * * It's simple to create a basic geometry with these classes. * ```js var sphere = new clay.geometry.Sphere({ radius: 2 }); ``` * * #### Create the geometry data by yourself * * Usually the vertex attributes data are created by the {@link clay.loader.GLTF} or procedural geometries like {@link clay.geometry.Sphere}. * Besides these, you can create the data manually. Here is a simple example to create a triangle. ```js var TRIANGLE_POSITIONS = [ [-0.5, -0.5, 0], [0.5, -0.5, 0], [0, 0.5, 0] ]; var geometry = new clay.StaticGeometryBase(); // Add triangle vertices to position attribute. geometry.attributes.position.fromArray(TRIANGLE_POSITIONS); ``` * Then you can use the utility methods like `generateVertexNormals`, `generateTangents` to create the remaining necessary attributes. * * * #### Use with custom shaders * * If you wan't to write custom shaders. Don't forget to add SEMANTICS to these attributes. For example * ```glsl uniform mat4 worldViewProjection : WORLDVIEWPROJECTION; uniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE; uniform mat4 world : WORLD; attribute vec3 position : POSITION; attribute vec2 texcoord : TEXCOORD_0; attribute vec3 normal : NORMAL; ``` * These `POSITION`, `TEXCOORD_0`, `NORMAL` are SEMANTICS which will map the attributes in shader to the attributes in the GeometryBase * * Available attributes SEMANTICS includes `POSITION`, `TEXCOORD_0`, `TEXCOORD_1` `NORMAL`, `TANGENT`, `COLOR`, `WEIGHT`, `JOINT`. * * * @constructor clay.Geometry * @extends clay.GeometryBase */ var Geometry = GeometryBase.extend(function () { return /** @lends clay.Geometry# */ { /** * Attributes of geometry. Including: * + `position` * + `texcoord0` * + `texcoord1` * + `normal` * + `tangent` * + `color` * + `weight` * + `joint` * + `barycentric` * * @type {Object.} */ attributes: { position: new Attribute('position', 'float', 3, 'POSITION'), texcoord0: new Attribute('texcoord0', 'float', 2, 'TEXCOORD_0'), texcoord1: new Attribute('texcoord1', 'float', 2, 'TEXCOORD_1'), normal: new Attribute('normal', 'float', 3, 'NORMAL'), tangent: new Attribute('tangent', 'float', 4, 'TANGENT'), color: new Attribute('color', 'float', 4, 'COLOR'), // Skinning attributes // Each vertex can be bind to 4 bones, because the // sum of weights is 1, so the weights is stored in vec3 and the last // can be calculated by 1-w.x-w.y-w.z weight: new Attribute('weight', 'float', 3, 'WEIGHT'), joint: new Attribute('joint', 'float', 4, 'JOINT'), // For wireframe display // http://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-barycentric-coordinates/ barycentric: new Attribute('barycentric', 'float', 3, null), }, /** * Calculated bounding box of geometry. * @type {clay.BoundingBox} */ boundingBox: null }; }, /** @lends clay.Geometry.prototype */ { mainAttribute: 'position', /** * Update boundingBox of Geometry */ updateBoundingBox: function () { var bbox = this.boundingBox; if (!bbox) { bbox = this.boundingBox = new BoundingBox(); } var posArr = this.attributes.position.value; if (posArr && posArr.length) { var min = bbox.min; var max = bbox.max; var minArr = min.array; var maxArr = max.array; vec3.set(minArr, posArr[0], posArr[1], posArr[2]); vec3.set(maxArr, posArr[0], posArr[1], posArr[2]); for (var i = 3; i < posArr.length;) { var x = posArr[i++]; var y = posArr[i++]; var z = posArr[i++]; if (x < minArr[0]) { minArr[0] = x; } if (y < minArr[1]) { minArr[1] = y; } if (z < minArr[2]) { minArr[2] = z; } if (x > maxArr[0]) { maxArr[0] = x; } if (y > maxArr[1]) { maxArr[1] = y; } if (z > maxArr[2]) { maxArr[2] = z; } } min._dirty = true; max._dirty = true; } }, /** * Generate normals per vertex. */ generateVertexNormals: function () { if (!this.vertexCount) { return; } var indices = this.indices; var attributes = this.attributes; var positions = attributes.position.value; var normals = attributes.normal.value; if (!normals || normals.length !== positions.length) { normals = attributes.normal.value = new vendor.Float32Array(positions.length); } else { // Reset for (var i = 0; i < normals.length; i++) { normals[i] = 0; } } var p1 = vec3Create(); var p2 = vec3Create(); var p3 = vec3Create(); var v21 = vec3Create(); var v32 = vec3Create(); var n = vec3Create(); var len = indices ? indices.length : this.vertexCount; var i1, i2, i3; for (var f = 0; f < len;) { if (indices) { i1 = indices[f++]; i2 = indices[f++]; i3 = indices[f++]; } else { i1 = f++; i2 = f++; i3 = f++; } vec3Set$2(p1, positions[i1*3], positions[i1*3+1], positions[i1*3+2]); vec3Set$2(p2, positions[i2*3], positions[i2*3+1], positions[i2*3+2]); vec3Set$2(p3, positions[i3*3], positions[i3*3+1], positions[i3*3+2]); vec3.sub(v21, p1, p2); vec3.sub(v32, p2, p3); vec3.cross(n, v21, v32); // Already be weighted by the triangle area for (var i = 0; i < 3; i++) { normals[i1*3+i] = normals[i1*3+i] + n[i]; normals[i2*3+i] = normals[i2*3+i] + n[i]; normals[i3*3+i] = normals[i3*3+i] + n[i]; } } for (var i = 0; i < normals.length;) { vec3Set$2(n, normals[i], normals[i+1], normals[i+2]); vec3.normalize(n, n); normals[i++] = n[0]; normals[i++] = n[1]; normals[i++] = n[2]; } this.dirty(); }, /** * Generate normals per face. */ generateFaceNormals: function () { if (!this.vertexCount) { return; } if (!this.isUniqueVertex()) { this.generateUniqueVertex(); } var indices = this.indices; var attributes = this.attributes; var positions = attributes.position.value; var normals = attributes.normal.value; var p1 = vec3Create(); var p2 = vec3Create(); var p3 = vec3Create(); var v21 = vec3Create(); var v32 = vec3Create(); var n = vec3Create(); if (!normals) { normals = attributes.normal.value = new Float32Array(positions.length); } var len = indices ? indices.length : this.vertexCount; var i1, i2, i3; for (var f = 0; f < len;) { if (indices) { i1 = indices[f++]; i2 = indices[f++]; i3 = indices[f++]; } else { i1 = f++; i2 = f++; i3 = f++; } vec3Set$2(p1, positions[i1*3], positions[i1*3+1], positions[i1*3+2]); vec3Set$2(p2, positions[i2*3], positions[i2*3+1], positions[i2*3+2]); vec3Set$2(p3, positions[i3*3], positions[i3*3+1], positions[i3*3+2]); vec3.sub(v21, p1, p2); vec3.sub(v32, p2, p3); vec3.cross(n, v21, v32); vec3.normalize(n, n); for (var i = 0; i < 3; i++) { normals[i1*3 + i] = n[i]; normals[i2*3 + i] = n[i]; normals[i3*3 + i] = n[i]; } } this.dirty(); }, /** * Generate tangents attributes. */ generateTangents: function () { if (!this.vertexCount) { return; } var nVertex = this.vertexCount; var attributes = this.attributes; if (!attributes.tangent.value) { attributes.tangent.value = new Float32Array(nVertex * 4); } var texcoords = attributes.texcoord0.value; var positions = attributes.position.value; var tangents = attributes.tangent.value; var normals = attributes.normal.value; if (!texcoords) { console.warn('Geometry without texcoords can\'t generate tangents.'); return; } var tan1 = []; var tan2 = []; for (var i = 0; i < nVertex; i++) { tan1[i] = [0.0, 0.0, 0.0]; tan2[i] = [0.0, 0.0, 0.0]; } var sdir = [0.0, 0.0, 0.0]; var tdir = [0.0, 0.0, 0.0]; var indices = this.indices; var len = indices ? indices.length : this.vertexCount; var i1, i2, i3; for (var i = 0; i < len;) { if (indices) { i1 = indices[i++]; i2 = indices[i++]; i3 = indices[i++]; } else { i1 = i++; i2 = i++; i3 = i++; } var st1s = texcoords[i1 * 2], st2s = texcoords[i2 * 2], st3s = texcoords[i3 * 2], st1t = texcoords[i1 * 2 + 1], st2t = texcoords[i2 * 2 + 1], st3t = texcoords[i3 * 2 + 1], p1x = positions[i1 * 3], p2x = positions[i2 * 3], p3x = positions[i3 * 3], p1y = positions[i1 * 3 + 1], p2y = positions[i2 * 3 + 1], p3y = positions[i3 * 3 + 1], p1z = positions[i1 * 3 + 2], p2z = positions[i2 * 3 + 2], p3z = positions[i3 * 3 + 2]; var x1 = p2x - p1x, x2 = p3x - p1x, y1 = p2y - p1y, y2 = p3y - p1y, z1 = p2z - p1z, z2 = p3z - p1z; var s1 = st2s - st1s, s2 = st3s - st1s, t1 = st2t - st1t, t2 = st3t - st1t; var r = 1.0 / (s1 * t2 - t1 * s2); sdir[0] = (t2 * x1 - t1 * x2) * r; sdir[1] = (t2 * y1 - t1 * y2) * r; sdir[2] = (t2 * z1 - t1 * z2) * r; tdir[0] = (s1 * x2 - s2 * x1) * r; tdir[1] = (s1 * y2 - s2 * y1) * r; tdir[2] = (s1 * z2 - s2 * z1) * r; vec3Add(tan1[i1], tan1[i1], sdir); vec3Add(tan1[i2], tan1[i2], sdir); vec3Add(tan1[i3], tan1[i3], sdir); vec3Add(tan2[i1], tan2[i1], tdir); vec3Add(tan2[i2], tan2[i2], tdir); vec3Add(tan2[i3], tan2[i3], tdir); } var tmp = vec3Create(); var nCrossT = vec3Create(); var n = vec3Create(); for (var i = 0; i < nVertex; i++) { n[0] = normals[i * 3]; n[1] = normals[i * 3 + 1]; n[2] = normals[i * 3 + 2]; var t = tan1[i]; // Gram-Schmidt orthogonalize vec3.scale(tmp, n, vec3.dot(n, t)); vec3.sub(tmp, t, tmp); vec3.normalize(tmp, tmp); // Calculate handedness. vec3.cross(nCrossT, n, t); tangents[i * 4] = tmp[0]; tangents[i * 4 + 1] = tmp[1]; tangents[i * 4 + 2] = tmp[2]; // PENDING can config ? tangents[i * 4 + 3] = vec3.dot(nCrossT, tan2[i]) < 0.0 ? -1.0 : 1.0; } this.dirty(); }, /** * If vertices are not shared by different indices. */ isUniqueVertex: function () { if (this.isUseIndices()) { return this.vertexCount === this.indices.length; } else { return true; } }, /** * Create a unique vertex for each index. */ generateUniqueVertex: function () { if (!this.vertexCount || !this.indices) { return; } if (this.indices.length > 0xffff) { this.indices = new vendor.Uint32Array(this.indices); } var attributes = this.attributes; var indices = this.indices; var attributeNameList = this.getEnabledAttributes(); var oldAttrValues = {}; for (var a = 0; a < attributeNameList.length; a++) { var name = attributeNameList[a]; oldAttrValues[name] = attributes[name].value; attributes[name].init(this.indices.length); } var cursor = 0; for (var i = 0; i < indices.length; i++) { var ii = indices[i]; for (var a = 0; a < attributeNameList.length; a++) { var name = attributeNameList[a]; var array = attributes[name].value; var size = attributes[name].size; for (var k = 0; k < size; k++) { array[cursor * size + k] = oldAttrValues[name][ii * size + k]; } } indices[i] = cursor; cursor++; } this.dirty(); }, /** * Generate barycentric coordinates for wireframe draw. */ generateBarycentric: function () { if (!this.vertexCount) { return; } if (!this.isUniqueVertex()) { this.generateUniqueVertex(); } var attributes = this.attributes; var array = attributes.barycentric.value; var indices = this.indices; // Already existed; if (array && array.length === indices.length * 3) { return; } array = attributes.barycentric.value = new Float32Array(indices.length * 3); for (var i = 0; i < (indices ? indices.length : this.vertexCount / 3);) { for (var j = 0; j < 3; j++) { var ii = indices ? indices[i++] : (i * 3 + j); array[ii * 3 + j] = 1; } } this.dirty(); }, /** * Apply transform to geometry attributes. * @param {clay.Matrix4} matrix */ applyTransform: function (matrix) { var attributes = this.attributes; var positions = attributes.position.value; var normals = attributes.normal.value; var tangents = attributes.tangent.value; matrix = matrix.array; // Normal Matrix var inverseTransposeMatrix = mat4.create(); mat4.invert(inverseTransposeMatrix, matrix); mat4.transpose(inverseTransposeMatrix, inverseTransposeMatrix); var vec3TransformMat4 = vec3.transformMat4; var vec3ForEach = vec3.forEach; vec3ForEach(positions, 3, 0, null, vec3TransformMat4, matrix); if (normals) { vec3ForEach(normals, 3, 0, null, vec3TransformMat4, inverseTransposeMatrix); } if (tangents) { vec3ForEach(tangents, 4, 0, null, vec3TransformMat4, inverseTransposeMatrix); } if (this.boundingBox) { this.updateBoundingBox(); } }, /** * Dispose geometry data in GL context. * @param {clay.Renderer} renderer */ dispose: function (renderer) { var cache = this._cache; cache.use(renderer.__uid__); var chunks = cache.get('chunks'); if (chunks) { for (var c = 0; c < chunks.length; c++) { var chunk = chunks[c]; for (var k = 0; k < chunk.attributeBuffers.length; k++) { var attribs = chunk.attributeBuffers[k]; renderer.gl.deleteBuffer(attribs.buffer); } if (chunk.indicesBuffer) { renderer.gl.deleteBuffer(chunk.indicesBuffer.buffer); } } } if (this.__vaoCache) { var vaoExt = renderer.getGLExtension('OES_vertex_array_object'); for (var id in this.__vaoCache) { var vao = this.__vaoCache[id].vao; if (vao) { vaoExt.deleteVertexArrayOES(vao); } } } this.__vaoCache = {}; cache.deleteContext(renderer.__uid__); } }); Geometry.STATIC_DRAW = GeometryBase.STATIC_DRAW; Geometry.DYNAMIC_DRAW = GeometryBase.DYNAMIC_DRAW; Geometry.STREAM_DRAW = GeometryBase.STREAM_DRAW; Geometry.AttributeBuffer = GeometryBase.AttributeBuffer; Geometry.IndicesBuffer = GeometryBase.IndicesBuffer; Geometry.Attribute = Attribute; /** * @constructor clay.geometry.Plane * @extends clay.Geometry * @param {Object} [opt] * @param {number} [opt.widthSegments] * @param {number} [opt.heightSegments] */ var Plane$3 = Geometry.extend( /** @lends clay.geometry.Plane# */ { dynamic: false, /** * @type {number} */ widthSegments: 1, /** * @type {number} */ heightSegments: 1 }, function() { this.build(); }, /** @lends clay.geometry.Plane.prototype */ { /** * Build plane geometry */ build: function() { var heightSegments = this.heightSegments; var widthSegments = this.widthSegments; var attributes = this.attributes; var positions = []; var texcoords = []; var normals = []; var faces = []; for (var y = 0; y <= heightSegments; y++) { var t = y / heightSegments; for (var x = 0; x <= widthSegments; x++) { var s = x / widthSegments; positions.push([2 * s - 1, 2 * t - 1, 0]); if (texcoords) { texcoords.push([s, t]); } if (normals) { normals.push([0, 0, 1]); } if (x < widthSegments && y < heightSegments) { var i = x + y * (widthSegments + 1); faces.push([i, i + 1, i + widthSegments + 1]); faces.push([i + widthSegments + 1, i + 1, i + widthSegments + 2]); } } } attributes.position.fromArray(positions); attributes.texcoord0.fromArray(texcoords); attributes.normal.fromArray(normals); this.initIndicesFromArray(faces); this.boundingBox = new BoundingBox(); this.boundingBox.min.set(-1, -1, 0); this.boundingBox.max.set(1, 1, 0); } }); var planeMatrix = new Matrix4(); /** * @constructor clay.geometry.Cube * @extends clay.Geometry * @param {Object} [opt] * @param {number} [opt.widthSegments] * @param {number} [opt.heightSegments] * @param {number} [opt.depthSegments] * @param {boolean} [opt.inside] */ var Cube$1 = Geometry.extend( /**@lends clay.geometry.Cube# */ { dynamic: false, /** * @type {number} */ widthSegments: 1, /** * @type {number} */ heightSegments: 1, /** * @type {number} */ depthSegments: 1, /** * @type {boolean} */ inside: false }, function() { this.build(); }, /** @lends clay.geometry.Cube.prototype */ { /** * Build cube geometry */ build: function() { var planes = { 'px': createPlane('px', this.depthSegments, this.heightSegments), 'nx': createPlane('nx', this.depthSegments, this.heightSegments), 'py': createPlane('py', this.widthSegments, this.depthSegments), 'ny': createPlane('ny', this.widthSegments, this.depthSegments), 'pz': createPlane('pz', this.widthSegments, this.heightSegments), 'nz': createPlane('nz', this.widthSegments, this.heightSegments), }; var attrList = ['position', 'texcoord0', 'normal']; var vertexNumber = 0; var faceNumber = 0; for (var pos in planes) { vertexNumber += planes[pos].vertexCount; faceNumber += planes[pos].indices.length; } for (var k = 0; k < attrList.length; k++) { this.attributes[attrList[k]].init(vertexNumber); } this.indices = new vendor.Uint16Array(faceNumber); var faceOffset = 0; var vertexOffset = 0; for (var pos in planes) { var plane = planes[pos]; for (var k = 0; k < attrList.length; k++) { var attrName = attrList[k]; var attrArray = plane.attributes[attrName].value; var attrSize = plane.attributes[attrName].size; var isNormal = attrName === 'normal'; for (var i = 0; i < attrArray.length; i++) { var value = attrArray[i]; if (this.inside && isNormal) { value = -value; } this.attributes[attrName].value[i + attrSize * vertexOffset] = value; } } var len = plane.indices.length; for (var i = 0; i < plane.indices.length; i++) { this.indices[i + faceOffset] = vertexOffset + plane.indices[this.inside ? (len - i - 1) : i]; } faceOffset += plane.indices.length; vertexOffset += plane.vertexCount; } this.boundingBox = new BoundingBox(); this.boundingBox.max.set(1, 1, 1); this.boundingBox.min.set(-1, -1, -1); } }); function createPlane(pos, widthSegments, heightSegments) { planeMatrix.identity(); var plane = new Plane$3({ widthSegments: widthSegments, heightSegments: heightSegments }); switch(pos) { case 'px': Matrix4.translate(planeMatrix, planeMatrix, Vector3.POSITIVE_X); Matrix4.rotateY(planeMatrix, planeMatrix, Math.PI / 2); break; case 'nx': Matrix4.translate(planeMatrix, planeMatrix, Vector3.NEGATIVE_X); Matrix4.rotateY(planeMatrix, planeMatrix, -Math.PI / 2); break; case 'py': Matrix4.translate(planeMatrix, planeMatrix, Vector3.POSITIVE_Y); Matrix4.rotateX(planeMatrix, planeMatrix, -Math.PI / 2); break; case 'ny': Matrix4.translate(planeMatrix, planeMatrix, Vector3.NEGATIVE_Y); Matrix4.rotateX(planeMatrix, planeMatrix, Math.PI / 2); break; case 'pz': Matrix4.translate(planeMatrix, planeMatrix, Vector3.POSITIVE_Z); break; case 'nz': Matrix4.translate(planeMatrix, planeMatrix, Vector3.NEGATIVE_Z); Matrix4.rotateY(planeMatrix, planeMatrix, Math.PI); break; } plane.applyTransform(planeMatrix); return plane; } /** * @constructor clay.geometry.Sphere * @extends clay.Geometry * @param {Object} [opt] * @param {number} [widthSegments] * @param {number} [heightSegments] * @param {number} [phiStart] * @param {number} [phiLength] * @param {number} [thetaStart] * @param {number} [thetaLength] * @param {number} [radius] */ var Sphere$1 = Geometry.extend(/** @lends clay.geometry.Sphere# */ { dynamic: false, /** * @type {number} */ widthSegments: 40, /** * @type {number} */ heightSegments: 20, /** * @type {number} */ phiStart: 0, /** * @type {number} */ phiLength: Math.PI * 2, /** * @type {number} */ thetaStart: 0, /** * @type {number} */ thetaLength: Math.PI, /** * @type {number} */ radius: 1 }, function() { this.build(); }, /** @lends clay.geometry.Sphere.prototype */ { /** * Build sphere geometry */ build: function() { var heightSegments = this.heightSegments; var widthSegments = this.widthSegments; var positionAttr = this.attributes.position; var texcoordAttr = this.attributes.texcoord0; var normalAttr = this.attributes.normal; var vertexCount = (widthSegments + 1) * (heightSegments + 1); positionAttr.init(vertexCount); texcoordAttr.init(vertexCount); normalAttr.init(vertexCount); var IndicesCtor = vertexCount > 0xffff ? Uint32Array : Uint16Array; var indices = this.indices = new IndicesCtor(widthSegments * heightSegments * 6); var x, y, z, u, v, i, j; var radius = this.radius; var phiStart = this.phiStart; var phiLength = this.phiLength; var thetaStart = this.thetaStart; var thetaLength = this.thetaLength; var radius = this.radius; var pos = []; var uv = []; var offset = 0; var divider = 1 / radius; for (j = 0; j <= heightSegments; j ++) { for (i = 0; i <= widthSegments; i ++) { u = i / widthSegments; v = j / heightSegments; // X axis is inverted so texture can be mapped from left to right x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength); y = radius * Math.cos(thetaStart + v * thetaLength); z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength); pos[0] = x; pos[1] = y; pos[2] = z; uv[0] = u; uv[1] = v; positionAttr.set(offset, pos); texcoordAttr.set(offset, uv); pos[0] *= divider; pos[1] *= divider; pos[2] *= divider; normalAttr.set(offset, pos); offset++; } } var i1, i2, i3, i4; var len = widthSegments + 1; var n = 0; for (j = 0; j < heightSegments; j ++) { for (i = 0; i < widthSegments; i ++) { i2 = j * len + i; i1 = (j * len + i + 1); i4 = (j + 1) * len + i + 1; i3 = (j + 1) * len + i; indices[n++] = i1; indices[n++] = i2; indices[n++] = i4; indices[n++] = i2; indices[n++] = i3; indices[n++] = i4; } } this.boundingBox = new BoundingBox(); this.boundingBox.max.set(radius, radius, radius); this.boundingBox.min.set(-radius, -radius, -radius); } }); /** * @constructor clay.geometry.ParametricSurface * @extends clay.Geometry * @param {Object} [opt] * @param {Object} [generator] * @param {Function} generator.x * @param {Function} generator.y * @param {Function} generator.z * @param {Array} [generator.u=[0, 1, 0.05]] * @param {Array} [generator.v=[0, 1, 0.05]] */ var ParametricSurface$1 = Geometry.extend( /** @lends clay.geometry.ParametricSurface# */ { dynamic: false, /** * @type {Object} */ generator: null }, function() { this.build(); }, /** @lends clay.geometry.ParametricSurface.prototype */ { /** * Build parametric surface geometry */ build: function () { var generator = this.generator; if (!generator || !generator.x || !generator.y || !generator.z) { throw new Error('Invalid generator'); } var xFunc = generator.x; var yFunc = generator.y; var zFunc = generator.z; var uRange = generator.u || [0, 1, 0.05]; var vRange = generator.v || [0, 1, 0.05]; var uNum = Math.floor((uRange[1] - uRange[0] + uRange[2]) / uRange[2]); var vNum = Math.floor((vRange[1] - vRange[0] + vRange[2]) / vRange[2]); if (!isFinite(uNum) || !isFinite(vNum)) { throw new Error('Infinite generator'); } var vertexNum = uNum * vNum; this.attributes.position.init(vertexNum); this.attributes.texcoord0.init(vertexNum); var pos = []; var texcoord = []; var nVertex = 0; for (var j = 0; j < vNum; j++) { for (var i = 0; i < uNum; i++) { var u = i * uRange[2] + uRange[0]; var v = j * vRange[2] + vRange[0]; pos[0] = xFunc(u, v); pos[1] = yFunc(u, v); pos[2] = zFunc(u, v); texcoord[0] = i / (uNum - 1); texcoord[1] = j / (vNum - 1); this.attributes.position.set(nVertex, pos); this.attributes.texcoord0.set(nVertex, texcoord); nVertex++; } } var IndicesCtor = vertexNum > 0xffff ? Uint32Array : Uint16Array; var nIndices = (uNum - 1) * (vNum - 1) * 6; var indices = this.indices = new IndicesCtor(nIndices); var n = 0; for (var j = 0; j < vNum - 1; j++) { for (var i = 0; i < uNum - 1; i++) { var i2 = j * uNum + i; var i1 = (j * uNum + i + 1); var i4 = (j + 1) * uNum + i + 1; var i3 = (j + 1) * uNum + i; indices[n++] = i1; indices[n++] = i2; indices[n++] = i4; indices[n++] = i2; indices[n++] = i3; indices[n++] = i4; } } this.generateVertexNormals(); this.updateBoundingBox(); } }); /** * Base class for all textures like compressed texture, texture2d, texturecube * TODO mapping */ /** * @constructor * @alias clay.Texture * @extends clay.core.Base */ var Texture = Base.extend( /** @lends clay.Texture# */ { /** * Texture width, readonly when the texture source is image * @type {number} */ width: 512, /** * Texture height, readonly when the texture source is image * @type {number} */ height: 512, /** * Texel data type. * Possible values: * + {@link clay.Texture.UNSIGNED_BYTE} * + {@link clay.Texture.HALF_FLOAT} * + {@link clay.Texture.FLOAT} * + {@link clay.Texture.UNSIGNED_INT_24_8_WEBGL} * + {@link clay.Texture.UNSIGNED_INT} * @type {number} */ type: glenum.UNSIGNED_BYTE, /** * Format of texel data * Possible values: * + {@link clay.Texture.RGBA} * + {@link clay.Texture.DEPTH_COMPONENT} * + {@link clay.Texture.DEPTH_STENCIL} * @type {number} */ format: glenum.RGBA, /** * Texture wrap. Default to be REPEAT. * Possible values: * + {@link clay.Texture.CLAMP_TO_EDGE} * + {@link clay.Texture.REPEAT} * + {@link clay.Texture.MIRRORED_REPEAT} * @type {number} */ wrapS: glenum.REPEAT, /** * Texture wrap. Default to be REPEAT. * Possible values: * + {@link clay.Texture.CLAMP_TO_EDGE} * + {@link clay.Texture.REPEAT} * + {@link clay.Texture.MIRRORED_REPEAT} * @type {number} */ wrapT: glenum.REPEAT, /** * Possible values: * + {@link clay.Texture.NEAREST} * + {@link clay.Texture.LINEAR} * + {@link clay.Texture.NEAREST_MIPMAP_NEAREST} * + {@link clay.Texture.LINEAR_MIPMAP_NEAREST} * + {@link clay.Texture.NEAREST_MIPMAP_LINEAR} * + {@link clay.Texture.LINEAR_MIPMAP_LINEAR} * @type {number} */ minFilter: glenum.LINEAR_MIPMAP_LINEAR, /** * Possible values: * + {@link clay.Texture.NEAREST} * + {@link clay.Texture.LINEAR} * @type {number} */ magFilter: glenum.LINEAR, /** * If enable mimap. * @type {boolean} */ useMipmap: true, /** * Anisotropic filtering, enabled if value is larger than 1 * @see https://developer.mozilla.org/en-US/docs/Web/API/EXT_texture_filter_anisotropic * @type {number} */ anisotropic: 1, // pixelStorei parameters, not available when texture is used as render target // http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml /** * If flip in y axis for given image source * @type {boolean} * @default true */ flipY: true, /** * A flag to indicate if texture source is sRGB */ sRGB: true, /** * @type {number} * @default 4 */ unpackAlignment: 4, /** * @type {boolean} * @default false */ premultiplyAlpha: false, /** * Dynamic option for texture like video * @type {boolean} */ dynamic: false, NPOT: false, // PENDING // Init it here to avoid deoptimization when it's assigned in application dynamically __used: 0 }, function () { this._cache = new Cache(); }, /** @lends clay.Texture.prototype */ { getWebGLTexture: function (renderer) { var _gl = renderer.gl; var cache = this._cache; cache.use(renderer.__uid__); if (cache.miss('webgl_texture')) { // In a new gl context, create new texture and set dirty true cache.put('webgl_texture', _gl.createTexture()); } if (this.dynamic) { this.update(renderer); } else if (cache.isDirty()) { this.update(renderer); cache.fresh(); } return cache.get('webgl_texture'); }, bind: function () {}, unbind: function () {}, /** * Mark texture is dirty and update in the next frame */ dirty: function () { if (this._cache) { this._cache.dirtyAll(); } }, update: function (renderer) {}, // Update the common parameters of texture updateCommon: function (renderer) { var _gl = renderer.gl; _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, this.flipY); _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha); _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, this.unpackAlignment); // Use of none-power of two texture // http://www.khronos.org/webgl/wiki/WebGL_and_OpenGL_Differences if (this.format === glenum.DEPTH_COMPONENT) { this.useMipmap = false; } var sRGBExt = renderer.getGLExtension('EXT_sRGB'); // Fallback if (this.format === Texture.SRGB && !sRGBExt) { this.format = Texture.RGB; } if (this.format === Texture.SRGB_ALPHA && !sRGBExt) { this.format = Texture.RGBA; } this.NPOT = !this.isPowerOfTwo(); }, getAvailableWrapS: function () { if (this.NPOT) { return glenum.CLAMP_TO_EDGE; } return this.wrapS; }, getAvailableWrapT: function () { if (this.NPOT) { return glenum.CLAMP_TO_EDGE; } return this.wrapT; }, getAvailableMinFilter: function () { var minFilter = this.minFilter; if (this.NPOT || !this.useMipmap) { if (minFilter === glenum.NEAREST_MIPMAP_NEAREST || minFilter === glenum.NEAREST_MIPMAP_LINEAR ) { return glenum.NEAREST; } else if (minFilter === glenum.LINEAR_MIPMAP_LINEAR || minFilter === glenum.LINEAR_MIPMAP_NEAREST ) { return glenum.LINEAR; } else { return minFilter; } } else { return minFilter; } }, getAvailableMagFilter: function () { return this.magFilter; }, nextHighestPowerOfTwo: function (x) { --x; for (var i = 1; i < 32; i <<= 1) { x = x | x >> i; } return x + 1; }, /** * @param {clay.Renderer} renderer */ dispose: function (renderer) { var cache = this._cache; cache.use(renderer.__uid__); var webglTexture = cache.get('webgl_texture'); if (webglTexture){ renderer.gl.deleteTexture(webglTexture); } cache.deleteContext(renderer.__uid__); }, /** * Test if image of texture is valid and loaded. * @return {boolean} */ isRenderable: function () {}, /** * Test if texture size is power of two * @return {boolean} */ isPowerOfTwo: function () {} }); Object.defineProperty(Texture.prototype, 'width', { get: function () { return this._width; }, set: function (value) { this._width = value; } }); Object.defineProperty(Texture.prototype, 'height', { get: function () { return this._height; }, set: function (value) { this._height = value; } }); /* DataType */ /** * @type {number} */ Texture.BYTE = glenum.BYTE; /** * @type {number} */ Texture.UNSIGNED_BYTE = glenum.UNSIGNED_BYTE; /** * @type {number} */ Texture.SHORT = glenum.SHORT; /** * @type {number} */ Texture.UNSIGNED_SHORT = glenum.UNSIGNED_SHORT; /** * @type {number} */ Texture.INT = glenum.INT; /** * @type {number} */ Texture.UNSIGNED_INT = glenum.UNSIGNED_INT; /** * @type {number} */ Texture.FLOAT = glenum.FLOAT; /** * @type {number} */ Texture.HALF_FLOAT = 0x8D61; /** * UNSIGNED_INT_24_8_WEBGL for WEBGL_depth_texture extension * @type {number} */ Texture.UNSIGNED_INT_24_8_WEBGL = 34042; /* PixelFormat */ /** * @type {number} */ Texture.DEPTH_COMPONENT = glenum.DEPTH_COMPONENT; /** * @type {number} */ Texture.DEPTH_STENCIL = glenum.DEPTH_STENCIL; /** * @type {number} */ Texture.ALPHA = glenum.ALPHA; /** * @type {number} */ Texture.RGB = glenum.RGB; /** * @type {number} */ Texture.RGBA = glenum.RGBA; /** * @type {number} */ Texture.LUMINANCE = glenum.LUMINANCE; /** * @type {number} */ Texture.LUMINANCE_ALPHA = glenum.LUMINANCE_ALPHA; /** * @see https://www.khronos.org/registry/webgl/extensions/EXT_sRGB/ * @type {number} */ Texture.SRGB = 0x8C40; /** * @see https://www.khronos.org/registry/webgl/extensions/EXT_sRGB/ * @type {number} */ Texture.SRGB_ALPHA = 0x8C42; /* Compressed Texture */ Texture.COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0; Texture.COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1; Texture.COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2; Texture.COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3; /* TextureMagFilter */ /** * @type {number} */ Texture.NEAREST = glenum.NEAREST; /** * @type {number} */ Texture.LINEAR = glenum.LINEAR; /* TextureMinFilter */ /** * @type {number} */ Texture.NEAREST_MIPMAP_NEAREST = glenum.NEAREST_MIPMAP_NEAREST; /** * @type {number} */ Texture.LINEAR_MIPMAP_NEAREST = glenum.LINEAR_MIPMAP_NEAREST; /** * @type {number} */ Texture.NEAREST_MIPMAP_LINEAR = glenum.NEAREST_MIPMAP_LINEAR; /** * @type {number} */ Texture.LINEAR_MIPMAP_LINEAR = glenum.LINEAR_MIPMAP_LINEAR; /* TextureWrapMode */ /** * @type {number} */ Texture.REPEAT = glenum.REPEAT; /** * @type {number} */ Texture.CLAMP_TO_EDGE = glenum.CLAMP_TO_EDGE; /** * @type {number} */ Texture.MIRRORED_REPEAT = glenum.MIRRORED_REPEAT; var mathUtil = {}; mathUtil.isPowerOfTwo = function (value) { return (value & (value - 1)) === 0; }; mathUtil.nextPowerOfTwo = function (value) { value --; value |= value >> 1; value |= value >> 2; value |= value >> 4; value |= value >> 8; value |= value >> 16; value ++; return value; }; mathUtil.nearestPowerOfTwo = function (value) { return Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) ); }; var isPowerOfTwo = mathUtil.isPowerOfTwo; function nearestPowerOfTwo(val) { return Math.pow(2, Math.round(Math.log(val) / Math.LN2)); } function convertTextureToPowerOfTwo(texture, canvas) { // var canvas = document.createElement('canvas'); var width = nearestPowerOfTwo(texture.width); var height = nearestPowerOfTwo(texture.height); canvas = canvas || document.createElement('canvas'); canvas.width = width; canvas.height = height; var ctx = canvas.getContext('2d'); ctx.drawImage(texture.image, 0, 0, width, height); return canvas; } /** * @constructor clay.Texture2D * @extends clay.Texture * * @example * ... * var mat = new clay.Material({ * shader: clay.shader.library.get('clay.phong', 'diffuseMap') * }); * var diffuseMap = new clay.Texture2D(); * diffuseMap.load('assets/textures/diffuse.jpg'); * mat.set('diffuseMap', diffuseMap); * ... * diffuseMap.success(function () { * // Wait for the diffuse texture loaded * animation.on('frame', function (frameTime) { * renderer.render(scene, camera); * }); * }); */ var Texture2D = Texture.extend(function () { return /** @lends clay.Texture2D# */ { /** * @type {?HTMLImageElement|HTMLCanvasElemnet} */ // TODO mark dirty when assigned. image: null, /** * Pixels data. Will be ignored if image is set. * @type {?Uint8Array|Float32Array} */ pixels: null, /** * @type {Array.} * @example * [{ * image: mipmap0, * pixels: null * }, { * image: mipmap1, * pixels: null * }, ....] */ mipmaps: [], /** * If convert texture to power-of-two * @type {boolean} */ convertToPOT: false }; }, { textureType: 'texture2D', update: function (renderer) { var _gl = renderer.gl; _gl.bindTexture(_gl.TEXTURE_2D, this._cache.get('webgl_texture')); this.updateCommon(renderer); var glFormat = this.format; var glType = this.type; // Convert to pot is only available when using image/canvas/video element. var convertToPOT = !!(this.convertToPOT && !this.mipmaps.length && this.image && (this.wrapS === Texture.REPEAT || this.wrapT === Texture.REPEAT) && this.NPOT ); _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, convertToPOT ? this.wrapS : this.getAvailableWrapS()); _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, convertToPOT ? this.wrapT : this.getAvailableWrapT()); _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, convertToPOT ? this.magFilter : this.getAvailableMagFilter()); _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, convertToPOT ? this.minFilter : this.getAvailableMinFilter()); var anisotropicExt = renderer.getGLExtension('EXT_texture_filter_anisotropic'); if (anisotropicExt && this.anisotropic > 1) { _gl.texParameterf(_gl.TEXTURE_2D, anisotropicExt.TEXTURE_MAX_ANISOTROPY_EXT, this.anisotropic); } // Fallback to float type if browser don't have half float extension if (glType === 36193) { var halfFloatExt = renderer.getGLExtension('OES_texture_half_float'); if (!halfFloatExt) { glType = glenum.FLOAT; } } if (this.mipmaps.length) { var width = this.width; var height = this.height; for (var i = 0; i < this.mipmaps.length; i++) { var mipmap = this.mipmaps[i]; this._updateTextureData(_gl, mipmap, i, width, height, glFormat, glType, false); width /= 2; height /= 2; } } else { this._updateTextureData(_gl, this, 0, this.width, this.height, glFormat, glType, convertToPOT); if (this.useMipmap && (!this.NPOT || convertToPOT)) { _gl.generateMipmap(_gl.TEXTURE_2D); } } _gl.bindTexture(_gl.TEXTURE_2D, null); }, _updateTextureData: function (_gl, data, level, width, height, glFormat, glType, convertToPOT) { if (data.image) { var imgData = data.image; if (convertToPOT) { this._potCanvas = convertTextureToPowerOfTwo(this, this._potCanvas); imgData = this._potCanvas; } _gl.texImage2D(_gl.TEXTURE_2D, level, glFormat, glFormat, glType, imgData); } else { // Can be used as a blank texture when writing render to texture(RTT) if ( glFormat <= Texture.COMPRESSED_RGBA_S3TC_DXT5_EXT && glFormat >= Texture.COMPRESSED_RGB_S3TC_DXT1_EXT ) { _gl.compressedTexImage2D(_gl.TEXTURE_2D, level, glFormat, width, height, 0, data.pixels); } else { // Is a render target if pixels is null _gl.texImage2D(_gl.TEXTURE_2D, level, glFormat, width, height, 0, glFormat, glType, data.pixels); } } }, /** * @param {clay.Renderer} renderer * @memberOf clay.Texture2D.prototype */ generateMipmap: function (renderer) { var _gl = renderer.gl; if (this.useMipmap && !this.NPOT) { _gl.bindTexture(_gl.TEXTURE_2D, this._cache.get('webgl_texture')); _gl.generateMipmap(_gl.TEXTURE_2D); } }, isPowerOfTwo: function () { return isPowerOfTwo(this.width) && isPowerOfTwo(this.height); }, isRenderable: function () { if (this.image) { return this.image.nodeName === 'CANVAS' || this.image.nodeName === 'VIDEO' || this.image.complete; } else { return !!(this.width && this.height); } }, bind: function (renderer) { renderer.gl.bindTexture(renderer.gl.TEXTURE_2D, this.getWebGLTexture(renderer)); }, unbind: function (renderer) { renderer.gl.bindTexture(renderer.gl.TEXTURE_2D, null); }, load: function (src, crossOrigin) { var image = vendor.createImage(); if (crossOrigin) { image.crossOrigin = crossOrigin; } var self = this; image.onload = function () { self.dirty(); self.trigger('success', self); }; image.onerror = function () { self.trigger('error', self); }; image.src = src; this.image = image; return this; } }); Object.defineProperty(Texture2D.prototype, 'width', { get: function () { if (this.image) { return this.image.width; } return this._width; }, set: function (value) { if (this.image) { console.warn('Texture from image can\'t set width'); } else { if (this._width !== value) { this.dirty(); } this._width = value; } } }); Object.defineProperty(Texture2D.prototype, 'height', { get: function () { if (this.image) { return this.image.height; } return this._height; }, set: function (value) { if (this.image) { console.warn('Texture from image can\'t set height'); } else { if (this._height !== value) { this.dirty(); } this._height = value; } } }); var isPowerOfTwo$1 = mathUtil.isPowerOfTwo; var targetList = ['px', 'nx', 'py', 'ny', 'pz', 'nz']; /** * @constructor clay.TextureCube * @extends clay.Texture * * @example * ... * var mat = new clay.Material({ * shader: clay.shader.library.get('clay.phong', 'environmentMap') * }); * var envMap = new clay.TextureCube(); * envMap.load({ * 'px': 'assets/textures/sky/px.jpg', * 'nx': 'assets/textures/sky/nx.jpg' * 'py': 'assets/textures/sky/py.jpg' * 'ny': 'assets/textures/sky/ny.jpg' * 'pz': 'assets/textures/sky/pz.jpg' * 'nz': 'assets/textures/sky/nz.jpg' * }); * mat.set('environmentMap', envMap); * ... * envMap.success(function () { * // Wait for the sky texture loaded * animation.on('frame', function (frameTime) { * renderer.render(scene, camera); * }); * }); */ var TextureCube = Texture.extend(function () { return /** @lends clay.TextureCube# */{ /** * @type {boolean} * @default false */ // PENDING cubemap should not flipY in default. // flipY: false, /** * @type {Object} * @property {?HTMLImageElement|HTMLCanvasElemnet} px * @property {?HTMLImageElement|HTMLCanvasElemnet} nx * @property {?HTMLImageElement|HTMLCanvasElemnet} py * @property {?HTMLImageElement|HTMLCanvasElemnet} ny * @property {?HTMLImageElement|HTMLCanvasElemnet} pz * @property {?HTMLImageElement|HTMLCanvasElemnet} nz */ image: { px: null, nx: null, py: null, ny: null, pz: null, nz: null }, /** * Pixels data of each side. Will be ignored if images are set. * @type {Object} * @property {?Uint8Array} px * @property {?Uint8Array} nx * @property {?Uint8Array} py * @property {?Uint8Array} ny * @property {?Uint8Array} pz * @property {?Uint8Array} nz */ pixels: { px: null, nx: null, py: null, ny: null, pz: null, nz: null }, /** * @type {Array.} */ mipmaps: [] }; }, { textureType: 'textureCube', update: function (renderer) { var _gl = renderer.gl; _gl.bindTexture(_gl.TEXTURE_CUBE_MAP, this._cache.get('webgl_texture')); this.updateCommon(renderer); var glFormat = this.format; var glType = this.type; _gl.texParameteri(_gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_WRAP_S, this.getAvailableWrapS()); _gl.texParameteri(_gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_WRAP_T, this.getAvailableWrapT()); _gl.texParameteri(_gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_MAG_FILTER, this.getAvailableMagFilter()); _gl.texParameteri(_gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_MIN_FILTER, this.getAvailableMinFilter()); var anisotropicExt = renderer.getGLExtension('EXT_texture_filter_anisotropic'); if (anisotropicExt && this.anisotropic > 1) { _gl.texParameterf(_gl.TEXTURE_CUBE_MAP, anisotropicExt.TEXTURE_MAX_ANISOTROPY_EXT, this.anisotropic); } // Fallback to float type if browser don't have half float extension if (glType === 36193) { var halfFloatExt = renderer.getGLExtension('OES_texture_half_float'); if (!halfFloatExt) { glType = glenum.FLOAT; } } if (this.mipmaps.length) { var width = this.width; var height = this.height; for (var i = 0; i < this.mipmaps.length; i++) { var mipmap = this.mipmaps[i]; this._updateTextureData(_gl, mipmap, i, width, height, glFormat, glType); width /= 2; height /= 2; } } else { this._updateTextureData(_gl, this, 0, this.width, this.height, glFormat, glType); if (!this.NPOT && this.useMipmap) { _gl.generateMipmap(_gl.TEXTURE_CUBE_MAP); } } _gl.bindTexture(_gl.TEXTURE_CUBE_MAP, null); }, _updateTextureData: function (_gl, data, level, width, height, glFormat, glType) { for (var i = 0; i < 6; i++) { var target = targetList[i]; var img = data.image && data.image[target]; if (img) { _gl.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, level, glFormat, glFormat, glType, img); } else { _gl.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, level, glFormat, width, height, 0, glFormat, glType, data.pixels && data.pixels[target]); } } }, /** * @param {clay.Renderer} renderer * @memberOf clay.TextureCube.prototype */ generateMipmap: function (renderer) { var _gl = renderer.gl; if (this.useMipmap && !this.NPOT) { _gl.bindTexture(_gl.TEXTURE_CUBE_MAP, this._cache.get('webgl_texture')); _gl.generateMipmap(_gl.TEXTURE_CUBE_MAP); } }, bind: function (renderer) { renderer.gl.bindTexture(renderer.gl.TEXTURE_CUBE_MAP, this.getWebGLTexture(renderer)); }, unbind: function (renderer) { renderer.gl.bindTexture(renderer.gl.TEXTURE_CUBE_MAP, null); }, // Overwrite the isPowerOfTwo method isPowerOfTwo: function () { if (this.image.px) { return isPowerOfTwo$1(this.image.px.width) && isPowerOfTwo$1(this.image.px.height); } else { return isPowerOfTwo$1(this.width) && isPowerOfTwo$1(this.height); } }, isRenderable: function () { if (this.image.px) { return isImageRenderable(this.image.px) && isImageRenderable(this.image.nx) && isImageRenderable(this.image.py) && isImageRenderable(this.image.ny) && isImageRenderable(this.image.pz) && isImageRenderable(this.image.nz); } else { return !!(this.width && this.height); } }, load: function (imageList, crossOrigin) { var loading = 0; var self = this; util$1.each(imageList, function (src, target){ var image = vendor.createImage(); if (crossOrigin) { image.crossOrigin = crossOrigin; } image.onload = function () { loading --; if (loading === 0){ self.dirty(); self.trigger('success', self); } }; image.onerror = function () { loading --; }; loading++; image.src = src; self.image[target] = image; }); return this; } }); Object.defineProperty(TextureCube.prototype, 'width', { get: function () { if (this.image && this.image.px) { return this.image.px.width; } return this._width; }, set: function (value) { if (this.image && this.image.px) { console.warn('Texture from image can\'t set width'); } else { if (this._width !== value) { this.dirty(); } this._width = value; } } }); Object.defineProperty(TextureCube.prototype, 'height', { get: function () { if (this.image && this.image.px) { return this.image.px.height; } return this._height; }, set: function (value) { if (this.image && this.image.px) { console.warn('Texture from image can\'t set height'); } else { if (this._height !== value) { this.dirty(); } this._height = value; } } }); function isImageRenderable(image) { return image.nodeName === 'CANVAS' || image.nodeName === 'VIDEO' || image.complete; } /** * @constructor * @alias clay.Renderable * @extends clay.Node */ var Renderable = Node.extend(/** @lends clay.Renderable# */ { /** * @type {clay.Material} */ material: null, /** * @type {clay.Geometry} */ geometry: null, /** * @type {number} */ mode: glenum.TRIANGLES, _renderInfo: null }, /** @lends clay.Renderable.prototype */ { __program: null, /** * Group of received light. */ lightGroup: 0, /** * Render order, Nodes with smaller value renders before nodes with larger values. * @type {Number} */ renderOrder: 0, /** * Used when mode is LINES, LINE_STRIP or LINE_LOOP * @type {number} */ // lineWidth: 1, /** * If enable culling * @type {boolean} */ culling: true, /** * Specify which side of polygon will be culled. * Possible values: * + {@link clay.Renderable.BACK} * + {@link clay.Renderable.FRONT} * + {@link clay.Renderable.FRONT_AND_BACK} * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/cullFace * @type {number} */ cullFace: glenum.BACK, /** * Specify which side is front face. * Possible values: * + {@link clay.Renderable.CW} * + {@link clay.Renderable.CCW} * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/frontFace * @type {number} */ frontFace: glenum.CCW, /** * If enable software frustum culling * @type {boolean} */ frustumCulling: true, /** * @type {boolean} */ receiveShadow: true, /** * @type {boolean} */ castShadow: true, /** * @type {boolean} */ ignorePicking: false, /** * @type {boolean} */ ignorePreZ: false, /** * @type {boolean} */ ignoreGBuffer: false, /** * @return {boolean} */ isRenderable: function() { // TODO Shader ? return this.geometry && this.material && this.material.shader && !this.invisible && this.geometry.vertexCount > 0; }, /** * Before render hook * @type {Function} */ beforeRender: function (_gl) {}, /** * Before render hook * @type {Function} */ afterRender: function (_gl, renderStat) {}, getBoundingBox: function (filter, out) { out = Node.prototype.getBoundingBox.call(this, filter, out); if (this.geometry && this.geometry.boundingBox) { out.union(this.geometry.boundingBox); } return out; }, /** * Clone a new renderable * @function * @return {clay.Renderable} */ clone: (function() { var properties = [ 'castShadow', 'receiveShadow', 'mode', 'culling', 'cullFace', 'frontFace', 'frustumCulling', 'renderOrder', 'lineWidth', 'ignorePicking', 'ignorePreZ', 'ignoreGBuffer' ]; return function() { var renderable = Node.prototype.clone.call(this); renderable.geometry = this.geometry; renderable.material = this.material; for (var i = 0; i < properties.length; i++) { var name = properties[i]; // Try not to overwrite the prototype property if (renderable[name] !== this[name]) { renderable[name] = this[name]; } } return renderable; }; })() }); /** * @type {number} */ Renderable.POINTS = glenum.POINTS; /** * @type {number} */ Renderable.LINES = glenum.LINES; /** * @type {number} */ Renderable.LINE_LOOP = glenum.LINE_LOOP; /** * @type {number} */ Renderable.LINE_STRIP = glenum.LINE_STRIP; /** * @type {number} */ Renderable.TRIANGLES = glenum.TRIANGLES; /** * @type {number} */ Renderable.TRIANGLE_STRIP = glenum.TRIANGLE_STRIP; /** * @type {number} */ Renderable.TRIANGLE_FAN = glenum.TRIANGLE_FAN; /** * @type {number} */ Renderable.BACK = glenum.BACK; /** * @type {number} */ Renderable.FRONT = glenum.FRONT; /** * @type {number} */ Renderable.FRONT_AND_BACK = glenum.FRONT_AND_BACK; /** * @type {number} */ Renderable.CW = glenum.CW; /** * @type {number} */ Renderable.CCW = glenum.CCW; /** * @constructor clay.Mesh * @extends clay.Renderable */ var Mesh = Renderable.extend(/** @lends clay.Mesh# */ { /** * Used when it is a skinned mesh * @type {clay.Skeleton} */ skeleton: null, /** * Joints indices Meshes can share the one skeleton instance and each mesh can use one part of joints. Joints indices indicate the index of joint in the skeleton instance * @type {number[]} */ joints: null, /** * If store the skin matrices in vertex texture * @type {bool} */ useSkinMatricesTexture: false }, function () { if (!this.joints) { this.joints = []; } }, { isSkinnedMesh: function () { return !!(this.skeleton && this.joints && this.joints.length > 0); }, clone: function () { var mesh = Renderable.prototype.clone.call(this); mesh.skeleton = this.skeleton; if (this.joints) { mesh.joints = this.joints.slice(); } return mesh; } }); // Enums Mesh.POINTS = glenum.POINTS; Mesh.LINES = glenum.LINES; Mesh.LINE_LOOP = glenum.LINE_LOOP; Mesh.LINE_STRIP = glenum.LINE_STRIP; Mesh.TRIANGLES = glenum.TRIANGLES; Mesh.TRIANGLE_STRIP = glenum.TRIANGLE_STRIP; Mesh.TRIANGLE_FAN = glenum.TRIANGLE_FAN; Mesh.BACK = glenum.BACK; Mesh.FRONT = glenum.FRONT; Mesh.FRONT_AND_BACK = glenum.FRONT_AND_BACK; Mesh.CW = glenum.CW; Mesh.CCW = glenum.CCW; /** * @constructor clay.camera.Perspective * @extends clay.Camera */ var Perspective$1 = Camera.extend(/** @lends clay.camera.Perspective# */{ /** * Vertical field of view in degrees * @type {number} */ fov: 50, /** * Aspect ratio, typically viewport width / height * @type {number} */ aspect: 1, /** * Near bound of the frustum * @type {number} */ near: 0.1, /** * Far bound of the frustum * @type {number} */ far: 2000 }, /** @lends clay.camera.Perspective.prototype */ { updateProjectionMatrix: function() { var rad = this.fov / 180 * Math.PI; this.projectionMatrix.perspective(rad, this.aspect, this.near, this.far); }, decomposeProjectionMatrix: function () { var m = this.projectionMatrix.array; var rad = Math.atan(1 / m[5]) * 2; this.fov = rad / Math.PI * 180; this.aspect = m[5] / m[0]; this.near = m[14] / (m[10] - 1); this.far = m[14] / (m[10] + 1); }, /** * @return {clay.camera.Perspective} */ clone: function() { var camera = Camera.prototype.clone.call(this); camera.fov = this.fov; camera.aspect = this.aspect; camera.near = this.near; camera.far = this.far; return camera; } }); /** * @constructor clay.camera.Orthographic * @extends clay.Camera */ var Orthographic$1 = Camera.extend( /** @lends clay.camera.Orthographic# */ { /** * @type {number} */ left: -1, /** * @type {number} */ right: 1, /** * @type {number} */ near: -1, /** * @type {number} */ far: 1, /** * @type {number} */ top: 1, /** * @type {number} */ bottom: -1 }, /** @lends clay.camera.Orthographic.prototype */ { updateProjectionMatrix: function() { this.projectionMatrix.ortho(this.left, this.right, this.bottom, this.top, this.near, this.far); }, decomposeProjectionMatrix: function () { var m = this.projectionMatrix.array; this.left = (-1 - m[12]) / m[0]; this.right = (1 - m[12]) / m[0]; this.top = (1 - m[13]) / m[5]; this.bottom = (-1 - m[13]) / m[5]; this.near = -(-1 - m[14]) / m[10]; this.far = -(1 - m[14]) / m[10]; }, /** * @return {clay.camera.Orthographic} */ clone: function() { var camera = Camera.prototype.clone.call(this); camera.left = this.left; camera.right = this.right; camera.near = this.near; camera.far = this.far; camera.top = this.top; camera.bottom = this.bottom; return camera; } }); var standardEssl = "\n@export clay.standard.chunk.varying\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nvarying vec3 v_Barycentric;\n#if defined(PARALLAXOCCLUSIONMAP_ENABLED) || defined(NORMALMAP_ENABLED)\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\n#endif\n#if defined(AOMAP_ENABLED)\nvarying vec2 v_Texcoord2;\n#endif\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n@end\n@export clay.standard.chunk.light_header\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n#ifdef AMBIENT_CUBEMAP_LIGHT_COUNT\n@import clay.header.ambient_cubemap_light\n#endif\n#ifdef POINT_LIGHT_COUNT\n@import clay.header.point_light\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n#ifdef SPOT_LIGHT_COUNT\n@import clay.header.spot_light\n#endif\n@end\n@export clay.standard.vertex\n#define SHADER_NAME standard\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\n#if defined(AOMAP_ENABLED)\nattribute vec2 texcoord2 : TEXCOORD_1;\n#endif\nattribute vec3 normal : NORMAL;\nattribute vec4 tangent : TANGENT;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\n#endif\nattribute vec3 barycentric;\n@import clay.standard.chunk.varying\n@import clay.chunk.skinning_header\nvoid main()\n{\n vec3 skinnedPosition = position;\n vec3 skinnedNormal = normal;\n vec3 skinnedTangent = tangent.xyz;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n skinnedNormal = (skinMatrixWS * vec4(normal, 0.0)).xyz;\n skinnedTangent = (skinMatrixWS * vec4(tangent.xyz, 0.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0);\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_WorldPosition = (world * vec4(skinnedPosition, 1.0)).xyz;\n v_Barycentric = barycentric;\n v_Normal = normalize((worldInverseTranspose * vec4(skinnedNormal, 0.0)).xyz);\n#if defined(PARALLAXOCCLUSIONMAP_ENABLED) || defined(NORMALMAP_ENABLED)\n v_Tangent = normalize((worldInverseTranspose * vec4(skinnedTangent, 0.0)).xyz);\n v_Bitangent = normalize(cross(v_Normal, v_Tangent) * tangent.w);\n#endif\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n#if defined(AOMAP_ENABLED)\n v_Texcoord2 = texcoord2;\n#endif\n}\n@end\n@export clay.standard.fragment\n#define PI 3.14159265358979\n#define GLOSSINESS_CHANNEL 0\n#define ROUGHNESS_CHANNEL 0\n#define METALNESS_CHANNEL 1\n#define DIFFUSEMAP_ALPHA_ALPHA\n@import clay.standard.chunk.varying\nuniform mat4 viewInverse : VIEWINVERSE;\n#ifdef NORMALMAP_ENABLED\nuniform sampler2D normalMap;\n#endif\nuniform float normalScale: 1.0;\n#ifdef DIFFUSEMAP_ENABLED\nuniform sampler2D diffuseMap;\n#endif\n#ifdef SPECULARMAP_ENABLED\nuniform sampler2D specularMap;\n#endif\n#ifdef USE_ROUGHNESS\nuniform float roughness : 0.5;\n #ifdef ROUGHNESSMAP_ENABLED\nuniform sampler2D roughnessMap;\n #endif\n#else\nuniform float glossiness: 0.5;\n #ifdef GLOSSINESSMAP_ENABLED\nuniform sampler2D glossinessMap;\n #endif\n#endif\n#ifdef METALNESSMAP_ENABLED\nuniform sampler2D metalnessMap;\n#endif\n#ifdef OCCLUSIONMAP_ENABLED\nuniform sampler2D occlusionMap;\n#endif\n#ifdef ENVIRONMENTMAP_ENABLED\nuniform samplerCube environmentMap;\n #ifdef PARALLAX_CORRECTED\nuniform vec3 environmentBoxMin;\nuniform vec3 environmentBoxMax;\n #endif\n#endif\n#ifdef BRDFLOOKUP_ENABLED\nuniform sampler2D brdfLookup;\n#endif\n#ifdef EMISSIVEMAP_ENABLED\nuniform sampler2D emissiveMap;\n#endif\n#ifdef SSAOMAP_ENABLED\nuniform sampler2D ssaoMap;\nuniform vec4 viewport : VIEWPORT;\n#endif\n#ifdef AOMAP_ENABLED\nuniform sampler2D aoMap;\nuniform float aoIntensity;\n#endif\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\n#ifdef USE_METALNESS\nuniform float metalness : 0.0;\n#else\nuniform vec3 specularColor : [0.1, 0.1, 0.1];\n#endif\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float emissionIntensity: 1;\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\n#ifdef ENVIRONMENTMAP_PREFILTER\nuniform float maxMipmapLevel: 5;\n#endif\n@import clay.standard.chunk.light_header\n@import clay.util.calculate_attenuation\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.util.srgb\n@import clay.plugin.compute_shadow_map\n@import clay.util.parallax_correct\n@import clay.util.ACES\nfloat G_Smith(float g, float ndv, float ndl)\n{\n float roughness = 1.0 - g;\n float k = roughness * roughness / 2.0;\n float G1V = ndv / (ndv * (1.0 - k) + k);\n float G1L = ndl / (ndl * (1.0 - k) + k);\n return G1L * G1V;\n}\nvec3 F_Schlick(float ndv, vec3 spec) {\n return spec + (1.0 - spec) * pow(1.0 - ndv, 5.0);\n}\nfloat D_Phong(float g, float ndh) {\n float a = pow(8192.0, g);\n return (a + 2.0) / 8.0 * pow(ndh, a);\n}\nfloat D_GGX(float g, float ndh) {\n float r = 1.0 - g;\n float a = r * r;\n float tmp = ndh * ndh * (a - 1.0) + 1.0;\n return a / (PI * tmp * tmp);\n}\n#ifdef PARALLAXOCCLUSIONMAP_ENABLED\nuniform float parallaxOcclusionScale : 0.02;\nuniform float parallaxMaxLayers : 20;\nuniform float parallaxMinLayers : 5;\nuniform sampler2D parallaxOcclusionMap;\nmat3 transpose(in mat3 inMat)\n{\n vec3 i0 = inMat[0];\n vec3 i1 = inMat[1];\n vec3 i2 = inMat[2];\n return mat3(\n vec3(i0.x, i1.x, i2.x),\n vec3(i0.y, i1.y, i2.y),\n vec3(i0.z, i1.z, i2.z)\n );\n}\nvec2 parallaxUv(vec2 uv, vec3 viewDir)\n{\n float numLayers = mix(parallaxMaxLayers, parallaxMinLayers, abs(dot(vec3(0.0, 0.0, 1.0), viewDir)));\n float layerHeight = 1.0 / numLayers;\n float curLayerHeight = 0.0;\n vec2 deltaUv = viewDir.xy * parallaxOcclusionScale / (viewDir.z * numLayers);\n vec2 curUv = uv;\n float height = 1.0 - texture2D(parallaxOcclusionMap, curUv).r;\n for (int i = 0; i < 30; i++) {\n curLayerHeight += layerHeight;\n curUv -= deltaUv;\n height = 1.0 - texture2D(parallaxOcclusionMap, curUv).r;\n if (height < curLayerHeight) {\n break;\n }\n }\n vec2 prevUv = curUv + deltaUv;\n float next = height - curLayerHeight;\n float prev = 1.0 - texture2D(parallaxOcclusionMap, prevUv).r - curLayerHeight + layerHeight;\n return mix(curUv, prevUv, next / (next - prev));\n}\n#endif\nvoid main() {\n vec4 albedoColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n albedoColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n albedoColor = sRGBToLinear(albedoColor);\n#endif\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n vec2 uv = v_Texcoord;\n#if defined(PARALLAXOCCLUSIONMAP_ENABLED) || defined(NORMALMAP_ENABLED)\n mat3 tbn = mat3(v_Tangent, v_Bitangent, v_Normal);\n#endif\n#ifdef PARALLAXOCCLUSIONMAP_ENABLED\n uv = parallaxUv(v_Texcoord, normalize(transpose(tbn) * -V));\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 texel = texture2D(diffuseMap, uv);\n #ifdef SRGB_DECODE\n texel = sRGBToLinear(texel);\n #endif\n albedoColor.rgb *= texel.rgb;\n #ifdef DIFFUSEMAP_ALPHA_ALPHA\n albedoColor.a *= texel.a;\n #endif\n#endif\n#ifdef USE_METALNESS\n float m = metalness;\n #ifdef METALNESSMAP_ENABLED\n float m2 = texture2D(metalnessMap, uv)[METALNESS_CHANNEL];\n m = clamp(m2 + (m - 0.5) * 2.0, 0.0, 1.0);\n #endif\n vec3 baseColor = albedoColor.rgb;\n albedoColor.rgb = baseColor * (1.0 - m);\n vec3 spec = mix(vec3(0.04), baseColor, m);\n#else\n vec3 spec = specularColor;\n#endif\n#ifdef USE_ROUGHNESS\n float g = clamp(1.0 - roughness, 0.0, 1.0);\n #ifdef ROUGHNESSMAP_ENABLED\n float g2 = 1.0 - texture2D(roughnessMap, uv)[ROUGHNESS_CHANNEL];\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n #endif\n#else\n float g = glossiness;\n #ifdef GLOSSINESSMAP_ENABLED\n float g2 = texture2D(glossinessMap, uv)[GLOSSINESS_CHANNEL];\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n #endif\n#endif\n#ifdef SPECULARMAP_ENABLED\n spec *= sRGBToLinear(texture2D(specularMap, uv)).rgb;\n#endif\n vec3 N = v_Normal;\n#ifdef DOUBLE_SIDED\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n#endif\n#ifdef NORMALMAP_ENABLED\n if (dot(v_Tangent, v_Tangent) > 0.0) {\n vec3 normalTexel = texture2D(normalMap, uv).xyz;\n if (dot(normalTexel, normalTexel) > 0.0) { N = (normalTexel * 2.0 - 1.0);\n N = normalize(N * vec3(normalScale, normalScale, 1.0));\n tbn[1] = -tbn[1];\n N = normalize(tbn * N);\n }\n }\n#endif\n vec3 diffuseTerm = vec3(0.0, 0.0, 0.0);\n vec3 specularTerm = vec3(0.0, 0.0, 0.0);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n vec3 fresnelTerm = F_Schlick(ndv, spec);\n#ifdef AMBIENT_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_LIGHT_COUNT; _idx_++)\n {{\n diffuseTerm += ambientLightColor[_idx_];\n }}\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseTerm += calcAmbientSHLight(_idx_, N) * ambientSHLightColor[_idx_];\n }}\n#endif\n#ifdef POINT_LIGHT_COUNT\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsPoint[POINT_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfPointLights(v_WorldPosition, shadowContribsPoint);\n }\n#endif\n for(int _idx_ = 0; _idx_ < POINT_LIGHT_COUNT; _idx_++)\n {{\n vec3 lightPosition = pointLightPosition[_idx_];\n vec3 lc = pointLightColor[_idx_];\n float range = pointLightRange[_idx_];\n vec3 L = lightPosition - v_WorldPosition;\n float dist = length(L);\n float attenuation = lightAttenuation(dist, range);\n L /= dist;\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n if(shadowEnabled)\n {\n shadowContrib = shadowContribsPoint[_idx_];\n }\n#endif\n vec3 li = lc * ndl * attenuation * shadowContrib;\n diffuseTerm += li;\n specularTerm += li * fresnelTerm * D_Phong(g, ndh);\n }}\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int _idx_ = 0; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++)\n {{\n vec3 L = -normalize(directionalLightDirection[_idx_]);\n vec3 lc = directionalLightColor[_idx_];\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if(shadowEnabled)\n {\n shadowContrib = shadowContribsDir[_idx_];\n }\n#endif\n vec3 li = lc * ndl * shadowContrib;\n diffuseTerm += li;\n specularTerm += li * fresnelTerm * D_Phong(g, ndh);\n }}\n#endif\n#ifdef SPOT_LIGHT_COUNT\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsSpot[SPOT_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfSpotLights(v_WorldPosition, shadowContribsSpot);\n }\n#endif\n for(int i = 0; i < SPOT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = spotLightPosition[i];\n vec3 spotLightDirection = -normalize(spotLightDirection[i]);\n vec3 lc = spotLightColor[i];\n float range = spotLightRange[i];\n float a = spotLightUmbraAngleCosine[i];\n float b = spotLightPenumbraAngleCosine[i];\n float falloffFactor = spotLightFalloffFactor[i];\n vec3 L = lightPosition - v_WorldPosition;\n float dist = length(L);\n float attenuation = lightAttenuation(dist, range);\n L /= dist;\n float c = dot(spotLightDirection, L);\n float falloff;\n falloff = clamp((c - a) /(b - a), 0.0, 1.0);\n falloff = pow(falloff, falloffFactor);\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n if (shadowEnabled)\n {\n shadowContrib = shadowContribsSpot[i];\n }\n#endif\n vec3 li = lc * attenuation * (1.0 - falloff) * shadowContrib * ndl;\n diffuseTerm += li;\n specularTerm += li * fresnelTerm * D_Phong(g, ndh);\n }\n#endif\n vec4 outColor = albedoColor;\n outColor.rgb *= max(diffuseTerm, vec3(0.0));\n outColor.rgb += max(specularTerm, vec3(0.0));\n#ifdef AMBIENT_CUBEMAP_LIGHT_COUNT\n vec3 L = reflect(-V, N);\n float rough2 = clamp(1.0 - g, 0.0, 1.0);\n float bias2 = rough2 * 5.0;\n vec2 brdfParam2 = texture2D(ambientCubemapLightBRDFLookup[0], vec2(rough2, ndv)).xy;\n vec3 envWeight2 = spec * brdfParam2.x + brdfParam2.y;\n vec3 envTexel2;\n for(int _idx_ = 0; _idx_ < AMBIENT_CUBEMAP_LIGHT_COUNT; _idx_++)\n {{\n #ifdef SUPPORT_TEXTURE_LOD\n envTexel2 = RGBMDecode(textureCubeLodEXT(ambientCubemapLightCubemap[_idx_], L, bias2), 8.12);\n #else\n envTexel2 = RGBMDecode(textureCube(ambientCubemapLightCubemap[_idx_], L), 8.12);\n #endif\n outColor.rgb += ambientCubemapLightColor[_idx_] * envTexel2 * envWeight2;\n }}\n#endif\n#ifdef ENVIRONMENTMAP_ENABLED\n vec3 envWeight = g * fresnelTerm;\n vec3 L = reflect(-V, N);\n #ifdef PARALLAX_CORRECTED\n L = parallaxCorrect(L, v_WorldPosition, environmentBoxMin, environmentBoxMax);\n#endif\n #ifdef ENVIRONMENTMAP_PREFILTER\n float rough = clamp(1.0 - g, 0.0, 1.0);\n float bias = rough * maxMipmapLevel;\n #ifdef SUPPORT_TEXTURE_LOD\n vec3 envTexel = decodeHDR(textureCubeLodEXT(environmentMap, L, bias)).rgb;\n #else\n vec3 envTexel = decodeHDR(textureCube(environmentMap, L)).rgb;\n #endif\n #ifdef BRDFLOOKUP_ENABLED\n vec2 brdfParam = texture2D(brdfLookup, vec2(rough, ndv)).xy;\n envWeight = spec * brdfParam.x + brdfParam.y;\n #endif\n #else\n vec3 envTexel = textureCube(environmentMap, L).xyz;\n #endif\n outColor.rgb += envTexel * envWeight;\n#endif\n float aoFactor = 1.0;\n#ifdef SSAOMAP_ENABLED\n aoFactor = min(texture2D(ssaoMap, (gl_FragCoord.xy - viewport.xy) / viewport.zw).r, aoFactor);\n#endif\n#ifdef AOMAP_ENABLED\n aoFactor = min(1.0 - clamp((1.0 - texture2D(aoMap, v_Texcoord2).r) * aoIntensity, 0.0, 1.0), aoFactor);\n#endif\n#ifdef OCCLUSIONMAP_ENABLED\n aoFactor = min(1.0 - clamp((1.0 - texture2D(occlusionMap, v_Texcoord).r), 0.0, 1.0), aoFactor);\n#endif\n outColor.rgb *= aoFactor;\n vec3 lEmission = emission;\n#ifdef EMISSIVEMAP_ENABLED\n lEmission *= texture2D(emissiveMap, uv).rgb;\n#endif\n outColor.rgb += lEmission * emissionIntensity;\n if(lineWidth > 0.)\n {\n outColor.rgb = mix(outColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (outColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n outColor.rgb = ACESToneMapping(outColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n outColor = linearTosRGB(outColor);\n#endif\n gl_FragColor = encodeHDR(outColor);\n}\n@end\n@export clay.standardMR.vertex\n@import clay.standard.vertex\n@end\n@export clay.standardMR.fragment\n#define USE_METALNESS\n#define USE_ROUGHNESS\n@import clay.standard.fragment\n@end"; // Import standard shader Shader['import'](standardEssl); var TEXTURE_PROPERTIES = ['diffuseMap', 'normalMap', 'roughnessMap', 'metalnessMap', 'emissiveMap', 'environmentMap', 'brdfLookup', 'ssaoMap', 'aoMap']; var SIMPLE_PROPERTIES = ['color', 'emission', 'emissionIntensity', 'alpha', 'roughness', 'metalness', 'uvRepeat', 'uvOffset', 'aoIntensity', 'alphaCutoff', 'normalScale']; var PROPERTIES_CHANGE_SHADER = ['linear', 'encodeRGBM', 'decodeRGBM', 'doubleSided', 'alphaTest', 'roughnessChannel', 'metalnessChannel', 'environmentMapPrefiltered']; var NUM_DEFINE_MAP = { 'roughnessChannel': 'ROUGHNESS_CHANNEL', 'metalnessChannel': 'METALNESS_CHANNEL' }; var BOOL_DEFINE_MAP = { 'linear': 'SRGB_DECODE', 'encodeRGBM': 'RGBM_ENCODE', 'decodeRGBM': 'RGBM_DECODE', 'doubleSided': 'DOUBLE_SIDED', 'alphaTest': 'ALPHA_TEST', 'environmentMapPrefiltered': 'ENVIRONMENTMAP_PREFILTER' }; var standardShader; /** * Standard material without custom shader. * @constructor clay.StandardMaterial * @extends clay.Base * @example * var mat = new clay.StandardMaterial({ * color: [1, 1, 1], * diffuseMap: diffuseTexture * }); * mat.roughness = 1; */ var StandardMaterial = Material.extend(function () { if (!standardShader) { standardShader = new Shader(Shader.source('clay.standardMR.vertex'), Shader.source('clay.standardMR.fragment')); } return /** @lends clay.StandardMaterial# */ { shader: standardShader }; }, function (option) { // PENDING util$1.extend(this, option); // Extend after shader is created. util$1.defaults(this, /** @lends clay.StandardMaterial# */ { /** * @type {Array.} * @default [1, 1, 1] */ color: [1, 1, 1], /** * @type {Array.} * @default [0, 0, 0] */ emission: [0, 0, 0], /** * @type {number} * @default 0 */ emissionIntensity: 0, /** * @type {number} * @default 0.5 */ roughness: 0.5, /** * @type {number} * @default 0 */ metalness: 0, /** * @type {number} * @default 1 */ alpha: 1, /** * @type {boolean} */ alphaTest: false, /** * Cutoff threshold for alpha test * @type {number} */ alphaCutoff: 0.9, /** * Scalar multiplier applied to each normal vector of normal texture. * * @type {number} * * XXX This value is considered only if a normal texture is specified. */ normalScale: 1.0, /** * @type {boolean} */ // TODO Must disable culling. doubleSided: false, /** * @type {clay.Texture2D} */ diffuseMap: null, /** * @type {clay.Texture2D} */ normalMap: null, /** * @type {clay.Texture2D} */ roughnessMap: null, /** * @type {clay.Texture2D} */ metalnessMap: null, /** * @type {clay.Texture2D} */ emissiveMap: null, /** * @type {clay.TextureCube} */ environmentMap: null, /** * @type {clay.BoundingBox} */ environmentBox: null, /** * BRDF Lookup is generated by clay.util.cubemap.integrateBrdf * @type {clay.Texture2D} */ brdfLookup: null, /** * @type {clay.Texture2D} */ ssaoMap: null, /** * @type {clay.Texture2D} */ aoMap: null, /** * @type {Array.} * @default [1, 1] */ uvRepeat: [1, 1], /** * @type {Array.} * @default [0, 0] */ uvOffset: [0, 0], /** * @type {number} * @default 1 */ aoIntensity: 1, /** * @type {boolean} */ environmentMapPrefiltered: false, /** * @type {boolean} */ linear: false, /** * @type {boolean} */ encodeRGBM: false, /** * @type {boolean} */ decodeRGBM: false, /** * @type {Number} */ roughnessChannel: 0, /** * @type {Number} */ metalnessChannel: 1 }); }, { clone: function () { var material = new StandardMaterial({ name: this.name }); TEXTURE_PROPERTIES.forEach(function (propName) { if (this[propName]) { material[propName] = this[propName]; } }, this); SIMPLE_PROPERTIES.concat(PROPERTIES_CHANGE_SHADER).forEach(function (propName) { material[propName] = this[propName]; }, this); return material; } }); SIMPLE_PROPERTIES.forEach(function (propName) { Object.defineProperty(StandardMaterial.prototype, propName, { get: function () { return this.get(propName); }, set: function (value) { this.setUniform(propName, value); } }); }); TEXTURE_PROPERTIES.forEach(function (propName) { Object.defineProperty(StandardMaterial.prototype, propName, { get: function () { return this.get(propName); }, set: function (value) { this.setUniform(propName, value); } }); }); PROPERTIES_CHANGE_SHADER.forEach(function (propName) { var privateKey = '_' + propName; Object.defineProperty(StandardMaterial.prototype, propName, { get: function () { return this[privateKey]; }, set: function (value) { this[privateKey] = value; if (propName in NUM_DEFINE_MAP) { var defineName = NUM_DEFINE_MAP[propName]; this.define('fragment', defineName, value); } else { var defineName = BOOL_DEFINE_MAP[propName]; value ? this.define('fragment', defineName) : this.undefine('fragment', defineName); } } }); }); Object.defineProperty(StandardMaterial.prototype, 'environmentBox', { get: function () { var envBox = this._environmentBox; if (envBox) { envBox.min.setArray(this.get('environmentBoxMin')); envBox.max.setArray(this.get('environmentBoxMax')); } return envBox; }, set: function (value) { this._environmentBox = value; var uniforms = this.uniforms = this.uniforms || {}; uniforms['environmentBoxMin'] = uniforms['environmentBoxMin'] || { value: null }; uniforms['environmentBoxMax'] = uniforms['environmentBoxMax'] || { value: null }; // TODO Can't detect operation like box.min = new Vector() if (value) { this.setUniform('environmentBoxMin', value.min.array); this.setUniform('environmentBoxMax', value.max.array); } if (value) { this.define('fragment', 'PARALLAX_CORRECTED'); } else { this.undefine('fragment', 'PARALLAX_CORRECTED'); } } }); var _library = {}; function ShaderLibrary () { this._pool = {}; } ShaderLibrary.prototype.get = function(name) { var key = name; if (this._pool[key]) { return this._pool[key]; } else { var source = _library[name]; if (!source) { console.error('Shader "' + name + '"' + ' is not in the library'); return; } var shader = new Shader(source.vertex, source.fragment); this._pool[key] = shader; return shader; } }; ShaderLibrary.prototype.clear = function() { this._pool = {}; }; function template(name, vertex, fragment) { _library[name] = { vertex: vertex, fragment: fragment }; } var defaultLibrary = new ShaderLibrary(); /** * ### Builin shaders * + clay.standard * + clay.basic * + clay.lambert * + clay.wireframe * * @namespace clay.shader.library */ var library = { /** * Create a new shader library. */ createLibrary: function () { return new ShaderLibrary(); }, /** * Get shader from default library. * @param {string} name * @return {clay.Shader} * @memberOf clay.shader.library * @example * clay.shader.library.get('clay.standard') */ get: function () { return defaultLibrary.get.apply(defaultLibrary, arguments); }, /** * @memberOf clay.shader.library * @param {string} name * @param {string} vertex - Vertex shader code * @param {string} fragment - Fragment shader code */ template: template, clear: function () { return defaultLibrary.clear(); } }; /** * @constructor clay.Joint * @extends clay.core.Base */ var Joint = Base.extend( /** @lends clay.Joint# */ { // https://github.com/KhronosGroup/glTF/issues/193#issuecomment-29216576 /** * Joint name * @type {string} */ name: '', /** * Index of joint in the skeleton * @type {number} */ index: -1, /** * Scene node attached to * @type {clay.Node} */ node: null }); var tmpBoundingBox = new BoundingBox(); var tmpMat4 = new Matrix4(); /** * @constructor clay.Skeleton */ var Skeleton = Base.extend(function () { return /** @lends clay.Skeleton# */{ /** * Relative root node that not affect transform of joint. * @type {clay.Node} */ relativeRootNode: null, /** * @type {string} */ name: '', /** * joints * @type {Array.} */ joints: [], /** * bounding box with bound geometry. * @type {clay.BoundingBox} */ boundingBox: null, _clips: [], // Matrix to joint space (relative to root joint) _invBindPoseMatricesArray: null, // Use subarray instead of copy back each time computing matrix // http://jsperf.com/subarray-vs-copy-for-array-transform/5 _jointMatricesSubArrays: [], // jointMatrix * currentPoseMatrix // worldTransform is relative to the root bone // still in model space not world space _skinMatricesArray: null, _skinMatricesSubArrays: [], _subSkinMatricesArray: {} }; }, /** @lends clay.Skeleton.prototype */ { /** * Add a skinning clip and create a map between clip and skeleton * @param {clay.animation.SkinningClip} clip * @param {Object} [mapRule] Map between joint name in skeleton and joint name in clip */ addClip: function (clip, mapRule) { // Clip have been exists in for (var i = 0; i < this._clips.length; i++) { if (this._clips[i].clip === clip) { return; } } // Map the joint index in skeleton to joint pose index in clip var maps = []; for (var i = 0; i < this.joints.length; i++) { maps[i] = -1; } // Create avatar for (var i = 0; i < clip.tracks.length; i++) { for (var j = 0; j < this.joints.length; j++) { var joint = this.joints[j]; var track = clip.tracks[i]; var jointName = joint.name; if (mapRule) { jointName = mapRule[jointName]; } if (track.name === jointName) { maps[j] = i; break; } } } this._clips.push({ maps: maps, clip: clip }); return this._clips.length - 1; }, /** * @param {clay.animation.SkinningClip} clip */ removeClip: function (clip) { var idx = -1; for (var i = 0; i < this._clips.length; i++) { if (this._clips[i].clip === clip) { idx = i; break; } } if (idx > 0) { this._clips.splice(idx, 1); } }, /** * Remove all clips */ removeClipsAll: function () { this._clips = []; }, /** * Get clip by index * @param {number} index */ getClip: function (index) { if (this._clips[index]) { return this._clips[index].clip; } }, /** * @return {number} */ getClipNumber: function () { return this._clips.length; }, /** * Calculate joint matrices from node transform * @function */ updateJointMatrices: (function () { var m4 = mat4.create(); return function () { this._invBindPoseMatricesArray = new Float32Array(this.joints.length * 16); this._skinMatricesArray = new Float32Array(this.joints.length * 16); for (var i = 0; i < this.joints.length; i++) { var joint = this.joints[i]; mat4.copy(m4, joint.node.worldTransform.array); mat4.invert(m4, m4); var offset = i * 16; for (var j = 0; j < 16; j++) { this._invBindPoseMatricesArray[offset + j] = m4[j]; } } this.updateMatricesSubArrays(); }; })(), /** * Update boundingBox of each joint bound to geometry. * ASSUME skeleton and geometry joints are matched. * @param {clay.Geometry} geometry */ updateJointsBoundingBoxes: function (geometry) { var attributes = geometry.attributes; var positionAttr = attributes.position; var jointAttr = attributes.joint; var weightAttr = attributes.weight; var jointsBoundingBoxes = []; for (var i = 0; i < this.joints.length; i++) { jointsBoundingBoxes[i] = new BoundingBox(); jointsBoundingBoxes[i].__updated = false; } var vtxJoint = []; var vtxPos = []; var vtxWeight = []; var maxJointIdx = 0; for (var i = 0; i < geometry.vertexCount; i++) { jointAttr.get(i, vtxJoint); positionAttr.get(i, vtxPos); weightAttr.get(i, vtxWeight); for (var k = 0; k < 4; k++) { if (vtxWeight[k] > 0.01) { var jointIdx = vtxJoint[k]; maxJointIdx = Math.max(maxJointIdx, jointIdx); var min = jointsBoundingBoxes[jointIdx].min.array; var max = jointsBoundingBoxes[jointIdx].max.array; jointsBoundingBoxes[jointIdx].__updated = true; min = vec3.min(min, min, vtxPos); max = vec3.max(max, max, vtxPos); } } } this._jointsBoundingBoxes = jointsBoundingBoxes; this.boundingBox = new BoundingBox(); if (maxJointIdx < this.joints.length - 1) { console.warn('Geometry joints and skeleton joints don\'t match'); } }, setJointMatricesArray: function (arr) { this._invBindPoseMatricesArray = arr; this._skinMatricesArray = new Float32Array(arr.length); this.updateMatricesSubArrays(); }, updateMatricesSubArrays: function () { for (var i = 0; i < this.joints.length; i++) { this._jointMatricesSubArrays[i] = this._invBindPoseMatricesArray.subarray(i * 16, (i+1) * 16); this._skinMatricesSubArrays[i] = this._skinMatricesArray.subarray(i * 16, (i+1) * 16); } }, /** * Update skinning matrices */ update: function () { this._setPose(); var jointsBoundingBoxes = this._jointsBoundingBoxes; for (var i = 0; i < this.joints.length; i++) { var joint = this.joints[i]; mat4.multiply( this._skinMatricesSubArrays[i], joint.node.worldTransform.array, this._jointMatricesSubArrays[i] ); } if (this.boundingBox) { this.boundingBox.min.set(Infinity, Infinity, Infinity); this.boundingBox.max.set(-Infinity, -Infinity, -Infinity); for (var i = 0; i < this.joints.length; i++) { var joint = this.joints[i]; var bbox = jointsBoundingBoxes[i]; if (bbox.__updated) { tmpBoundingBox.copy(bbox); tmpMat4.array = this._skinMatricesSubArrays[i]; tmpBoundingBox.applyTransform(tmpMat4); this.boundingBox.union(tmpBoundingBox); } } } }, getSubSkinMatrices: function (meshId, joints) { var subArray = this._subSkinMatricesArray[meshId]; if (!subArray) { subArray = this._subSkinMatricesArray[meshId] = new Float32Array(joints.length * 16); } var cursor = 0; for (var i = 0; i < joints.length; i++) { var idx = joints[i]; for (var j = 0; j < 16; j++) { subArray[cursor++] = this._skinMatricesArray[idx * 16 + j]; } } return subArray; }, getSubSkinMatricesTexture: function (meshId, joints) { var skinMatrices = this.getSubSkinMatrices(meshId, joints); var size; var numJoints = this.joints.length; if (numJoints > 256) { size = 64; } else if (numJoints > 64) { size = 32; } else if (numJoints > 16) { size = 16; } else { size = 8; } var texture = this._skinMatricesTexture = this._skinMatricesTexture || new Texture2D({ type: Texture.FLOAT, minFilter: Texture.NEAREST, magFilter: Texture.NEAREST, useMipmap: false, flipY: false }); texture.width = size; texture.height = size; if (!texture.pixels || texture.pixels.length !== size * size * 4) { texture.pixels = new Float32Array(size * size * 4); } texture.pixels.set(skinMatrices); texture.dirty(); return texture; }, getSkinMatricesTexture: function () { return this._skinMatricesTexture; }, _setPose: function () { if (this._clips[0]) { var clip = this._clips[0].clip; var maps = this._clips[0].maps; for (var i = 0; i < this.joints.length; i++) { var joint = this.joints[i]; if (maps[i] === -1) { continue; } var pose = clip.tracks[maps[i]]; // Not update if there is no data. // PENDING If sync pose.position, pose.rotation, pose.scale if (pose.channels.position) { vec3.copy(joint.node.position.array, pose.position); } if (pose.channels.rotation) { quat.copy(joint.node.rotation.array, pose.rotation); } if (pose.channels.scale) { vec3.copy(joint.node.scale.array, pose.scale); } joint.node.position._dirty = true; joint.node.rotation._dirty = true; joint.node.scale._dirty = true; } } }, clone: function (clonedNodesMap) { var skeleton = new Skeleton(); skeleton.name = this.name; for (var i = 0; i < this.joints.length; i++) { var newJoint = new Joint(); var joint = this.joints[i]; newJoint.name = joint.name; newJoint.index = joint.index; if (clonedNodesMap) { var newNode = clonedNodesMap[joint.node.__uid__]; if (!newNode) { // PENDING console.warn('Can\'t find node'); } newJoint.node = newNode || joint.node; } else { newJoint.node = joint.node; } skeleton.joints.push(newJoint); } if (this._invBindPoseMatricesArray) { var len = this._invBindPoseMatricesArray.length; skeleton._invBindPoseMatricesArray = new Float32Array(len); for (var i = 0; i < len; i++) { skeleton._invBindPoseMatricesArray[i] = this._invBindPoseMatricesArray[i]; } skeleton._skinMatricesArray = new Float32Array(len); skeleton.updateMatricesSubArrays(); } skeleton._jointsBoundingBoxe = (this._jointsBoundingBoxes || []).map(function (bbox) { return bbox.clone(); }); skeleton.update(); return skeleton; } }); var utilGlsl = "\n@export clay.util.rand\nhighp float rand(vec2 uv) {\n const highp float a = 12.9898, b = 78.233, c = 43758.5453;\n highp float dt = dot(uv.xy, vec2(a,b)), sn = mod(dt, 3.141592653589793);\n return fract(sin(sn) * c);\n}\n@end\n@export clay.util.calculate_attenuation\nuniform float attenuationFactor : 5.0;\nfloat lightAttenuation(float dist, float range)\n{\n float attenuation = 1.0;\n attenuation = dist*dist/(range*range+1.0);\n float att_s = attenuationFactor;\n attenuation = 1.0/(attenuation*att_s+1.0);\n att_s = 1.0/(att_s+1.0);\n attenuation = attenuation - att_s;\n attenuation /= 1.0 - att_s;\n return clamp(attenuation, 0.0, 1.0);\n}\n@end\n@export clay.util.edge_factor\n#ifdef SUPPORT_STANDARD_DERIVATIVES\nfloat edgeFactor(float width)\n{\n vec3 d = fwidth(v_Barycentric);\n vec3 a3 = smoothstep(vec3(0.0), d * width, v_Barycentric);\n return min(min(a3.x, a3.y), a3.z);\n}\n#else\nfloat edgeFactor(float width)\n{\n return 1.0;\n}\n#endif\n@end\n@export clay.util.encode_float\nvec4 encodeFloat(const in float depth)\n{\n const vec4 bitShifts = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);\n vec4 res = fract(depth * bitShifts);\n res -= res.xxyz * bit_mask;\n return res;\n}\n@end\n@export clay.util.decode_float\nfloat decodeFloat(const in vec4 color)\n{\n const vec4 bitShifts = vec4(1.0/(256.0*256.0*256.0), 1.0/(256.0*256.0), 1.0/256.0, 1.0);\n return dot(color, bitShifts);\n}\n@end\n@export clay.util.float\n@import clay.util.encode_float\n@import clay.util.decode_float\n@end\n@export clay.util.rgbm_decode\nvec3 RGBMDecode(vec4 rgbm, float range) {\n return range * rgbm.rgb * rgbm.a;\n}\n@end\n@export clay.util.rgbm_encode\nvec4 RGBMEncode(vec3 color, float range) {\n if (dot(color, color) == 0.0) {\n return vec4(0.0);\n }\n vec4 rgbm;\n color /= range;\n rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 1e-6)), 0.0, 1.0);\n rgbm.a = ceil(rgbm.a * 255.0) / 255.0;\n rgbm.rgb = color / rgbm.a;\n return rgbm;\n}\n@end\n@export clay.util.rgbm\n@import clay.util.rgbm_decode\n@import clay.util.rgbm_encode\nvec4 decodeHDR(vec4 color)\n{\n#if defined(RGBM_DECODE) || defined(RGBM)\n return vec4(RGBMDecode(color, 8.12), 1.0);\n#else\n return color;\n#endif\n}\nvec4 encodeHDR(vec4 color)\n{\n#if defined(RGBM_ENCODE) || defined(RGBM)\n return RGBMEncode(color.xyz, 8.12);\n#else\n return color;\n#endif\n}\n@end\n@export clay.util.srgb\nvec4 sRGBToLinear(in vec4 value) {\n return vec4(mix(pow(value.rgb * 0.9478672986 + vec3(0.0521327014), vec3(2.4)), value.rgb * 0.0773993808, vec3(lessThanEqual(value.rgb, vec3(0.04045)))), value.w);\n}\nvec4 linearTosRGB(in vec4 value) {\n return vec4(mix(pow(value.rgb, vec3(0.41666)) * 1.055 - vec3(0.055), value.rgb * 12.92, vec3(lessThanEqual(value.rgb, vec3(0.0031308)))), value.w);\n}\n@end\n@export clay.chunk.skinning_header\n#ifdef SKINNING\nattribute vec3 weight : WEIGHT;\nattribute vec4 joint : JOINT;\n#ifdef USE_SKIN_MATRICES_TEXTURE\nuniform sampler2D skinMatricesTexture : ignore;\nuniform float skinMatricesTextureSize: ignore;\nmat4 getSkinMatrix(sampler2D tex, float idx) {\n float j = idx * 4.0;\n float x = mod(j, skinMatricesTextureSize);\n float y = floor(j / skinMatricesTextureSize) + 0.5;\n vec2 scale = vec2(skinMatricesTextureSize);\n return mat4(\n texture2D(tex, vec2(x + 0.5, y) / scale),\n texture2D(tex, vec2(x + 1.5, y) / scale),\n texture2D(tex, vec2(x + 2.5, y) / scale),\n texture2D(tex, vec2(x + 3.5, y) / scale)\n );\n}\nmat4 getSkinMatrix(float idx) {\n return getSkinMatrix(skinMatricesTexture, idx);\n}\n#else\nuniform mat4 skinMatrix[JOINT_COUNT] : SKIN_MATRIX;\nmat4 getSkinMatrix(float idx) {\n return skinMatrix[int(idx)];\n}\n#endif\n#endif\n@end\n@export clay.chunk.skin_matrix\nmat4 skinMatrixWS = getSkinMatrix(joint.x) * weight.x;\nif (weight.y > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.y) * weight.y;\n}\nif (weight.z > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.z) * weight.z;\n}\nfloat weightW = 1.0-weight.x-weight.y-weight.z;\nif (weightW > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.w) * weightW;\n}\n@end\n@export clay.util.parallax_correct\nvec3 parallaxCorrect(in vec3 dir, in vec3 pos, in vec3 boxMin, in vec3 boxMax) {\n vec3 first = (boxMax - pos) / dir;\n vec3 second = (boxMin - pos) / dir;\n vec3 further = max(first, second);\n float dist = min(further.x, min(further.y, further.z));\n vec3 fixedPos = pos + dir * dist;\n vec3 boxCenter = (boxMax + boxMin) * 0.5;\n return normalize(fixedPos - boxCenter);\n}\n@end\n@export clay.util.clamp_sample\nvec4 clampSample(const in sampler2D texture, const in vec2 coord)\n{\n#ifdef STEREO\n float eye = step(0.5, coord.x) * 0.5;\n vec2 coordClamped = clamp(coord, vec2(eye, 0.0), vec2(0.5 + eye, 1.0));\n#else\n vec2 coordClamped = clamp(coord, vec2(0.0), vec2(1.0));\n#endif\n return texture2D(texture, coordClamped);\n}\n@end\n@export clay.util.ACES\nvec3 ACESToneMapping(vec3 color)\n{\n const float A = 2.51;\n const float B = 0.03;\n const float C = 2.43;\n const float D = 0.59;\n const float E = 0.14;\n return (color * (A * color + B)) / (color * (C * color + D) + E);\n}\n@end"; var basicEssl = "@export clay.basic.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 position : POSITION;\nattribute vec3 barycentric;\n@import clay.chunk.skinning_header\nvarying vec2 v_Texcoord;\nvarying vec3 v_Barycentric;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\nvoid main()\n{\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_Barycentric = barycentric;\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0);\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n}\n@end\n@export clay.basic.fragment\n#define DIFFUSEMAP_ALPHA_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D diffuseMap;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\nvarying vec3 v_Barycentric;\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.util.srgb\n@import clay.util.ACES\nvoid main()\n{\n gl_FragColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 texel = decodeHDR(texture2D(diffuseMap, v_Texcoord));\n#ifdef SRGB_DECODE\n texel = sRGBToLinear(texel);\n#endif\n#if defined(DIFFUSEMAP_ALPHA_ALPHA)\n gl_FragColor.a = texel.a;\n#endif\n gl_FragColor.rgb *= texel.rgb;\n#endif\n gl_FragColor.rgb += emission;\n if( lineWidth > 0.)\n {\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (gl_FragColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n gl_FragColor.rgb = ACESToneMapping(gl_FragColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n}\n@end"; var lambertEssl = "\n@export clay.lambert.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 normal : NORMAL;\nattribute vec3 barycentric;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n@import clay.chunk.skinning_header\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nvarying vec3 v_Barycentric;\nvoid main()\n{\n vec3 skinnedPosition = position;\n vec3 skinnedNormal = normal;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n skinnedNormal = (skinMatrixWS * vec4(normal, 0.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4( skinnedPosition, 1.0 );\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_Normal = normalize( ( worldInverseTranspose * vec4(skinnedNormal, 0.0) ).xyz );\n v_WorldPosition = ( world * vec4( skinnedPosition, 1.0) ).xyz;\n v_Barycentric = barycentric;\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n}\n@end\n@export clay.lambert.fragment\n#define DIFFUSEMAP_ALPHA_ALPHA\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nuniform sampler2D diffuseMap;\nuniform sampler2D alphaMap;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\nvarying vec3 v_Barycentric;\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n#ifdef POINT_LIGHT_COUNT\n@import clay.header.point_light\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n#ifdef SPOT_LIGHT_COUNT\n@import clay.header.spot_light\n#endif\n@import clay.util.calculate_attenuation\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.plugin.compute_shadow_map\n@import clay.util.ACES\nvoid main()\n{\n gl_FragColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 tex = texture2D( diffuseMap, v_Texcoord );\n#ifdef SRGB_DECODE\n tex.rgb = pow(tex.rgb, vec3(2.2));\n#endif\n gl_FragColor.rgb *= tex.rgb;\n#ifdef DIFFUSEMAP_ALPHA_ALPHA\n gl_FragColor.a *= tex.a;\n#endif\n#endif\n vec3 diffuseColor = vec3(0.0, 0.0, 0.0);\n#ifdef AMBIENT_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_LIGHT_COUNT; _idx_++)\n {\n diffuseColor += ambientLightColor[_idx_];\n }\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseColor += calcAmbientSHLight(_idx_, v_Normal) * ambientSHLightColor[_idx_];\n }}\n#endif\n#ifdef POINT_LIGHT_COUNT\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsPoint[POINT_LIGHT_COUNT];\n if( shadowEnabled )\n {\n computeShadowOfPointLights(v_WorldPosition, shadowContribsPoint);\n }\n#endif\n for(int i = 0; i < POINT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = pointLightPosition[i];\n vec3 lightColor = pointLightColor[i];\n float range = pointLightRange[i];\n vec3 lightDirection = lightPosition - v_WorldPosition;\n float dist = length(lightDirection);\n float attenuation = lightAttenuation(dist, range);\n lightDirection /= dist;\n float ndl = dot( v_Normal, lightDirection );\n float shadowContrib = 1.0;\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsPoint[i];\n }\n#endif\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0) * attenuation * shadowContrib;\n }\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++)\n {\n vec3 lightDirection = -directionalLightDirection[i];\n vec3 lightColor = directionalLightColor[i];\n float ndl = dot(v_Normal, normalize(lightDirection));\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsDir[i];\n }\n#endif\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0) * shadowContrib;\n }\n#endif\n#ifdef SPOT_LIGHT_COUNT\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsSpot[SPOT_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfSpotLights(v_WorldPosition, shadowContribsSpot);\n }\n#endif\n for(int i = 0; i < SPOT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = -spotLightPosition[i];\n vec3 spotLightDirection = -normalize( spotLightDirection[i] );\n vec3 lightColor = spotLightColor[i];\n float range = spotLightRange[i];\n float a = spotLightUmbraAngleCosine[i];\n float b = spotLightPenumbraAngleCosine[i];\n float falloffFactor = spotLightFalloffFactor[i];\n vec3 lightDirection = lightPosition - v_WorldPosition;\n float dist = length(lightDirection);\n float attenuation = lightAttenuation(dist, range);\n lightDirection /= dist;\n float c = dot(spotLightDirection, lightDirection);\n float falloff;\n falloff = clamp((c - a) /( b - a), 0.0, 1.0);\n falloff = pow(falloff, falloffFactor);\n float ndl = dot(v_Normal, lightDirection);\n ndl = clamp(ndl, 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsSpot[i];\n }\n#endif\n diffuseColor += lightColor * ndl * attenuation * (1.0-falloff) * shadowContrib;\n }\n#endif\n gl_FragColor.rgb *= diffuseColor;\n gl_FragColor.rgb += emission;\n if(lineWidth > 0.)\n {\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (gl_FragColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n gl_FragColor.rgb = ACESToneMapping(gl_FragColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n}\n@end"; var wireframeEssl = "@export clay.wireframe.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 world : WORLD;\nattribute vec3 position : POSITION;\nattribute vec3 barycentric;\n@import clay.chunk.skinning_header\nvarying vec3 v_Barycentric;\nvoid main()\n{\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0 );\n v_Barycentric = barycentric;\n}\n@end\n@export clay.wireframe.fragment\nuniform vec3 color : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\nuniform float lineWidth : 1.0;\nvarying vec3 v_Barycentric;\n@import clay.util.edge_factor\nvoid main()\n{\n gl_FragColor.rgb = color;\n gl_FragColor.a = (1.0-edgeFactor(lineWidth)) * alpha;\n}\n@end"; var skyboxEssl = "@export clay.skybox.vertex\n#define SHADER_NAME skybox\nuniform mat4 world : WORLD;\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\nvarying vec3 v_WorldPosition;\nvoid main()\n{\n v_WorldPosition = (world * vec4(position, 1.0)).xyz;\n gl_Position = worldViewProjection * vec4(position, 1.0);\n}\n@end\n@export clay.skybox.fragment\n#define PI 3.1415926\nuniform mat4 viewInverse : VIEWINVERSE;\n#ifdef EQUIRECTANGULAR\nuniform sampler2D environmentMap;\n#else\nuniform samplerCube environmentMap;\n#endif\nuniform float lod: 0.0;\nvarying vec3 v_WorldPosition;\n@import clay.util.rgbm\n@import clay.util.srgb\n@import clay.util.ACES\nvoid main()\n{\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(v_WorldPosition - eyePos);\n#ifdef EQUIRECTANGULAR\n float phi = acos(V.y);\n float theta = atan(-V.x, V.z) + PI * 0.5;\n vec2 uv = vec2(theta / 2.0 / PI, phi / PI);\n vec4 texel = decodeHDR(texture2D(environmentMap, fract(uv)));\n#else\n #if defined(LOD) || defined(SUPPORT_TEXTURE_LOD)\n vec4 texel = decodeHDR(textureCubeLodEXT(environmentMap, V, lod));\n #else\n vec4 texel = decodeHDR(textureCube(environmentMap, V));\n #endif\n#endif\n#ifdef SRGB_DECODE\n texel = sRGBToLinear(texel);\n#endif\n#ifdef TONEMAPPING\n texel.rgb = ACESToneMapping(texel.rgb);\n#endif\n#ifdef SRGB_ENCODE\n texel = linearTosRGB(texel);\n#endif\n gl_FragColor = encodeHDR(vec4(texel.rgb, 1.0));\n}\n@end"; Shader['import'](lightEssl); Shader['import'](utilGlsl); // Some build in shaders Shader['import'](basicEssl); Shader['import'](lambertEssl); Shader['import'](standardEssl); Shader['import'](wireframeEssl); Shader['import'](skyboxEssl); Shader['import'](prezGlsl); library.template('clay.basic', Shader.source('clay.basic.vertex'), Shader.source('clay.basic.fragment')); library.template('clay.lambert', Shader.source('clay.lambert.vertex'), Shader.source('clay.lambert.fragment')); library.template('clay.wireframe', Shader.source('clay.wireframe.vertex'), Shader.source('clay.wireframe.fragment')); library.template('clay.skybox', Shader.source('clay.skybox.vertex'), Shader.source('clay.skybox.fragment')); library.template('clay.prez', Shader.source('clay.prez.vertex'), Shader.source('clay.prez.fragment')); library.template('clay.standard', Shader.source('clay.standard.vertex'), Shader.source('clay.standard.fragment')); library.template('clay.standardMR', Shader.source('clay.standardMR.vertex'), Shader.source('clay.standardMR.fragment')); /** * glTF Loader * Specification https://github.com/KhronosGroup/glTF/blob/master/specification/README.md * * TODO Morph targets */ // Import builtin shader var semanticAttributeMap = { 'NORMAL': 'normal', 'POSITION': 'position', 'TEXCOORD_0': 'texcoord0', 'TEXCOORD_1': 'texcoord1', 'WEIGHTS_0': 'weight', 'JOINTS_0': 'joint', 'COLOR_0': 'color' }; var ARRAY_CTOR_MAP = { 5120: vendor.Int8Array, 5121: vendor.Uint8Array, 5122: vendor.Int16Array, 5123: vendor.Uint16Array, 5125: vendor.Uint32Array, 5126: vendor.Float32Array }; var SIZE_MAP = { SCALAR: 1, VEC2: 2, VEC3: 3, VEC4: 4, MAT2: 4, MAT3: 9, MAT4: 16 }; function getAccessorData(json, lib, accessorIdx, isIndices) { var accessorInfo = json.accessors[accessorIdx]; var buffer = lib.bufferViews[accessorInfo.bufferView]; var byteOffset = accessorInfo.byteOffset || 0; var ArrayCtor = ARRAY_CTOR_MAP[accessorInfo.componentType] || vendor.Float32Array; var size = SIZE_MAP[accessorInfo.type]; if (size == null && isIndices) { size = 1; } var arr = new ArrayCtor(buffer, byteOffset, size * accessorInfo.count); var quantizeExtension = accessorInfo.extensions && accessorInfo.extensions['WEB3D_quantized_attributes']; if (quantizeExtension) { var decodedArr = new vendor.Float32Array(size * accessorInfo.count); var decodeMatrix = quantizeExtension.decodeMatrix; var decodeOffset, decodeScale; var decodeOffset = new Array(size); var decodeScale = new Array(size); for (var k = 0; k < size; k++) { decodeOffset[k] = decodeMatrix[size * (size + 1) + k]; decodeScale[k] = decodeMatrix[k * (size + 1) + k]; } for (var i = 0; i < accessorInfo.count; i++) { for (var k = 0; k < size; k++) { decodedArr[i * size + k] = arr[i * size + k] * decodeScale[k] + decodeOffset[k]; } } arr = decodedArr; } return arr; } /** * @typedef {Object} clay.loader.GLTF.Result * @property {Object} json * @property {clay.Scene} scene * @property {clay.Node} rootNode * @property {clay.Camera[]} cameras * @property {clay.Texture[]} textures * @property {clay.Material[]} materials * @property {clay.Skeleton[]} skeletons * @property {clay.Mesh[]} meshes * @property {clay.animation.TrackClip[]} clips * @property {clay.Node[]} nodes */ /** * @constructor clay.loader.GLTF * @extends clay.core.Base */ var GLTFLoader = Base.extend(/** @lends clay.loader.GLTF# */ { /** * * @type {clay.Node} */ rootNode: null, /** * Root path for uri parsing. * @type {string} */ rootPath: null, /** * Root path for texture uri parsing. Defaultly use the rootPath * @type {string} */ textureRootPath: null, /** * Root path for buffer uri parsing. Defaultly use the rootPath * @type {string} */ bufferRootPath: null, /** * Shader used when creating the materials. * @type {string|clay.Shader} * @default 'clay.standard' */ shader: 'clay.standard', /** * If use {@link clay.StandardMaterial} * @type {string} */ useStandardMaterial: false, /** * If loading the cameras. * @type {boolean} */ includeCamera: true, /** * If loading the animations. * @type {boolean} */ includeAnimation: true, /** * If loading the meshes * @type {boolean} */ includeMesh: true, /** * If loading the textures. * @type {boolean} */ includeTexture: true, /** * @type {string} */ crossOrigin: '', /** * @type {boolean} * @see https://github.com/KhronosGroup/glTF/issues/674 */ textureFlipY: false, /** * If convert texture to power-of-two * @type {boolean} */ textureConvertToPOT: false, shaderLibrary: null }, function () { if (!this.shaderLibrary) { this.shaderLibrary = library.createLibrary(); } }, /** @lends clay.loader.GLTF.prototype */ { /** * @param {string} url */ load: function (url) { var self = this; var isBinary = url.endsWith('.glb'); if (this.rootPath == null) { this.rootPath = url.slice(0, url.lastIndexOf('/')); } vendor.request.get({ url: url, onprogress: function (percent, loaded, total) { self.trigger('progress', percent, loaded, total); }, onerror: function (e) { self.trigger('error', e); }, responseType: isBinary ? 'arraybuffer' : 'text', onload: function (data) { if (isBinary) { self.parseBinary(data); } else { if (typeof data === 'string') { data = JSON.parse(data); } self.parse(data); } } }); }, /** * Parse glTF binary * @param {ArrayBuffer} buffer * @return {clay.loader.GLTF.Result} */ parseBinary: function (buffer) { var header = new Uint32Array(buffer, 0, 4); if (header[0] !== 0x46546C67) { this.trigger('error', 'Invalid glTF binary format: Invalid header'); return; } if (header[0] < 2) { this.trigger('error', 'Only glTF2.0 is supported.'); return; } var dataView = new DataView(buffer, 12); var json; var buffers = []; // Read chunks for (var i = 0; i < dataView.byteLength;) { var chunkLength = dataView.getUint32(i, true); i += 4; var chunkType = dataView.getUint32(i, true); i += 4; // json if (chunkType === 0x4E4F534A) { var arr = new Uint8Array(buffer, i + 12, chunkLength); // TODO, for the browser not support TextDecoder. var decoder = new TextDecoder(); var str = decoder.decode(arr); try { json = JSON.parse(str); } catch (e) { this.trigger('error', 'JSON Parse error:' + e.toString()); return; } } else if (chunkType === 0x004E4942) { buffers.push(buffer.slice(i + 12, i + 12 + chunkLength)); } i += chunkLength; } if (!json) { this.trigger('error', 'Invalid glTF binary format: Can\'t find JSON.'); return; } return this.parse(json, buffers); }, /** * @param {Object} json * @param {ArrayBuffer[]} [buffer] * @return {clay.loader.GLTF.Result} */ parse: function (json, buffers) { var self = this; var lib = { json: json, buffers: [], bufferViews: [], materials: [], textures: [], meshes: [], joints: [], skeletons: [], cameras: [], nodes: [], clips: [] }; // Mount on the root node if given var rootNode = this.rootNode || new Scene(); var loading = 0; function checkLoad() { loading--; if (loading === 0) { afterLoadBuffer(); } } // If already load buffers if (buffers) { lib.buffers = buffers.slice(); afterLoadBuffer(true); } else { // Load buffers util$1.each(json.buffers, function (bufferInfo, idx) { loading++; var path = bufferInfo.uri; self._loadBuffer(path, function (buffer) { lib.buffers[idx] = buffer; checkLoad(); }, checkLoad); }); } function getResult() { return { json: json, scene: self.rootNode ? null : rootNode, rootNode: self.rootNode ? rootNode : null, cameras: lib.cameras, textures: lib.textures, materials: lib.materials, skeletons: lib.skeletons, meshes: lib.instancedMeshes, clips: lib.clips, nodes: lib.nodes }; } function afterLoadBuffer(immediately) { // Buffer not load complete. if (lib.buffers.length !== json.buffers.length) { setTimeout(function () { self.trigger('error', 'Buffer not load complete.'); }); return; } json.bufferViews.forEach(function (bufferViewInfo, idx) { // PENDING Performance lib.bufferViews[idx] = lib.buffers[bufferViewInfo.buffer] .slice(bufferViewInfo.byteOffset || 0, (bufferViewInfo.byteOffset || 0) + (bufferViewInfo.byteLength || 0)); }); lib.buffers = null; if (self.includeMesh) { if (self.includeTexture) { self._parseTextures(json, lib); } self._parseMaterials(json, lib); self._parseMeshes(json, lib); } self._parseNodes(json, lib); // Only support one scene. if (json.scenes) { var sceneInfo = json.scenes[json.scene || 0]; // Default use the first scene. if (sceneInfo) { for (var i = 0; i < sceneInfo.nodes.length; i++) { var node = lib.nodes[sceneInfo.nodes[i]]; node.update(); rootNode.add(node); } } } if (self.includeMesh) { self._parseSkins(json, lib); } if (self.includeAnimation) { self._parseAnimations(json, lib); } if (immediately) { setTimeout(function () { self.trigger('success', getResult()); }); } else { self.trigger('success', getResult()); } } return getResult(); }, /** * Binary file path resolver. User can override it * @param {string} path */ resolveBinaryPath: function (path) { if (path && path.match(/^data:(.*?)base64,/)) { return path; } var rootPath = this.bufferRootPath; if (rootPath == null) { rootPath = this.rootPath; } return util$1.relative2absolute(path, rootPath); }, /** * Texture file path resolver. User can override it * @param {string} path */ resolveTexturePath: function (path) { if (path && path.match(/^data:(.*?)base64,/)) { return path; } var rootPath = this.textureRootPath; if (rootPath == null) { rootPath = this.rootPath; } return util$1.relative2absolute(path, rootPath); }, _getShader: function () { if (typeof this.shader === 'string') { return this.shaderLibrary.get(this.shader); } else if (this.shader instanceof Shader) { return this.shader; } }, _loadBuffer: function (path, onsuccess, onerror) { vendor.request.get({ url: this.resolveBinaryPath(path), responseType: 'arraybuffer', onload: function (buffer) { onsuccess && onsuccess(buffer); }, onerror: function (buffer) { onerror && onerror(buffer); } }); }, // https://github.com/KhronosGroup/glTF/issues/100 // https://github.com/KhronosGroup/glTF/issues/193 _parseSkins: function (json, lib) { // Create skeletons and joints util$1.each(json.skins, function (skinInfo, idx) { var skeleton = new Skeleton({ name: skinInfo.name }); for (var i = 0; i < skinInfo.joints.length; i++) { var nodeIdx = skinInfo.joints[i]; var node = lib.nodes[nodeIdx]; var joint = new Joint({ name: node.name, node: node, index: skeleton.joints.length }); skeleton.joints.push(joint); } skeleton.relativeRootNode = lib.nodes[skinInfo.skeleton] || this.rootNode; if (skinInfo.inverseBindMatrices) { var IBMInfo = json.accessors[skinInfo.inverseBindMatrices]; var buffer = lib.bufferViews[IBMInfo.bufferView]; var offset = IBMInfo.byteOffset || 0; var size = IBMInfo.count * 16; var array = new vendor.Float32Array(buffer, offset, size); skeleton.setJointMatricesArray(array); } else { skeleton.updateJointMatrices(); } lib.skeletons[idx] = skeleton; }, this); function enableSkinningForMesh(mesh, skeleton, jointIndices) { mesh.skeleton = skeleton; mesh.joints = jointIndices; if (!skeleton.boundingBox) { skeleton.updateJointsBoundingBoxes(mesh.geometry); } } function getJointIndex(joint) { return joint.index; } util$1.each(json.nodes, function (nodeInfo, nodeIdx) { if (nodeInfo.skin != null) { var skinIdx = nodeInfo.skin; var skeleton = lib.skeletons[skinIdx]; var node = lib.nodes[nodeIdx]; var jointIndices = skeleton.joints.map(getJointIndex); if (node instanceof Mesh) { enableSkinningForMesh(node, skeleton, jointIndices); } else { // Mesh have multiple primitives var children = node.children(); for (var i = 0; i < children.length; i++) { enableSkinningForMesh(children[i], skeleton, jointIndices); } } } }, this); }, _parseTextures: function (json, lib) { util$1.each(json.textures, function (textureInfo, idx){ // samplers is optional var samplerInfo = (json.samplers && json.samplers[textureInfo.sampler]) || {}; var parameters = {}; ['wrapS', 'wrapT', 'magFilter', 'minFilter'].forEach(function (name) { var value = samplerInfo[name]; if (value != null) { parameters[name] = value; } }); util$1.defaults(parameters, { wrapS: Texture.REPEAT, wrapT: Texture.REPEAT, flipY: this.textureFlipY, convertToPOT: this.textureConvertToPOT }); var target = textureInfo.target || glenum.TEXTURE_2D; var format = textureInfo.format; if (format != null) { parameters.format = format; } if (target === glenum.TEXTURE_2D) { var texture = new Texture2D(parameters); var imageInfo = json.images[textureInfo.source]; var uri; if (imageInfo.uri) { uri = this.resolveTexturePath(imageInfo.uri); } else if (imageInfo.bufferView != null) { uri = URL.createObjectURL(new Blob([lib.bufferViews[imageInfo.bufferView]], { type: imageInfo.mimeType })); } if (uri) { texture.load(uri, this.crossOrigin); lib.textures[idx] = texture; } } }, this); }, _KHRCommonMaterialToStandard: function (materialInfo, lib) { var uniforms = {}; var commonMaterialInfo = materialInfo.extensions['KHR_materials_common']; uniforms = commonMaterialInfo.values || {}; if (typeof uniforms.diffuse === 'number') { uniforms.diffuse = lib.textures[uniforms.diffuse] || null; } if (typeof uniforms.emission === 'number') { uniforms.emission = lib.textures[uniforms.emission] || null; } var enabledTextures = []; if (uniforms['diffuse'] instanceof Texture2D) { enabledTextures.push('diffuseMap'); } if (materialInfo.normalTexture) { enabledTextures.push('normalMap'); } if (uniforms['emission'] instanceof Texture2D) { enabledTextures.push('emissiveMap'); } var material; var isStandardMaterial = this.useStandardMaterial; if (isStandardMaterial) { material = new StandardMaterial({ name: materialInfo.name, doubleSided: materialInfo.doubleSided }); } else { material = new Material({ name: materialInfo.name, shader: this._getShader() }); material.define('fragment', 'USE_ROUGHNESS'); material.define('fragment', 'USE_METALNESS'); if (materialInfo.doubleSided) { material.define('fragment', 'DOUBLE_SIDED'); } } if (uniforms.transparent) { material.depthMask = false; material.depthTest = true; material.transparent = true; } var diffuseProp = uniforms['diffuse']; if (diffuseProp) { // Color if (Array.isArray(diffuseProp)) { diffuseProp = diffuseProp.slice(0, 3); isStandardMaterial ? (material.color = diffuseProp) : material.set('color', diffuseProp); } else { // Texture isStandardMaterial ? (material.diffuseMap = diffuseProp) : material.set('diffuseMap', diffuseProp); } } var emissionProp = uniforms['emission']; if (emissionProp != null) { // Color if (Array.isArray(emissionProp)) { emissionProp = emissionProp.slice(0, 3); isStandardMaterial ? (material.emission = emissionProp) : material.set('emission', emissionProp); } else { // Texture isStandardMaterial ? (material.emissiveMap = emissionProp) : material.set('emissiveMap', emissionProp); } } if (materialInfo.normalTexture != null) { // TODO texCoord var normalTextureIndex = materialInfo.normalTexture.index; if (isStandardMaterial) { material.normalMap = lib.textures[normalTextureIndex] || null; } else { material.set('normalMap', lib.textures[normalTextureIndex] || null); } } if (uniforms['shininess'] != null) { var glossiness = Math.log(uniforms['shininess']) / Math.log(8192); // Uniform glossiness material.set('glossiness', glossiness); material.set('roughness', 1 - glossiness); } else { material.set('glossiness', 0.3); material.set('roughness', 0.3); } if (uniforms['specular'] != null) { material.set('specularColor', uniforms['specular'].slice(0, 3)); } if (uniforms['transparency'] != null) { material.set('alpha', uniforms['transparency']); } return material; }, _pbrMetallicRoughnessToStandard: function (materialInfo, metallicRoughnessMatInfo, lib) { var alphaTest = materialInfo.alphaMode === 'MASK'; var isStandardMaterial = this.useStandardMaterial; var material; var diffuseMap, roughnessMap, metalnessMap, normalMap, emissiveMap, occlusionMap; var enabledTextures = []; /** * The scalar multiplier applied to each normal vector of the normal texture. * * @type {number} * * XXX This value is ignored if `materialInfo.normalTexture` is not specified. */ var normalScale = 1.0; // TODO texCoord if (metallicRoughnessMatInfo.baseColorTexture) { diffuseMap = lib.textures[metallicRoughnessMatInfo.baseColorTexture.index] || null; diffuseMap && enabledTextures.push('diffuseMap'); } if (metallicRoughnessMatInfo.metallicRoughnessTexture) { roughnessMap = metalnessMap = lib.textures[metallicRoughnessMatInfo.metallicRoughnessTexture.index] || null; roughnessMap && enabledTextures.push('metalnessMap', 'roughnessMap'); } if (materialInfo.normalTexture) { normalMap = lib.textures[materialInfo.normalTexture.index] || null; normalMap && enabledTextures.push('normalMap'); if (typeof materialInfo.normalTexture.scale === 'number') { normalScale = materialInfo.normalTexture.scale; } } if (materialInfo.emissiveTexture) { emissiveMap = lib.textures[materialInfo.emissiveTexture.index] || null; emissiveMap && enabledTextures.push('emissiveMap'); } if (materialInfo.occlusionTexture) { occlusionMap = lib.textures[materialInfo.occlusionTexture.index] || null; occlusionMap && enabledTextures.push('occlusionMap'); } var baseColor = metallicRoughnessMatInfo.baseColorFactor || [1, 1, 1, 1]; var commonProperties = { diffuseMap: diffuseMap || null, roughnessMap: roughnessMap || null, metalnessMap: metalnessMap || null, normalMap: normalMap || null, occlusionMap: occlusionMap || null, emissiveMap: emissiveMap || null, color: baseColor.slice(0, 3), alpha: baseColor[3], metalness: metallicRoughnessMatInfo.metallicFactor || 0, roughness: metallicRoughnessMatInfo.roughnessFactor || 0, emission: materialInfo.emissiveFactor || [0, 0, 0], emissionIntensity: 1, alphaCutoff: materialInfo.alphaCutoff || 0, normalScale: normalScale }; if (commonProperties.roughnessMap) { // In glTF metallicFactor will do multiply, which is different from StandardMaterial. // So simply ignore it commonProperties.metalness = 0.5; commonProperties.roughness = 0.5; } if (isStandardMaterial) { material = new StandardMaterial(util$1.extend({ name: materialInfo.name, alphaTest: alphaTest, doubleSided: materialInfo.doubleSided, // G channel roughnessChannel: 1, // B Channel metalnessChannel: 2 }, commonProperties)); } else { material = new Material({ name: materialInfo.name, shader: this._getShader() }); material.define('fragment', 'USE_ROUGHNESS'); material.define('fragment', 'USE_METALNESS'); material.define('fragment', 'ROUGHNESS_CHANNEL', 1); material.define('fragment', 'METALNESS_CHANNEL', 2); material.define('fragment', 'DIFFUSEMAP_ALPHA_ALPHA'); if (alphaTest) { material.define('fragment', 'ALPHA_TEST'); } if (materialInfo.doubleSided) { material.define('fragment', 'DOUBLE_SIDED'); } material.set(commonProperties); } if (materialInfo.alphaMode === 'BLEND') { material.depthMask = false; material.depthTest = true; material.transparent = true; } return material; }, _pbrSpecularGlossinessToStandard: function (materialInfo, specularGlossinessMatInfo, lib) { var alphaTest = materialInfo.alphaMode === 'MASK'; if (this.useStandardMaterial) { console.error('StandardMaterial doesn\'t support specular glossiness workflow yet'); } var material; var diffuseMap, glossinessMap, specularMap, normalMap, emissiveMap, occlusionMap; var enabledTextures = []; // TODO texCoord if (specularGlossinessMatInfo.diffuseTexture) { diffuseMap = lib.textures[specularGlossinessMatInfo.diffuseTexture.index] || null; diffuseMap && enabledTextures.push('diffuseMap'); } if (specularGlossinessMatInfo.specularGlossinessTexture) { glossinessMap = specularMap = lib.textures[specularGlossinessMatInfo.specularGlossinessTexture.index] || null; glossinessMap && enabledTextures.push('specularMap', 'glossinessMap'); } if (materialInfo.normalTexture) { normalMap = lib.textures[materialInfo.normalTexture.index] || null; normalMap && enabledTextures.push('normalMap'); } if (materialInfo.emissiveTexture) { emissiveMap = lib.textures[materialInfo.emissiveTexture.index] || null; emissiveMap && enabledTextures.push('emissiveMap'); } if (materialInfo.occlusionTexture) { occlusionMap = lib.textures[materialInfo.occlusionTexture.index] || null; occlusionMap && enabledTextures.push('occlusionMap'); } var diffuseColor = specularGlossinessMatInfo.diffuseFactor || [1, 1, 1, 1]; var commonProperties = { diffuseMap: diffuseMap || null, glossinessMap: glossinessMap || null, specularMap: specularMap || null, normalMap: normalMap || null, emissiveMap: emissiveMap || null, occlusionMap: occlusionMap || null, color: diffuseColor.slice(0, 3), alpha: diffuseColor[3], specularColor: specularGlossinessMatInfo.specularFactor || [1, 1, 1], glossiness: specularGlossinessMatInfo.glossinessFactor || 0, emission: materialInfo.emissiveFactor || [0, 0, 0], emissionIntensity: 1, alphaCutoff: materialInfo.alphaCutoff == null ? 0.9 : materialInfo.alphaCutoff }; if (commonProperties.glossinessMap) { // Ignore specularFactor commonProperties.glossiness = 0.5; } if (commonProperties.specularMap) { // Ignore specularFactor commonProperties.specularColor = [1, 1, 1]; } material = new Material({ name: materialInfo.name, shader: this._getShader() }); material.define('fragment', 'GLOSSINESS_CHANNEL', 3); material.define('fragment', 'DIFFUSEMAP_ALPHA_ALPHA'); if (alphaTest) { material.define('fragment', 'ALPHA_TEST'); } if (materialInfo.doubleSided) { material.define('fragment', 'DOUBLE_SIDED'); } material.set(commonProperties); if (materialInfo.alphaMode === 'BLEND') { material.depthMask = false; material.depthTest = true; material.transparent = true; } return material; }, _parseMaterials: function (json, lib) { util$1.each(json.materials, function (materialInfo, idx) { if (materialInfo.extensions && materialInfo.extensions['KHR_materials_common']) { lib.materials[idx] = this._KHRCommonMaterialToStandard(materialInfo, lib); } else if (materialInfo.extensions && materialInfo.extensions['KHR_materials_pbrSpecularGlossiness']) { lib.materials[idx] = this._pbrSpecularGlossinessToStandard(materialInfo, materialInfo.extensions['KHR_materials_pbrSpecularGlossiness'], lib); } else { lib.materials[idx] = this._pbrMetallicRoughnessToStandard(materialInfo, materialInfo.pbrMetallicRoughness || {}, lib); } }, this); }, _parseMeshes: function (json, lib) { var self = this; util$1.each(json.meshes, function (meshInfo, idx) { lib.meshes[idx] = []; // Geometry for (var pp = 0; pp < meshInfo.primitives.length; pp++) { var primitiveInfo = meshInfo.primitives[pp]; var geometry = new Geometry({ dynamic: false, // PENDIGN name: meshInfo.name, boundingBox: new BoundingBox() }); // Parse attributes var semantics = Object.keys(primitiveInfo.attributes); for (var ss = 0; ss < semantics.length; ss++) { var semantic = semantics[ss]; var accessorIdx = primitiveInfo.attributes[semantic]; var attributeInfo = json.accessors[accessorIdx]; var attributeName = semanticAttributeMap[semantic]; if (!attributeName) { continue; } var size = SIZE_MAP[attributeInfo.type]; var attributeArray = getAccessorData(json, lib, accessorIdx); // WebGL attribute buffer not support uint32. // Direct use Float32Array may also have issue. if (attributeArray instanceof vendor.Uint32Array) { attributeArray = new Float32Array(attributeArray); } if (semantic === 'WEIGHTS_0' && size === 4) { // Weight data in QTEK has only 3 component, the last component can be evaluated since it is normalized var weightArray = new attributeArray.constructor(attributeInfo.count * 3); for (var i = 0; i < attributeInfo.count; i++) { var i4 = i * 4, i3 = i * 3; var w1 = attributeArray[i4], w2 = attributeArray[i4 + 1], w3 = attributeArray[i4 + 2], w4 = attributeArray[i4 + 3]; var wSum = w1 + w2 + w3 + w4; weightArray[i3] = w1 / wSum; weightArray[i3 + 1] = w2 / wSum; weightArray[i3 + 2] = w3 / wSum; } geometry.attributes[attributeName].value = weightArray; } else if (semantic === 'COLOR_0' && size === 3) { var colorArray = new attributeArray.constructor(attributeInfo.count * 4); for (var i = 0; i < attributeInfo.count; i++) { var i4 = i * 4, i3 = i * 3; colorArray[i4] = attributeArray[i3]; colorArray[i4 + 1] = attributeArray[i3 + 1]; colorArray[i4 + 2] = attributeArray[i3 + 2]; colorArray[i4 + 3] = 1; } geometry.attributes[attributeName].value = colorArray; } else { geometry.attributes[attributeName].value = attributeArray; } var attributeType = 'float'; if (attributeArray instanceof vendor.Uint16Array) { attributeType = 'ushort'; } else if (attributeArray instanceof vendor.Int16Array) { attributeType = 'short'; } else if (attributeArray instanceof vendor.Uint8Array) { attributeType = 'ubyte'; } else if (attributeArray instanceof vendor.Int8Array) { attributeType = 'byte'; } geometry.attributes[attributeName].type = attributeType; if (semantic === 'POSITION') { // Bounding Box var min = attributeInfo.min; var max = attributeInfo.max; if (min) { geometry.boundingBox.min.set(min[0], min[1], min[2]); } if (max) { geometry.boundingBox.max.set(max[0], max[1], max[2]); } } } // Parse indices if (primitiveInfo.indices != null) { geometry.indices = getAccessorData(json, lib, primitiveInfo.indices, true); if (geometry.vertexCount <= 0xffff && geometry.indices instanceof vendor.Uint32Array) { geometry.indices = new vendor.Uint16Array(geometry.indices); } if(geometry.indices instanceof vendor.Uint8Array) { geometry.indices = new vendor.Uint16Array(geometry.indices); } } var material = lib.materials[primitiveInfo.material]; var materialInfo = (json.materials || [])[primitiveInfo.material]; // Use default material if (!material) { material = new Material({ shader: self._getShader() }); } var mesh = new Mesh({ geometry: geometry, material: material, mode: [Mesh.POINTS, Mesh.LINES, Mesh.LINE_LOOP, Mesh.LINE_STRIP, Mesh.TRIANGLES, Mesh.TRIANGLE_STRIP, Mesh.TRIANGLE_FAN][primitiveInfo.mode] || Mesh.TRIANGLES, ignoreGBuffer: material.transparent }); if (materialInfo != null) { mesh.culling = !materialInfo.doubleSided; } if (!mesh.geometry.attributes.normal.value) { mesh.geometry.generateVertexNormals(); } if (((material instanceof StandardMaterial) && material.normalMap) || (material.isTextureEnabled('normalMap')) ) { if (!mesh.geometry.attributes.tangent.value) { mesh.geometry.generateTangents(); } } if (mesh.geometry.attributes.color.value) { mesh.material.define('VERTEX_COLOR'); } mesh.name = GLTFLoader.generateMeshName(json.meshes, idx, pp); lib.meshes[idx].push(mesh); } }, this); }, _instanceCamera: function (json, nodeInfo) { var cameraInfo = json.cameras[nodeInfo.camera]; if (cameraInfo.type === 'perspective') { var perspectiveInfo = cameraInfo.perspective || {}; return new Perspective$1({ name: nodeInfo.name, aspect: perspectiveInfo.aspectRatio, fov: perspectiveInfo.yfov / Math.PI * 180, far: perspectiveInfo.zfar, near: perspectiveInfo.znear }); } else { var orthographicInfo = cameraInfo.orthographic || {}; return new Orthographic$1({ name: nodeInfo.name, top: orthographicInfo.ymag, right: orthographicInfo.xmag, left: -orthographicInfo.xmag, bottom: -orthographicInfo.ymag, near: orthographicInfo.znear, far: orthographicInfo.zfar }); } }, _parseNodes: function (json, lib) { function instanceMesh(mesh) { return new Mesh({ name: mesh.name, geometry: mesh.geometry, material: mesh.material, culling: mesh.culling, mode: mesh.mode }); } lib.instancedMeshes = []; util$1.each(json.nodes, function (nodeInfo, idx) { var node; if (nodeInfo.camera != null && this.includeCamera) { node = this._instanceCamera(json, nodeInfo); lib.cameras.push(node); } else if (nodeInfo.mesh != null && this.includeMesh) { var primitives = lib.meshes[nodeInfo.mesh]; if (primitives) { if (primitives.length === 1) { // Replace the node with mesh directly node = instanceMesh(primitives[0]); node.setName(nodeInfo.name); lib.instancedMeshes.push(node); } else { node = new Node(); node.setName(nodeInfo.name); for (var j = 0; j < primitives.length; j++) { var newMesh = instanceMesh(primitives[j]); node.add(newMesh); lib.instancedMeshes.push(newMesh); } } } } else { node = new Node(); // PENDING Dulplicate name. node.setName(nodeInfo.name); } if (nodeInfo.matrix) { node.localTransform.setArray(nodeInfo.matrix); node.decomposeLocalTransform(); } else { if (nodeInfo.translation) { node.position.setArray(nodeInfo.translation); } if (nodeInfo.rotation) { node.rotation.setArray(nodeInfo.rotation); } if (nodeInfo.scale) { node.scale.setArray(nodeInfo.scale); } } lib.nodes[idx] = node; }, this); // Build hierarchy util$1.each(json.nodes, function (nodeInfo, idx) { var node = lib.nodes[idx]; if (nodeInfo.children) { for (var i = 0; i < nodeInfo.children.length; i++) { var childIdx = nodeInfo.children[i]; var child = lib.nodes[childIdx]; node.add(child); } } }); }, _parseAnimations: function (json, lib) { function checkChannelPath(channelInfo) { if (channelInfo.path === 'weights') { console.warn('GLTFLoader not support morph targets yet.'); return false; } return true; } function getChannelHash(channelInfo, animationInfo) { return channelInfo.target.node + '_' + animationInfo.samplers[channelInfo.sampler].input; } var timeAccessorMultiplied = {}; util$1.each(json.animations, function (animationInfo, idx) { var channels = animationInfo.channels.filter(checkChannelPath); if (!channels.length) { return; } var tracks = {}; for (var i = 0; i < channels.length; i++) { var channelInfo = channels[i]; var channelHash = getChannelHash(channelInfo, animationInfo); var targetNode = lib.nodes[channelInfo.target.node]; var track = tracks[channelHash]; var samplerInfo = animationInfo.samplers[channelInfo.sampler]; if (!track) { track = tracks[channelHash] = new SamplerTrack({ name: targetNode ? targetNode.name : '', target: targetNode }); track.targetNodeIndex = channelInfo.target.node; track.channels.time = getAccessorData(json, lib, samplerInfo.input); var frameLen = track.channels.time.length; if (!timeAccessorMultiplied[samplerInfo.input]) { for (var k = 0; k < frameLen; k++) { track.channels.time[k] *= 1000; } timeAccessorMultiplied[samplerInfo.input] = true; } } var interpolation = samplerInfo.interpolation || 'LINEAR'; if (interpolation !== 'LINEAR') { console.warn('GLTFLoader only support LINEAR interpolation.'); } var path = channelInfo.target.path; if (path === 'translation') { path = 'position'; } track.channels[path] = getAccessorData(json, lib, samplerInfo.output); } var tracksList = []; for (var hash in tracks) { tracksList.push(tracks[hash]); } var clip = new TrackClip({ name: animationInfo.name, loop: true, tracks: tracksList }); lib.clips.push(clip); }, this); // PENDING var maxLife = lib.clips.reduce(function (maxTime, clip) { return Math.max(maxTime, clip.life); }, 0); lib.clips.forEach(function (clip) { clip.life = maxLife; }); return lib.clips; } }); GLTFLoader.generateMeshName = function (meshes, idx, primitiveIdx) { var meshInfo = meshes[idx]; var meshName = meshInfo.name || ('mesh_' + idx); return primitiveIdx === 0 ? meshName : (meshName + '$' + primitiveIdx); }; /** * @constructor clay.light.Directional * @extends clay.Light * * @example * var light = new clay.light.Directional({ * intensity: 0.5, * color: [1.0, 0.0, 0.0] * }); * light.position.set(10, 10, 10); * light.lookAt(clay.Vector3.ZERO); * scene.add(light); */ var DirectionalLight = Light.extend(/** @lends clay.light.Directional# */ { /** * @type {number} */ shadowBias: 0.001, /** * @type {number} */ shadowSlopeScale: 2.0, /** * Shadow cascade. * Use PSSM technique when it is larger than 1 and have a unique directional light in scene. * @type {number} */ shadowCascade: 1, /** * Available when shadowCascade is larger than 1 and have a unique directional light in scene. * @type {number} */ cascadeSplitLogFactor: 0.2 }, { type: 'DIRECTIONAL_LIGHT', uniformTemplates: { directionalLightDirection: { type: '3f', value: function (instance) { instance.__dir = instance.__dir || new Vector3(); // Direction is target to eye return instance.__dir.copy(instance.worldTransform.z).normalize().negate().array; } }, directionalLightColor: { type: '3f', value: function (instance) { var color = instance.color; var intensity = instance.intensity; return [color[0] * intensity, color[1] * intensity, color[2] * intensity]; } } }, /** * @return {clay.light.Directional} * @memberOf clay.light.Directional.prototype */ clone: function () { var light = Light.prototype.clone.call(this); light.shadowBias = this.shadowBias; light.shadowSlopeScale = this.shadowSlopeScale; return light; } }); /** * @constructor clay.light.Point * @extends clay.Light */ var PointLight = Light.extend(/** @lends clay.light.Point# */ { /** * @type {number} */ range: 100, /** * @type {number} */ castShadow: false }, { type: 'POINT_LIGHT', uniformTemplates: { pointLightPosition: { type: '3f', value: function(instance) { return instance.getWorldPosition().array; } }, pointLightRange: { type: '1f', value: function(instance) { return instance.range; } }, pointLightColor: { type: '3f', value: function(instance) { var color = instance.color; var intensity = instance.intensity; return [color[0] * intensity, color[1] * intensity, color[2] * intensity]; } } }, /** * @return {clay.light.Point} * @memberOf clay.light.Point.prototype */ clone: function() { var light = Light.prototype.clone.call(this); light.range = this.range; return light; } }); /** * @constructor clay.light.Spot * @extends clay.Light */ var SpotLight = Light.extend(/**@lends clay.light.Spot */ { /** * @type {number} */ range: 20, /** * @type {number} */ umbraAngle: 30, /** * @type {number} */ penumbraAngle: 45, /** * @type {number} */ falloffFactor: 2.0, /** * @type {number} */ shadowBias: 0.001, /** * @type {number} */ shadowSlopeScale: 2.0 }, { type: 'SPOT_LIGHT', uniformTemplates: { spotLightPosition: { type: '3f', value: function (instance) { return instance.getWorldPosition().array; } }, spotLightRange: { type: '1f', value: function (instance) { return instance.range; } }, spotLightUmbraAngleCosine: { type: '1f', value: function (instance) { return Math.cos(instance.umbraAngle * Math.PI / 180); } }, spotLightPenumbraAngleCosine: { type: '1f', value: function (instance) { return Math.cos(instance.penumbraAngle * Math.PI / 180); } }, spotLightFalloffFactor: { type: '1f', value: function (instance) { return instance.falloffFactor; } }, spotLightDirection: { type: '3f', value: function (instance) { instance.__dir = instance.__dir || new Vector3(); // Direction is target to eye return instance.__dir.copy(instance.worldTransform.z).negate().array; } }, spotLightColor: { type: '3f', value: function (instance) { var color = instance.color; var intensity = instance.intensity; return [color[0] * intensity, color[1] * intensity, color[2] * intensity]; } } }, /** * @return {clay.light.Spot} * @memberOf clay.light.Spot.prototype */ clone: function () { var light = Light.prototype.clone.call(this); light.range = this.range; light.umbraAngle = this.umbraAngle; light.penumbraAngle = this.penumbraAngle; light.falloffFactor = this.falloffFactor; light.shadowBias = this.shadowBias; light.shadowSlopeScale = this.shadowSlopeScale; return light; } }); /** * @constructor clay.light.Ambient * @extends clay.Light */ var AmbientLight = Light.extend({ castShadow: false }, { type: 'AMBIENT_LIGHT', uniformTemplates: { ambientLightColor: { type: '3f', value: function(instance) { var color = instance.color; var intensity = instance.intensity; return [color[0]*intensity, color[1]*intensity, color[2]*intensity]; } } } /** * @function * @name clone * @return {clay.light.Ambient} * @memberOf clay.light.Ambient.prototype */ }); var KEY_FRAMEBUFFER = 'framebuffer'; var KEY_RENDERBUFFER = 'renderbuffer'; var KEY_RENDERBUFFER_WIDTH = KEY_RENDERBUFFER + '_width'; var KEY_RENDERBUFFER_HEIGHT = KEY_RENDERBUFFER + '_height'; var KEY_RENDERBUFFER_ATTACHED = KEY_RENDERBUFFER + '_attached'; var KEY_DEPTHTEXTURE_ATTACHED = 'depthtexture_attached'; var GL_FRAMEBUFFER = glenum.FRAMEBUFFER; var GL_RENDERBUFFER = glenum.RENDERBUFFER; var GL_DEPTH_ATTACHMENT = glenum.DEPTH_ATTACHMENT; var GL_COLOR_ATTACHMENT0 = glenum.COLOR_ATTACHMENT0; /** * @constructor clay.FrameBuffer * @extends clay.core.Base */ var FrameBuffer = Base.extend( /** @lends clay.FrameBuffer# */ { /** * If use depth buffer * @type {boolean} */ depthBuffer: true, /** * @type {Object} */ viewport: null, _width: 0, _height: 0, _textures: null, _boundRenderer: null, }, function () { // Use cache this._cache = new Cache(); this._textures = {}; }, /**@lends clay.FrameBuffer.prototype. */ { /** * Get attached texture width * {number} */ // FIXME Can't use before #bind getTextureWidth: function () { return this._width; }, /** * Get attached texture height * {number} */ getTextureHeight: function () { return this._height; }, /** * Bind the framebuffer to given renderer before rendering * @param {clay.Renderer} renderer */ bind: function (renderer) { if (renderer.__currentFrameBuffer) { // Already bound if (renderer.__currentFrameBuffer === this) { return; } console.warn('Renderer already bound with another framebuffer. Unbind it first'); } renderer.__currentFrameBuffer = this; var _gl = renderer.gl; _gl.bindFramebuffer(GL_FRAMEBUFFER, this._getFrameBufferGL(renderer)); this._boundRenderer = renderer; var cache = this._cache; cache.put('viewport', renderer.viewport); var hasTextureAttached = false; var width; var height; for (var attachment in this._textures) { hasTextureAttached = true; var obj = this._textures[attachment]; if (obj) { // TODO Do width, height checking, make sure size are same width = obj.texture.width; height = obj.texture.height; // Attach textures this._doAttach(renderer, obj.texture, attachment, obj.target); } } this._width = width; this._height = height; if (!hasTextureAttached && this.depthBuffer) { console.error('Must attach texture before bind, or renderbuffer may have incorrect width and height.'); } if (this.viewport) { renderer.setViewport(this.viewport); } else { renderer.setViewport(0, 0, width, height, 1); } var attachedTextures = cache.get('attached_textures'); if (attachedTextures) { for (var attachment in attachedTextures) { if (!this._textures[attachment]) { var target = attachedTextures[attachment]; this._doDetach(_gl, attachment, target); } } } if (!cache.get(KEY_DEPTHTEXTURE_ATTACHED) && this.depthBuffer) { // Create a new render buffer if (cache.miss(KEY_RENDERBUFFER)) { cache.put(KEY_RENDERBUFFER, _gl.createRenderbuffer()); } var renderbuffer = cache.get(KEY_RENDERBUFFER); if (width !== cache.get(KEY_RENDERBUFFER_WIDTH) || height !== cache.get(KEY_RENDERBUFFER_HEIGHT)) { _gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer); _gl.renderbufferStorage(GL_RENDERBUFFER, _gl.DEPTH_COMPONENT16, width, height); cache.put(KEY_RENDERBUFFER_WIDTH, width); cache.put(KEY_RENDERBUFFER_HEIGHT, height); _gl.bindRenderbuffer(GL_RENDERBUFFER, null); } if (!cache.get(KEY_RENDERBUFFER_ATTACHED)) { _gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer); cache.put(KEY_RENDERBUFFER_ATTACHED, true); } } }, /** * Unbind the frame buffer after rendering * @param {clay.Renderer} renderer */ unbind: function (renderer) { // Remove status record on renderer renderer.__currentFrameBuffer = null; var _gl = renderer.gl; _gl.bindFramebuffer(GL_FRAMEBUFFER, null); this._boundRenderer = null; this._cache.use(renderer.__uid__); var viewport = this._cache.get('viewport'); // Reset viewport; if (viewport) { renderer.setViewport(viewport); } this.updateMipmap(renderer); }, // Because the data of texture is changed over time, // Here update the mipmaps of texture each time after rendered; updateMipmap: function (renderer) { var _gl = renderer.gl; for (var attachment in this._textures) { var obj = this._textures[attachment]; if (obj) { var texture = obj.texture; // FIXME some texture format can't generate mipmap if (!texture.NPOT && texture.useMipmap && texture.minFilter === Texture.LINEAR_MIPMAP_LINEAR) { var target = texture.textureType === 'textureCube' ? glenum.TEXTURE_CUBE_MAP : glenum.TEXTURE_2D; _gl.bindTexture(target, texture.getWebGLTexture(renderer)); _gl.generateMipmap(target); _gl.bindTexture(target, null); } } } }, // 0x8CD5, 36053, FRAMEBUFFER_COMPLETE // 0x8CD6, 36054, FRAMEBUFFER_INCOMPLETE_ATTACHMENT // 0x8CD7, 36055, FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT // 0x8CD9, 36057, FRAMEBUFFER_INCOMPLETE_DIMENSIONS // 0x8CDD, 36061, FRAMEBUFFER_UNSUPPORTED checkStatus: function (_gl) { return _gl.checkFramebufferStatus(GL_FRAMEBUFFER); }, _getFrameBufferGL: function (renderer) { var cache = this._cache; cache.use(renderer.__uid__); if (cache.miss(KEY_FRAMEBUFFER)) { cache.put(KEY_FRAMEBUFFER, renderer.gl.createFramebuffer()); } return cache.get(KEY_FRAMEBUFFER); }, /** * Attach a texture(RTT) to the framebuffer * @param {clay.Texture} texture * @param {number} [attachment=gl.COLOR_ATTACHMENT0] * @param {number} [target=gl.TEXTURE_2D] */ attach: function (texture, attachment, target) { if (!texture.width) { throw new Error('The texture attached to color buffer is not a valid.'); } // TODO width and height check // If the depth_texture extension is enabled, developers // Can attach a depth texture to the depth buffer // http://blog.tojicode.com/2012/07/using-webgldepthtexture.html attachment = attachment || GL_COLOR_ATTACHMENT0; target = target || glenum.TEXTURE_2D; var boundRenderer = this._boundRenderer; var _gl = boundRenderer && boundRenderer.gl; var attachedTextures; if (_gl) { var cache = this._cache; cache.use(boundRenderer.__uid__); attachedTextures = cache.get('attached_textures'); } // Check if texture attached var previous = this._textures[attachment]; if (previous && previous.target === target && previous.texture === texture && (attachedTextures && attachedTextures[attachment] != null) ) { return; } var canAttach = true; if (boundRenderer) { canAttach = this._doAttach(boundRenderer, texture, attachment, target); // Set viewport again incase attached to different size textures. if (!this.viewport) { boundRenderer.setViewport(0, 0, texture.width, texture.height, 1); } } if (canAttach) { this._textures[attachment] = this._textures[attachment] || {}; this._textures[attachment].texture = texture; this._textures[attachment].target = target; } }, _doAttach: function (renderer, texture, attachment, target) { var _gl = renderer.gl; // Make sure texture is always updated // Because texture width or height may be changed and in this we can't be notified // FIXME awkward; var webglTexture = texture.getWebGLTexture(renderer); // Assume cache has been used. var attachedTextures = this._cache.get('attached_textures'); if (attachedTextures && attachedTextures[attachment]) { var obj = attachedTextures[attachment]; // Check if texture and target not changed if (obj.texture === texture && obj.target === target) { return; } } attachment = +attachment; var canAttach = true; if (attachment === GL_DEPTH_ATTACHMENT || attachment === glenum.DEPTH_STENCIL_ATTACHMENT) { var extension = renderer.getGLExtension('WEBGL_depth_texture'); if (!extension) { console.error('Depth texture is not supported by the browser'); canAttach = false; } if (texture.format !== glenum.DEPTH_COMPONENT && texture.format !== glenum.DEPTH_STENCIL ) { console.error('The texture attached to depth buffer is not a valid.'); canAttach = false; } // Dispose render buffer created previous if (canAttach) { var renderbuffer = this._cache.get(KEY_RENDERBUFFER); if (renderbuffer) { _gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, null); _gl.deleteRenderbuffer(renderbuffer); this._cache.put(KEY_RENDERBUFFER, false); } this._cache.put(KEY_RENDERBUFFER_ATTACHED, false); this._cache.put(KEY_DEPTHTEXTURE_ATTACHED, true); } } // Mipmap level can only be 0 _gl.framebufferTexture2D(GL_FRAMEBUFFER, attachment, target, webglTexture, 0); if (!attachedTextures) { attachedTextures = {}; this._cache.put('attached_textures', attachedTextures); } attachedTextures[attachment] = attachedTextures[attachment] || {}; attachedTextures[attachment].texture = texture; attachedTextures[attachment].target = target; return canAttach; }, _doDetach: function (_gl, attachment, target) { // Detach a texture from framebuffer // https://github.com/KhronosGroup/WebGL/blob/master/conformance-suites/1.0.0/conformance/framebuffer-test.html#L145 _gl.framebufferTexture2D(GL_FRAMEBUFFER, attachment, target, null, 0); // Assume cache has been used. var attachedTextures = this._cache.get('attached_textures'); if (attachedTextures && attachedTextures[attachment]) { attachedTextures[attachment] = null; } if (attachment === GL_DEPTH_ATTACHMENT || attachment === glenum.DEPTH_STENCIL_ATTACHMENT) { this._cache.put(KEY_DEPTHTEXTURE_ATTACHED, false); } }, /** * Detach a texture * @param {number} [attachment=gl.COLOR_ATTACHMENT0] * @param {number} [target=gl.TEXTURE_2D] */ detach: function (attachment, target) { // TODO depth extension check ? this._textures[attachment] = null; if (this._boundRenderer) { var cache = this._cache; cache.use(this._boundRenderer.__uid__); this._doDetach(this._boundRenderer.gl, attachment, target); } }, /** * Dispose * @param {WebGLRenderingContext} _gl */ dispose: function (renderer) { var _gl = renderer.gl; var cache = this._cache; cache.use(renderer.__uid__); var renderBuffer = cache.get(KEY_RENDERBUFFER); if (renderBuffer) { _gl.deleteRenderbuffer(renderBuffer); } var frameBuffer = cache.get(KEY_FRAMEBUFFER); if (frameBuffer) { _gl.deleteFramebuffer(frameBuffer); } cache.deleteContext(renderer.__uid__); // Clear cache for reusing this._textures = {}; } }); FrameBuffer.DEPTH_ATTACHMENT = GL_DEPTH_ATTACHMENT; FrameBuffer.COLOR_ATTACHMENT0 = GL_COLOR_ATTACHMENT0; FrameBuffer.STENCIL_ATTACHMENT = glenum.STENCIL_ATTACHMENT; FrameBuffer.DEPTH_STENCIL_ATTACHMENT = glenum.DEPTH_STENCIL_ATTACHMENT; var vertexGlsl = "\n@export clay.compositor.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n v_Texcoord = texcoord;\n gl_Position = worldViewProjection * vec4(position, 1.0);\n}\n@end"; Shader['import'](vertexGlsl); var planeGeo = new Plane$3(); var mesh = new Mesh({ geometry: planeGeo, frustumCulling: false }); var camera$1 = new Orthographic$1(); /** * @constructor clay.compositor.Pass * @extends clay.core.Base */ var Pass = Base.extend(function () { return /** @lends clay.compositor.Pass# */ { /** * Fragment shader string * @type {string} */ // PENDING shader or fragment ? fragment: '', /** * @type {Object} */ outputs: null, /** * @type {clay.Material} */ material: null, /** * @type {Boolean} */ blendWithPrevious: false, /** * @type {Boolean} */ clearColor: false, /** * @type {Boolean} */ clearDepth: true }; }, function() { var shader = new Shader(Shader.source('clay.compositor.vertex'), this.fragment); var material = new Material({ shader: shader }); material.enableTexturesAll(); this.material = material; }, /** @lends clay.compositor.Pass.prototype */ { /** * @param {string} name * @param {} value */ setUniform: function(name, value) { this.material.setUniform(name, value); }, /** * @param {string} name * @return {} */ getUniform: function(name) { var uniform = this.material.uniforms[name]; if (uniform) { return uniform.value; } }, /** * @param {clay.Texture} texture * @param {number} attachment */ attachOutput: function(texture, attachment) { if (!this.outputs) { this.outputs = {}; } attachment = attachment || glenum.COLOR_ATTACHMENT0; this.outputs[attachment] = texture; }, /** * @param {clay.Texture} texture */ detachOutput: function(texture) { for (var attachment in this.outputs) { if (this.outputs[attachment] === texture) { this.outputs[attachment] = null; } } }, bind: function(renderer, frameBuffer) { if (this.outputs) { for (var attachment in this.outputs) { var texture = this.outputs[attachment]; if (texture) { frameBuffer.attach(texture, attachment); } } } if (frameBuffer) { frameBuffer.bind(renderer); } }, unbind: function(renderer, frameBuffer) { frameBuffer.unbind(renderer); }, /** * @param {clay.Renderer} renderer * @param {clay.FrameBuffer} [frameBuffer] */ render: function(renderer, frameBuffer) { var _gl = renderer.gl; if (frameBuffer) { this.bind(renderer, frameBuffer); // MRT Support in chrome // https://www.khronos.org/registry/webgl/sdk/tests/conformance/extensions/ext-draw-buffers.html var ext = renderer.getGLExtension('EXT_draw_buffers'); if (ext && this.outputs) { var bufs = []; for (var attachment in this.outputs) { attachment = +attachment; if (attachment >= _gl.COLOR_ATTACHMENT0 && attachment <= _gl.COLOR_ATTACHMENT0 + 8) { bufs.push(attachment); } } ext.drawBuffersEXT(bufs); } } this.trigger('beforerender', this, renderer); // FIXME Don't clear in each pass in default, let the color overwrite the buffer // FIXME pixels may be discard var clearBit = this.clearDepth ? _gl.DEPTH_BUFFER_BIT : 0; _gl.depthMask(true); if (this.clearColor) { clearBit = clearBit | _gl.COLOR_BUFFER_BIT; _gl.colorMask(true, true, true, true); var cc = this.clearColor; if (Array.isArray(cc)) { _gl.clearColor(cc[0], cc[1], cc[2], cc[3]); } } _gl.clear(clearBit); if (this.blendWithPrevious) { // Blend with previous rendered scene in the final output // FIXME Configure blend. // FIXME It will cause screen blink? _gl.enable(_gl.BLEND); this.material.transparent = true; } else { _gl.disable(_gl.BLEND); this.material.transparent = false; } this.renderQuad(renderer); this.trigger('afterrender', this, renderer); if (frameBuffer) { this.unbind(renderer, frameBuffer); } }, /** * Simply do quad rendering */ renderQuad: function (renderer) { mesh.material = this.material; renderer.renderPass([mesh], camera$1); }, /** * @param {clay.Renderer} renderer */ dispose: function (renderer) {} }); // TODO Should not derived from mesh? Shader.import(skyboxEssl); /** * @constructor clay.plugin.Skybox * * @example * var skyTex = new clay.TextureCube(); * skyTex.load({ * 'px': 'assets/textures/sky/px.jpg', * 'nx': 'assets/textures/sky/nx.jpg' * 'py': 'assets/textures/sky/py.jpg' * 'ny': 'assets/textures/sky/ny.jpg' * 'pz': 'assets/textures/sky/pz.jpg' * 'nz': 'assets/textures/sky/nz.jpg' * }); * var skybox = new clay.plugin.Skybox({ * scene: scene * }); * skybox.material.set('environmentMap', skyTex); */ var Skybox$1 = Mesh.extend(function () { var skyboxShader = new Shader({ vertex: Shader.source('clay.skybox.vertex'), fragment: Shader.source('clay.skybox.fragment') }); var material = new Material({ shader: skyboxShader, depthMask: false }); return { /** * @type {clay.Scene} * @memberOf clay.plugin.Skybox.prototype */ scene: null, geometry: new Cube$1(), material: material, environmentMap: null, culling: false }; }, function () { var scene = this.scene; if (scene) { this.attachScene(scene); } if (this.environmentMap) { this.setEnvironmentMap(this.environmentMap); } }, /** @lends clay.plugin.Skybox# */ { /** * Attach the skybox to the scene * @param {clay.Scene} scene */ attachScene: function (scene) { if (this.scene) { this.detachScene(); } scene.skybox = this; this.scene = scene; scene.on('beforerender', this._beforeRenderScene, this); }, /** * Detach from scene */ detachScene: function () { if (this.scene) { this.scene.off('beforerender', this._beforeRenderScene); this.scene.skybox = null; } this.scene = null; }, /** * Dispose skybox * @param {clay.Renderer} renderer */ dispose: function (renderer) { this.detachScene(); this.geometry.dispose(renderer); }, /** * Set environment map * @param {clay.TextureCube} envMap */ setEnvironmentMap: function (envMap) { if (envMap.textureType === 'texture2D') { this.material.define('EQUIRECTANGULAR'); // LINEAR filter can remove the artifacts in pole envMap.minFilter = Texture.LINEAR; } else { this.material.undefine('EQUIRECTANGULAR'); } this.material.set('environmentMap', envMap); }, /** * Get environment map * @return {clay.TextureCube} */ getEnvironmentMap: function () { return this.material.get('environmentMap'); }, _beforeRenderScene: function(renderer, scene, camera) { this.renderSkybox(renderer, camera); }, renderSkybox: function (renderer, camera) { this.position.copy(camera.getWorldPosition()); this.update(); // Don't remember to disable blend renderer.gl.disable(renderer.gl.BLEND); if (this.material.get('lod') > 0) { this.material.define('fragment', 'LOD'); } else { this.material.undefine('fragment', 'LOD'); } renderer.renderPass([this], camera); } }); var targets$1 = ['px', 'nx', 'py', 'ny', 'pz', 'nz']; /** * Pass rendering scene to a environment cube map * * @constructor clay.prePass.EnvironmentMap * @extends clay.core.Base * @example * // Example of car reflection * var envMap = new clay.TextureCube({ * width: 256, * height: 256 * }); * var envPass = new clay.prePass.EnvironmentMap({ * position: car.position, * texture: envMap * }); * var carBody = car.getChildByName('body'); * carBody.material.enableTexture('environmentMap'); * carBody.material.set('environmentMap', envMap); * ... * animation.on('frame', function(frameTime) { * envPass.render(renderer, scene); * renderer.render(scene, camera); * }); */ var EnvironmentMapPass = Base.extend(function() { var ret = /** @lends clay.prePass.EnvironmentMap# */ { /** * Camera position * @type {clay.Vector3} * @memberOf clay.prePass.EnvironmentMap# */ position: new Vector3(), /** * Camera far plane * @type {number} * @memberOf clay.prePass.EnvironmentMap# */ far: 1000, /** * Camera near plane * @type {number} * @memberOf clay.prePass.EnvironmentMap# */ near: 0.1, /** * Environment cube map * @type {clay.TextureCube} * @memberOf clay.prePass.EnvironmentMap# */ texture: null, /** * Used if you wan't have shadow in environment map * @type {clay.prePass.ShadowMap} */ shadowMapPass: null, }; var cameras = ret._cameras = { px: new Perspective$1({ fov: 90 }), nx: new Perspective$1({ fov: 90 }), py: new Perspective$1({ fov: 90 }), ny: new Perspective$1({ fov: 90 }), pz: new Perspective$1({ fov: 90 }), nz: new Perspective$1({ fov: 90 }) }; cameras.px.lookAt(Vector3.POSITIVE_X, Vector3.NEGATIVE_Y); cameras.nx.lookAt(Vector3.NEGATIVE_X, Vector3.NEGATIVE_Y); cameras.py.lookAt(Vector3.POSITIVE_Y, Vector3.POSITIVE_Z); cameras.ny.lookAt(Vector3.NEGATIVE_Y, Vector3.NEGATIVE_Z); cameras.pz.lookAt(Vector3.POSITIVE_Z, Vector3.NEGATIVE_Y); cameras.nz.lookAt(Vector3.NEGATIVE_Z, Vector3.NEGATIVE_Y); // FIXME In windows, use one framebuffer only renders one side of cubemap ret._frameBuffer = new FrameBuffer(); return ret; }, /** @lends clay.prePass.EnvironmentMap# */ { /** * @param {string} target * @return {clay.Camera} */ getCamera: function (target) { return this._cameras[target]; }, /** * @param {clay.Renderer} renderer * @param {clay.Scene} scene * @param {boolean} [notUpdateScene=false] */ render: function(renderer, scene, notUpdateScene) { var _gl = renderer.gl; if (!notUpdateScene) { scene.update(); } // Tweak fov // http://the-witness.net/news/2012/02/seamless-cube-map-filtering/ var n = this.texture.width; var fov = 2 * Math.atan(n / (n - 0.5)) / Math.PI * 180; for (var i = 0; i < 6; i++) { var target = targets$1[i]; var camera = this._cameras[target]; Vector3.copy(camera.position, this.position); camera.far = this.far; camera.near = this.near; camera.fov = fov; if (this.shadowMapPass) { camera.update(); // update boundingBoxLastFrame var bbox = scene.getBoundingBox(); bbox.applyTransform(camera.viewMatrix); scene.viewBoundingBoxLastFrame.copy(bbox); this.shadowMapPass.render(renderer, scene, camera, true); } this._frameBuffer.attach( this.texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i ); this._frameBuffer.bind(renderer); renderer.render(scene, camera, true); this._frameBuffer.unbind(renderer); } }, /** * @param {clay.Renderer} renderer */ dispose: function (renderer) { this._frameBuffer.dispose(renderer); } }); // http://msdn.microsoft.com/en-us/library/windows/desktop/bb943991(v=vs.85).aspx // https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js var DDS_MAGIC = 0x20534444; var DDSD_MIPMAPCOUNT = 0x20000; var DDSCAPS2_CUBEMAP = 0x200; var DDPF_FOURCC = 0x4; function fourCCToInt32(value) { return value.charCodeAt(0) + (value.charCodeAt(1) << 8) + (value.charCodeAt(2) << 16) + (value.charCodeAt(3) << 24); } var headerLengthInt = 31; // The header length in 32 bit ints var FOURCC_DXT1 = fourCCToInt32('DXT1'); var FOURCC_DXT3 = fourCCToInt32('DXT3'); var FOURCC_DXT5 = fourCCToInt32('DXT5'); // Offsets into the header array var off_magic = 0; var off_size = 1; var off_flags = 2; var off_height = 3; var off_width = 4; var off_mipmapCount = 7; var off_pfFlags = 20; var off_pfFourCC = 21; var off_caps2 = 28; var ret = { parse: function(arrayBuffer, out) { var header = new Int32Array(arrayBuffer, 0, headerLengthInt); if (header[off_magic] !== DDS_MAGIC) { return null; } if (!header(off_pfFlags) & DDPF_FOURCC) { return null; } var fourCC = header(off_pfFourCC); var width = header[off_width]; var height = header[off_height]; var isCubeMap = header[off_caps2] & DDSCAPS2_CUBEMAP; var hasMipmap = header[off_flags] & DDSD_MIPMAPCOUNT; var blockBytes, internalFormat; switch(fourCC) { case FOURCC_DXT1: blockBytes = 8; internalFormat = Texture.COMPRESSED_RGB_S3TC_DXT1_EXT; break; case FOURCC_DXT3: blockBytes = 16; internalFormat = Texture.COMPRESSED_RGBA_S3TC_DXT3_EXT; break; case FOURCC_DXT5: blockBytes = 16; internalFormat = Texture.COMPRESSED_RGBA_S3TC_DXT5_EXT; break; default: return null; } var dataOffset = header[off_size] + 4; // TODO: Suppose all face are existed var faceNumber = isCubeMap ? 6 : 1; var mipmapCount = 1; if (hasMipmap) { mipmapCount = Math.max(1, header[off_mipmapCount]); } var textures = []; for (var f = 0; f < faceNumber; f++) { var _width = width; var _height = height; textures[f] = new Texture2D({ width: _width, height: _height, format: internalFormat }); var mipmaps = []; for (var i = 0; i < mipmapCount; i++) { var dataLength = Math.max(4, _width) / 4 * Math.max(4, _height) / 4 * blockBytes; var byteArray = new Uint8Array(arrayBuffer, dataOffset, dataLength); dataOffset += dataLength; _width *= 0.5; _height *= 0.5; mipmaps[i] = byteArray; } textures[f].pixels = mipmaps[0]; if (hasMipmap) { textures[f].mipmaps = mipmaps; } } // TODO // return isCubeMap ? textures : textures[0]; if (out) { out.width = textures[0].width; out.height = textures[0].height; out.format = textures[0].format; out.pixels = textures[0].pixels; out.mipmaps = textures[0].mipmaps; } else { return textures[0]; } } }; var toChar = String.fromCharCode; var MINELEN = 8; var MAXELEN = 0x7fff; function rgbe2float(rgbe, buffer, offset, exposure) { if (rgbe[3] > 0) { var f = Math.pow(2.0, rgbe[3] - 128 - 8 + exposure); buffer[offset + 0] = rgbe[0] * f; buffer[offset + 1] = rgbe[1] * f; buffer[offset + 2] = rgbe[2] * f; } else { buffer[offset + 0] = 0; buffer[offset + 1] = 0; buffer[offset + 2] = 0; } buffer[offset + 3] = 1.0; return buffer; } function uint82string(array, offset, size) { var str = ''; for (var i = offset; i < size; i++) { str += toChar(array[i]); } return str; } function copyrgbe(s, t) { t[0] = s[0]; t[1] = s[1]; t[2] = s[2]; t[3] = s[3]; } // TODO : check function oldReadColors(scan, buffer, offset, xmax) { var rshift = 0, x = 0, len = xmax; while (len > 0) { scan[x][0] = buffer[offset++]; scan[x][1] = buffer[offset++]; scan[x][2] = buffer[offset++]; scan[x][3] = buffer[offset++]; if (scan[x][0] === 1 && scan[x][1] === 1 && scan[x][2] === 1) { // exp is count of repeated pixels for (var i = (scan[x][3] << rshift) >>> 0; i > 0; i--) { copyrgbe(scan[x-1], scan[x]); x++; len--; } rshift += 8; } else { x++; len--; rshift = 0; } } return offset; } function readColors(scan, buffer, offset, xmax) { if ((xmax < MINELEN) | (xmax > MAXELEN)) { return oldReadColors(scan, buffer, offset, xmax); } var i = buffer[offset++]; if (i != 2) { return oldReadColors(scan, buffer, offset - 1, xmax); } scan[0][1] = buffer[offset++]; scan[0][2] = buffer[offset++]; i = buffer[offset++]; if ((((scan[0][2] << 8) >>> 0) | i) >>> 0 !== xmax) { return null; } for (var i = 0; i < 4; i++) { for (var x = 0; x < xmax;) { var code = buffer[offset++]; if (code > 128) { code = (code & 127) >>> 0; var val = buffer[offset++]; while (code--) { scan[x++][i] = val; } } else { while (code--) { scan[x++][i] = buffer[offset++]; } } } } return offset; } var ret$1 = { // http://www.graphics.cornell.edu/~bjw/rgbe.html // Blender source // http://radsite.lbl.gov/radiance/refer/Notes/picture_format.html parseRGBE: function(arrayBuffer, texture, exposure) { if (exposure == null) { exposure = 0; } var data = new Uint8Array(arrayBuffer); var size = data.length; if (uint82string(data, 0, 2) !== '#?') { return; } // find empty line, next line is resolution info for (var i = 2; i < size; i++) { if (toChar(data[i]) === '\n' && toChar(data[i+1]) === '\n') { break; } } if (i >= size) { // not found return; } // find resolution info line i += 2; var str = ''; for (; i < size; i++) { var _char = toChar(data[i]); if (_char === '\n') { break; } str += _char; } // -Y M +X N var tmp = str.split(' '); var height = parseInt(tmp[1]); var width = parseInt(tmp[3]); if (!width || !height) { return; } // read and decode actual data var offset = i+1; var scanline = []; // memzero for (var x = 0; x < width; x++) { scanline[x] = []; for (var j = 0; j < 4; j++) { scanline[x][j] = 0; } } var pixels = new Float32Array(width * height * 4); var offset2 = 0; for (var y = 0; y < height; y++) { var offset = readColors(scanline, data, offset, width); if (!offset) { return null; } for (var x = 0; x < width; x++) { rgbe2float(scanline[x], pixels, offset2, exposure); offset2 += 4; } } if (!texture) { texture = new Texture2D(); } texture.width = width; texture.height = height; texture.pixels = pixels; // HALF_FLOAT can't use Float32Array texture.type = Texture.FLOAT; return texture; }, parseRGBEFromPNG: function(png) { } }; /** * @alias clay.util.texture */ var textureUtil = { /** * @param {string|object} path * @param {object} [option] * @param {Function} [onsuccess] * @param {Function} [onerror] * @return {clay.Texture} */ loadTexture: function (path, option, onsuccess, onerror) { var texture; if (typeof(option) === 'function') { onsuccess = option; onerror = onsuccess; option = {}; } else { option = option || {}; } if (typeof(path) === 'string') { if (path.match(/.hdr$/) || option.fileType === 'hdr') { texture = new Texture2D({ width: 0, height: 0, sRGB: false }); textureUtil._fetchTexture( path, function (data) { ret$1.parseRGBE(data, texture, option.exposure); texture.dirty(); onsuccess && onsuccess(texture); }, onerror ); return texture; } else if (path.match(/.dds$/) || option.fileType === 'dds') { texture = new Texture2D({ width: 0, height: 0 }); textureUtil._fetchTexture( path, function (data) { ret.parse(data, texture); texture.dirty(); onsuccess && onsuccess(texture); }, onerror ); } else { texture = new Texture2D(); texture.load(path); texture.success(onsuccess); texture.error(onerror); } } else if (typeof path === 'object' && typeof(path.px) !== 'undefined') { texture = new TextureCube(); texture.load(path); texture.success(onsuccess); texture.error(onerror); } return texture; }, /** * Load a panorama texture and render it to a cube map * @param {clay.Renderer} renderer * @param {string} path * @param {clay.TextureCube} cubeMap * @param {object} [option] * @param {boolean} [option.encodeRGBM] * @param {number} [option.exposure] * @param {Function} [onsuccess] * @param {Function} [onerror] */ loadPanorama: function (renderer, path, cubeMap, option, onsuccess, onerror) { var self = this; if (typeof(option) === 'function') { onsuccess = option; onerror = onsuccess; option = {}; } else { option = option || {}; } textureUtil.loadTexture(path, option, function (texture) { // PENDING texture.flipY = option.flipY || false; self.panoramaToCubeMap(renderer, texture, cubeMap, option); texture.dispose(renderer); onsuccess && onsuccess(cubeMap); }, onerror); }, /** * Render a panorama texture to a cube map * @param {clay.Renderer} renderer * @param {clay.Texture2D} panoramaMap * @param {clay.TextureCube} cubeMap * @param {Object} option * @param {boolean} [option.encodeRGBM] */ panoramaToCubeMap: function (renderer, panoramaMap, cubeMap, option) { var environmentMapPass = new EnvironmentMapPass(); var skydome = new Skybox$1({ scene: new Scene() }); skydome.setEnvironmentMap(panoramaMap); option = option || {}; if (option.encodeRGBM) { skydome.material.define('fragment', 'RGBM_ENCODE'); } // Share sRGB cubeMap.sRGB = panoramaMap.sRGB; environmentMapPass.texture = cubeMap; environmentMapPass.render(renderer, skydome.scene); environmentMapPass.texture = null; environmentMapPass.dispose(renderer); return cubeMap; }, /** * Convert height map to normal map * @param {HTMLImageElement|HTMLCanvasElement} image * @param {boolean} [checkBump=false] * @return {HTMLCanvasElement} */ heightToNormal: function (image, checkBump) { var canvas = document.createElement('canvas'); var width = canvas.width = image.width; var height = canvas.height = image.height; var ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0, width, height); checkBump = checkBump || false; var srcData = ctx.getImageData(0, 0, width, height); var dstData = ctx.createImageData(width, height); for (var i = 0; i < srcData.data.length; i += 4) { if (checkBump) { var r = srcData.data[i]; var g = srcData.data[i + 1]; var b = srcData.data[i + 2]; var diff = Math.abs(r - g) + Math.abs(g - b); if (diff > 20) { console.warn('Given image is not a height map'); return image; } } // Modified from http://mrdoob.com/lab/javascript/height2normal/ var x1, y1, x2, y2; if (i % (width * 4) === 0) { // left edge x1 = srcData.data[i]; x2 = srcData.data[i + 4]; } else if (i % (width * 4) === (width - 1) * 4) { // right edge x1 = srcData.data[i - 4]; x2 = srcData.data[i]; } else { x1 = srcData.data[i - 4]; x2 = srcData.data[i + 4]; } if (i < width * 4) { // top edge y1 = srcData.data[i]; y2 = srcData.data[i + width * 4]; } else if (i > width * (height - 1) * 4) { // bottom edge y1 = srcData.data[i - width * 4]; y2 = srcData.data[i]; } else { y1 = srcData.data[i - width * 4]; y2 = srcData.data[i + width * 4]; } dstData.data[i] = (x1 - x2) + 127; dstData.data[i + 1] = (y1 - y2) + 127; dstData.data[i + 2] = 255; dstData.data[i + 3] = 255; } ctx.putImageData(dstData, 0, 0); return canvas; }, /** * Convert height map to normal map * @param {HTMLImageElement|HTMLCanvasElement} image * @param {boolean} [checkBump=false] * @param {number} [threshold=20] * @return {HTMLCanvasElement} */ isHeightImage: function (img, downScaleSize, threshold) { if (!img || !img.width || !img.height) { return false; } var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var size = downScaleSize || 32; threshold = threshold || 20; canvas.width = canvas.height = size; ctx.drawImage(img, 0, 0, size, size); var srcData = ctx.getImageData(0, 0, size, size); for (var i = 0; i < srcData.data.length; i += 4) { var r = srcData.data[i]; var g = srcData.data[i + 1]; var b = srcData.data[i + 2]; var diff = Math.abs(r - g) + Math.abs(g - b); if (diff > threshold) { return false; } } return true; }, _fetchTexture: function (path, onsuccess, onerror) { vendor.request.get({ url: path, responseType: 'arraybuffer', onload: onsuccess, onerror: onerror }); }, /** * Create a chessboard texture * @param {number} [size] * @param {number} [unitSize] * @param {string} [color1] * @param {string} [color2] * @return {clay.Texture2D} */ createChessboard: function (size, unitSize, color1, color2) { size = size || 512; unitSize = unitSize || 64; color1 = color1 || 'black'; color2 = color2 || 'white'; var repeat = Math.ceil(size / unitSize); var canvas = document.createElement('canvas'); canvas.width = size; canvas.height = size; var ctx = canvas.getContext('2d'); ctx.fillStyle = color2; ctx.fillRect(0, 0, size, size); ctx.fillStyle = color1; for (var i = 0; i < repeat; i++) { for (var j = 0; j < repeat; j++) { var isFill = j % 2 ? (i % 2) : (i % 2 - 1); if (isFill) { ctx.fillRect(i * unitSize, j * unitSize, unitSize, unitSize); } } } var texture = new Texture2D({ image: canvas, anisotropic: 8 }); return texture; }, /** * Create a blank pure color 1x1 texture * @param {string} color * @return {clay.Texture2D} */ createBlank: function (color) { var canvas = document.createElement('canvas'); canvas.width = 1; canvas.height = 1; var ctx = canvas.getContext('2d'); ctx.fillStyle = color; ctx.fillRect(0, 0, 1, 1); var texture = new Texture2D({ image: canvas }); return texture; } }; var integrateBRDFShaderCode = "#define SAMPLE_NUMBER 1024\n#define PI 3.14159265358979\nuniform sampler2D normalDistribution;\nuniform vec2 viewportSize : [512, 256];\nconst vec3 N = vec3(0.0, 0.0, 1.0);\nconst float fSampleNumber = float(SAMPLE_NUMBER);\nvec3 importanceSampleNormal(float i, float roughness, vec3 N) {\n vec3 H = texture2D(normalDistribution, vec2(roughness, i)).rgb;\n vec3 upVector = abs(N.y) > 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nfloat G_Smith(float roughness, float NoV, float NoL) {\n float k = roughness * roughness / 2.0;\n float G1V = NoV / (NoV * (1.0 - k) + k);\n float G1L = NoL / (NoL * (1.0 - k) + k);\n return G1L * G1V;\n}\nvoid main() {\n vec2 uv = gl_FragCoord.xy / viewportSize;\n float NoV = uv.x;\n float roughness = uv.y;\n vec3 V;\n V.x = sqrt(1.0 - NoV * NoV);\n V.y = 0.0;\n V.z = NoV;\n float A = 0.0;\n float B = 0.0;\n for (int i = 0; i < SAMPLE_NUMBER; i++) {\n vec3 H = importanceSampleNormal(float(i) / fSampleNumber, roughness, N);\n vec3 L = reflect(-V, H);\n float NoL = clamp(L.z, 0.0, 1.0);\n float NoH = clamp(H.z, 0.0, 1.0);\n float VoH = clamp(dot(V, H), 0.0, 1.0);\n if (NoL > 0.0) {\n float G = G_Smith(roughness, NoV, NoL);\n float G_Vis = G * VoH / (NoH * NoV);\n float Fc = pow(1.0 - VoH, 5.0);\n A += (1.0 - Fc) * G_Vis;\n B += Fc * G_Vis;\n }\n }\n gl_FragColor = vec4(vec2(A, B) / fSampleNumber, 0.0, 1.0);\n}\n"; var prefilterFragCode = "#define SHADER_NAME prefilter\n#define SAMPLE_NUMBER 1024\n#define PI 3.14159265358979\nuniform mat4 viewInverse : VIEWINVERSE;\nuniform samplerCube environmentMap;\nuniform sampler2D normalDistribution;\nuniform float roughness : 0.5;\nvarying vec2 v_Texcoord;\nvarying vec3 v_WorldPosition;\n@import clay.util.rgbm\nvec3 importanceSampleNormal(float i, float roughness, vec3 N) {\n vec3 H = texture2D(normalDistribution, vec2(roughness, i)).rgb;\n vec3 upVector = abs(N.y) > 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nvoid main() {\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(v_WorldPosition - eyePos);\n vec3 N = V;\n vec3 prefilteredColor = vec3(0.0);\n float totalWeight = 0.0;\n float fMaxSampleNumber = float(SAMPLE_NUMBER);\n for (int i = 0; i < SAMPLE_NUMBER; i++) {\n vec3 H = importanceSampleNormal(float(i) / fMaxSampleNumber, roughness, N);\n vec3 L = reflect(-V, H);\n float NoL = clamp(dot(N, L), 0.0, 1.0);\n if (NoL > 0.0) {\n prefilteredColor += decodeHDR(textureCube(environmentMap, L)).rgb * NoL;\n totalWeight += NoL;\n }\n }\n gl_FragColor = encodeHDR(vec4(prefilteredColor / totalWeight, 1.0));\n}\n"; // Cubemap prefilter utility // http://www.unrealengine.com/files/downloads/2013SiggraphPresentationsNotes.pdf // http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html var cubemapUtil = {}; var targets = ['px', 'nx', 'py', 'ny', 'pz', 'nz']; // TODO Downsample /** * @name clay.util.cubemap.prefilterEnvironmentMap * @param {clay.Renderer} renderer * @param {clay.Texture} envMap * @param {Object} [textureOpts] * @param {number} [textureOpts.width=64] * @param {number} [textureOpts.height=64] * @param {number} [textureOpts.type] * @param {boolean} [textureOpts.encodeRGBM=false] * @param {boolean} [textureOpts.decodeRGBM=false] * @param {clay.Texture2D} [normalDistribution] * @param {clay.Texture2D} [brdfLookup] */ cubemapUtil.prefilterEnvironmentMap = function ( renderer, envMap, textureOpts, normalDistribution, brdfLookup ) { // Not create other renderer, it is easy having issue of cross reference of resources like framebuffer // PENDING preserveDrawingBuffer? if (!brdfLookup || !normalDistribution) { normalDistribution = cubemapUtil.generateNormalDistribution(); brdfLookup = cubemapUtil.integrateBRDF(renderer, normalDistribution); } textureOpts = textureOpts || {}; var width = textureOpts.width || 64; var height = textureOpts.height || 64; var textureType = textureOpts.type || envMap.type; // Use same type with given envMap var prefilteredCubeMap = new TextureCube({ width: width, height: height, type: textureType, flipY: false, mipmaps: [] }); if (!prefilteredCubeMap.isPowerOfTwo()) { console.warn('Width and height must be power of two to enable mipmap.'); } var size = Math.min(width, height); var mipmapNum = Math.log(size) / Math.log(2) + 1; var prefilterMaterial = new Material({ shader: new Shader({ vertex: Shader.source('clay.skybox.vertex'), fragment: prefilterFragCode }) }); prefilterMaterial.set('normalDistribution', normalDistribution); textureOpts.encodeRGBM && prefilterMaterial.define('fragment', 'RGBM_ENCODE'); textureOpts.decodeRGBM && prefilterMaterial.define('fragment', 'RGBM_DECODE'); var dummyScene = new Scene(); var skyEnv; if (envMap.textureType === 'texture2D') { // Convert panorama to cubemap var envCubemap = new TextureCube({ width: width, height: height, // FIXME FLOAT type will cause GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT error on iOS type: textureType === Texture.FLOAT ? Texture.HALF_FLOAT : textureType }); textureUtil.panoramaToCubeMap(renderer, envMap, envCubemap, { // PENDING encodeRGBM so it can be decoded as RGBM encodeRGBM: textureOpts.decodeRGBM }); envMap = envCubemap; } skyEnv = new Skybox$1({ scene: dummyScene, material: prefilterMaterial }); skyEnv.material.set('environmentMap', envMap); var envMapPass = new EnvironmentMapPass({ texture: prefilteredCubeMap }); // Force to be UNSIGNED_BYTE if (textureOpts.encodeRGBM) { textureType = prefilteredCubeMap.type = Texture.UNSIGNED_BYTE; } var renderTargetTmp = new Texture2D({ width: width, height: height, type: textureType }); var frameBuffer = new FrameBuffer({ depthBuffer: false }); var ArrayCtor = vendor[textureType === Texture.UNSIGNED_BYTE ? 'Uint8Array' : 'Float32Array']; for (var i = 0; i < mipmapNum; i++) { // console.time('prefilter'); prefilteredCubeMap.mipmaps[i] = { pixels: {} }; skyEnv.material.set('roughness', i / (mipmapNum - 1)); // Tweak fov // http://the-witness.net/news/2012/02/seamless-cube-map-filtering/ var n = renderTargetTmp.width; var fov = 2 * Math.atan(n / (n - 0.5)) / Math.PI * 180; for (var j = 0; j < targets.length; j++) { var pixels = new ArrayCtor(renderTargetTmp.width * renderTargetTmp.height * 4); frameBuffer.attach(renderTargetTmp); frameBuffer.bind(renderer); var camera = envMapPass.getCamera(targets[j]); camera.fov = fov; renderer.render(dummyScene, camera); renderer.gl.readPixels( 0, 0, renderTargetTmp.width, renderTargetTmp.height, Texture.RGBA, textureType, pixels ); // var canvas = document.createElement('canvas'); // var ctx = canvas.getContext('2d'); // canvas.width = renderTargetTmp.width; // canvas.height = renderTargetTmp.height; // var imageData = ctx.createImageData(renderTargetTmp.width, renderTargetTmp.height); // for (var k = 0; k < pixels.length; k++) { // imageData.data[k] = pixels[k]; // } // ctx.putImageData(imageData, 0, 0); // document.body.appendChild(canvas); frameBuffer.unbind(renderer); prefilteredCubeMap.mipmaps[i].pixels[targets[j]] = pixels; } renderTargetTmp.width /= 2; renderTargetTmp.height /= 2; renderTargetTmp.dirty(); // console.timeEnd('prefilter'); } frameBuffer.dispose(renderer); renderTargetTmp.dispose(renderer); skyEnv.dispose(renderer); // Remove gpu resource allucated in renderer normalDistribution.dispose(renderer); // renderer.dispose(); return { environmentMap: prefilteredCubeMap, brdfLookup: brdfLookup, normalDistribution: normalDistribution, maxMipmapLevel: mipmapNum }; }; cubemapUtil.integrateBRDF = function (renderer, normalDistribution) { normalDistribution = normalDistribution || cubemapUtil.generateNormalDistribution(); var framebuffer = new FrameBuffer({ depthBuffer: false }); var pass = new Pass({ fragment: integrateBRDFShaderCode }); var texture = new Texture2D({ width: 512, height: 256, type: Texture.HALF_FLOAT, wrapS: Texture.CLAMP_TO_EDGE, wrapT: Texture.CLAMP_TO_EDGE, minFilter: Texture.NEAREST, magFilter: Texture.NEAREST, useMipmap: false }); pass.setUniform('normalDistribution', normalDistribution); pass.setUniform('viewportSize', [512, 256]); pass.attachOutput(texture); pass.render(renderer, framebuffer); // FIXME Only chrome and firefox can readPixels with float type. // framebuffer.bind(renderer); // var pixels = new Float32Array(512 * 256 * 4); // renderer.gl.readPixels( // 0, 0, texture.width, texture.height, // Texture.RGBA, Texture.FLOAT, pixels // ); // texture.pixels = pixels; // texture.flipY = false; // texture.dirty(); // framebuffer.unbind(renderer); framebuffer.dispose(renderer); return texture; }; cubemapUtil.generateNormalDistribution = function (roughnessLevels, sampleSize) { // http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html // GLSL not support bit operation, use lookup instead // V -> i / N, U -> roughness var roughnessLevels = roughnessLevels || 256; var sampleSize = sampleSize || 1024; var normalDistribution = new Texture2D({ width: roughnessLevels, height: sampleSize, type: Texture.FLOAT, minFilter: Texture.NEAREST, magFilter: Texture.NEAREST, wrapS: Texture.CLAMP_TO_EDGE, wrapT: Texture.CLAMP_TO_EDGE, useMipmap: false }); var pixels = new Float32Array(sampleSize * roughnessLevels * 4); var tmp = []; // function sortFunc(a, b) { // return Math.abs(b) - Math.abs(a); // } for (var j = 0; j < roughnessLevels; j++) { var roughness = j / roughnessLevels; var a = roughness * roughness; for (var i = 0; i < sampleSize; i++) { // http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators // http://stackoverflow.com/questions/1908492/unsigned-integer-in-javascript // http://stackoverflow.com/questions/1822350/what-is-the-javascript-operator-and-how-do-you-use-it var y = (i << 16 | i >>> 16) >>> 0; y = ((y & 1431655765) << 1 | (y & 2863311530) >>> 1) >>> 0; y = ((y & 858993459) << 2 | (y & 3435973836) >>> 2) >>> 0; y = ((y & 252645135) << 4 | (y & 4042322160) >>> 4) >>> 0; y = (((y & 16711935) << 8 | (y & 4278255360) >>> 8) >>> 0) / 4294967296; // CDF var cosTheta = Math.sqrt((1 - y) / (1 + (a * a - 1.0) * y)); tmp[i] = cosTheta; } for (var i = 0; i < sampleSize; i++) { var offset = (i * roughnessLevels + j) * 4; var cosTheta = tmp[i]; var sinTheta = Math.sqrt(1.0 - cosTheta * cosTheta); var x = i / sampleSize; var phi = 2.0 * Math.PI * x; pixels[offset] = sinTheta * Math.cos(phi); pixels[offset + 1] = cosTheta; pixels[offset + 2] = sinTheta * Math.sin(phi); pixels[offset + 3] = 1.0; } } normalDistribution.pixels = pixels; return normalDistribution; }; // https://docs.unrealengine.com/latest/INT/Engine/Rendering/LightingAndShadows/AmbientCubemap/ /** * Ambient cubemap light provides specular parts of Image Based Lighting. * Which is a basic requirement for Physically Based Rendering * @constructor clay.light.AmbientCubemap * @extends clay.Light */ var AmbientCubemapLight = Light.extend({ /** * @type {clay.TextureCube} * @memberOf clay.light.AmbientCubemap# */ cubemap: null, // TODO // range: 100, castShadow: false, _normalDistribution: null, _brdfLookup: null }, /** @lends clay.light.AmbientCubemap# */ { type: 'AMBIENT_CUBEMAP_LIGHT', /** * Do prefitering the cubemap * @param {clay.Renderer} renderer * @param {number} [size=32] */ prefilter: function (renderer, size) { if (!renderer.getGLExtension('EXT_shader_texture_lod')) { console.warn('Device not support textureCubeLodEXT'); return; } if (!this._brdfLookup) { this._normalDistribution = cubemapUtil.generateNormalDistribution(); this._brdfLookup = cubemapUtil.integrateBRDF(renderer, this._normalDistribution); } var cubemap = this.cubemap; if (cubemap.__prefiltered) { return; } var result = cubemapUtil.prefilterEnvironmentMap( renderer, cubemap, { encodeRGBM: true, width: size, height: size }, this._normalDistribution, this._brdfLookup ); this.cubemap = result.environmentMap; this.cubemap.__prefiltered = true; cubemap.dispose(renderer); }, getBRDFLookup: function () { return this._brdfLookup; }, uniformTemplates: { ambientCubemapLightColor: { type: '3f', value: function (instance) { var color = instance.color; var intensity = instance.intensity; return [color[0]*intensity, color[1]*intensity, color[2]*intensity]; } }, ambientCubemapLightCubemap: { type: 't', value: function (instance) { return instance.cubemap; } }, ambientCubemapLightBRDFLookup: { type: 't', value: function (instance) { return instance._brdfLookup; } } } /** * @function * @name clone * @return {clay.light.AmbientCubemap} * @memberOf clay.light.AmbientCubemap.prototype */ }); /** * Spherical Harmonic Ambient Light * @constructor clay.light.AmbientSH * @extends clay.Light */ var AmbientSHLight = Light.extend({ castShadow: false, /** * Spherical Harmonic Coefficients * @type {Array.} * @memberOf clay.light.AmbientSH# */ coefficients: [], }, function () { this._coefficientsTmpArr = new vendor.Float32Array(9 * 3); }, { type: 'AMBIENT_SH_LIGHT', uniformTemplates: { ambientSHLightColor: { type: '3f', value: function (instance) { var color = instance.color; var intensity = instance.intensity; return [color[0] * intensity, color[1] * intensity, color[2] * intensity]; } }, ambientSHLightCoefficients: { type: '3f', value: function (instance) { var coefficientsTmpArr = instance._coefficientsTmpArr; for (var i = 0; i < instance.coefficients.length; i++) { coefficientsTmpArr[i] = instance.coefficients[i]; } return coefficientsTmpArr; } } } /** * @function * @name clone * @return {clay.light.Ambient} * @memberOf clay.light.Ambient.prototype */ }); var TexturePool = function () { this._pool = {}; this._allocatedTextures = []; }; TexturePool.prototype = { constructor: TexturePool, get: function (parameters) { var key = generateKey(parameters); if (!this._pool.hasOwnProperty(key)) { this._pool[key] = []; } var list = this._pool[key]; if (!list.length) { var texture = new Texture2D(parameters); this._allocatedTextures.push(texture); return texture; } return list.pop(); }, put: function (texture) { var key = generateKey(texture); if (!this._pool.hasOwnProperty(key)) { this._pool[key] = []; } var list = this._pool[key]; list.push(texture); }, clear: function (renderer) { for (var i = 0; i < this._allocatedTextures.length; i++) { this._allocatedTextures[i].dispose(renderer); } this._pool = {}; this._allocatedTextures = []; } }; var defaultParams = { width: 512, height: 512, type: glenum.UNSIGNED_BYTE, format: glenum.RGBA, wrapS: glenum.CLAMP_TO_EDGE, wrapT: glenum.CLAMP_TO_EDGE, minFilter: glenum.LINEAR_MIPMAP_LINEAR, magFilter: glenum.LINEAR, useMipmap: true, anisotropic: 1, flipY: true, unpackAlignment: 4, premultiplyAlpha: false }; var defaultParamPropList = Object.keys(defaultParams); function generateKey(parameters) { util$1.defaultsWithPropList(parameters, defaultParams, defaultParamPropList); fallBack(parameters); var key = ''; for (var i = 0; i < defaultParamPropList.length; i++) { var name = defaultParamPropList[i]; var chunk = parameters[name].toString(); key += chunk; } return key; } function fallBack(target) { var IPOT = isPowerOfTwo$2(target.width, target.height); if (target.format === glenum.DEPTH_COMPONENT) { target.useMipmap = false; } if (!IPOT || !target.useMipmap) { if (target.minFilter == glenum.NEAREST_MIPMAP_NEAREST || target.minFilter == glenum.NEAREST_MIPMAP_LINEAR) { target.minFilter = glenum.NEAREST; } else if ( target.minFilter == glenum.LINEAR_MIPMAP_LINEAR || target.minFilter == glenum.LINEAR_MIPMAP_NEAREST ) { target.minFilter = glenum.LINEAR; } } if (!IPOT) { target.wrapS = glenum.CLAMP_TO_EDGE; target.wrapT = glenum.CLAMP_TO_EDGE; } } function isPowerOfTwo$2(width, height) { return (width & (width-1)) === 0 && (height & (height-1)) === 0; } var shadowmapEssl = "@export clay.sm.depth.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\n@import clay.chunk.skinning_header\nvarying vec4 v_ViewPosition;\nvarying vec2 v_Texcoord;\nvoid main(){\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n v_ViewPosition = worldViewProjection * vec4(skinnedPosition, 1.0);\n gl_Position = v_ViewPosition;\n v_Texcoord = texcoord;\n}\n@end\n@export clay.sm.depth.fragment\nvarying vec4 v_ViewPosition;\nvarying vec2 v_Texcoord;\nuniform float bias : 0.001;\nuniform float slopeScale : 1.0;\nuniform sampler2D alphaMap;\nuniform float alphaCutoff: 0.0;\n@import clay.util.encode_float\nvoid main(){\n float depth = v_ViewPosition.z / v_ViewPosition.w;\n if (alphaCutoff > 0.0) {\n if (texture2D(alphaMap, v_Texcoord).a <= alphaCutoff) {\n discard;\n }\n }\n#ifdef USE_VSM\n depth = depth * 0.5 + 0.5;\n float moment1 = depth;\n float moment2 = depth * depth;\n float dx = dFdx(depth);\n float dy = dFdy(depth);\n moment2 += 0.25*(dx*dx+dy*dy);\n gl_FragColor = vec4(moment1, moment2, 0.0, 1.0);\n#else\n float dx = dFdx(depth);\n float dy = dFdy(depth);\n depth += sqrt(dx*dx + dy*dy) * slopeScale + bias;\n gl_FragColor = encodeFloat(depth * 0.5 + 0.5);\n#endif\n}\n@end\n@export clay.sm.debug_depth\nuniform sampler2D depthMap;\nvarying vec2 v_Texcoord;\n@import clay.util.decode_float\nvoid main() {\n vec4 tex = texture2D(depthMap, v_Texcoord);\n#ifdef USE_VSM\n gl_FragColor = vec4(tex.rgb, 1.0);\n#else\n float depth = decodeFloat(tex);\n gl_FragColor = vec4(depth, depth, depth, 1.0);\n#endif\n}\n@end\n@export clay.sm.distance.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 world : WORLD;\nattribute vec3 position : POSITION;\n@import clay.chunk.skinning_header\nvarying vec3 v_WorldPosition;\nvoid main (){\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition , 1.0);\n v_WorldPosition = (world * vec4(skinnedPosition, 1.0)).xyz;\n}\n@end\n@export clay.sm.distance.fragment\nuniform vec3 lightPosition;\nuniform float range : 100;\nvarying vec3 v_WorldPosition;\n@import clay.util.encode_float\nvoid main(){\n float dist = distance(lightPosition, v_WorldPosition);\n#ifdef USE_VSM\n gl_FragColor = vec4(dist, dist * dist, 0.0, 0.0);\n#else\n dist = dist / range;\n gl_FragColor = encodeFloat(dist);\n#endif\n}\n@end\n@export clay.plugin.shadow_map_common\n@import clay.util.decode_float\nfloat tapShadowMap(sampler2D map, vec2 uv, float z){\n vec4 tex = texture2D(map, uv);\n return step(z, decodeFloat(tex) * 2.0 - 1.0);\n}\nfloat pcf(sampler2D map, vec2 uv, float z, float textureSize, vec2 scale) {\n float shadowContrib = tapShadowMap(map, uv, z);\n vec2 offset = vec2(1.0 / textureSize) * scale;\n#ifdef PCF_KERNEL_SIZE\n for (int _idx_ = 0; _idx_ < PCF_KERNEL_SIZE; _idx_++) {{\n shadowContrib += tapShadowMap(map, uv + offset * pcfKernel[_idx_], z);\n }}\n return shadowContrib / float(PCF_KERNEL_SIZE + 1);\n#else\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, 0.0), z);\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(0.0, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, 0.0), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, -offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, -offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(0.0, -offset.y), z);\n return shadowContrib / 9.0;\n#endif\n}\nfloat pcf(sampler2D map, vec2 uv, float z, float textureSize) {\n return pcf(map, uv, z, textureSize, vec2(1.0));\n}\nfloat chebyshevUpperBound(vec2 moments, float z){\n float p = 0.0;\n z = z * 0.5 + 0.5;\n if (z <= moments.x) {\n p = 1.0;\n }\n float variance = moments.y - moments.x * moments.x;\n variance = max(variance, 0.0000001);\n float mD = moments.x - z;\n float pMax = variance / (variance + mD * mD);\n pMax = clamp((pMax-0.4)/(1.0-0.4), 0.0, 1.0);\n return max(p, pMax);\n}\nfloat computeShadowContrib(\n sampler2D map, mat4 lightVPM, vec3 position, float textureSize, vec2 scale, vec2 offset\n) {\n vec4 posInLightSpace = lightVPM * vec4(position, 1.0);\n posInLightSpace.xyz /= posInLightSpace.w;\n float z = posInLightSpace.z;\n if(all(greaterThan(posInLightSpace.xyz, vec3(-0.99, -0.99, -1.0))) &&\n all(lessThan(posInLightSpace.xyz, vec3(0.99, 0.99, 1.0)))){\n vec2 uv = (posInLightSpace.xy+1.0) / 2.0;\n #ifdef USE_VSM\n vec2 moments = texture2D(map, uv * scale + offset).xy;\n return chebyshevUpperBound(moments, z);\n #else\n return pcf(map, uv * scale + offset, z, textureSize, scale);\n #endif\n }\n return 1.0;\n}\nfloat computeShadowContrib(sampler2D map, mat4 lightVPM, vec3 position, float textureSize) {\n return computeShadowContrib(map, lightVPM, position, textureSize, vec2(1.0), vec2(0.0));\n}\nfloat computeShadowContribOmni(samplerCube map, vec3 direction, float range)\n{\n float dist = length(direction);\n vec4 shadowTex = textureCube(map, direction);\n#ifdef USE_VSM\n vec2 moments = shadowTex.xy;\n float variance = moments.y - moments.x * moments.x;\n float mD = moments.x - dist;\n float p = variance / (variance + mD * mD);\n if(moments.x + 0.001 < dist){\n return clamp(p, 0.0, 1.0);\n }else{\n return 1.0;\n }\n#else\n return step(dist, (decodeFloat(shadowTex) + 0.0002) * range);\n#endif\n}\n@end\n@export clay.plugin.compute_shadow_map\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT) || defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT) || defined(POINT_LIGHT_SHADOWMAP_COUNT)\n#ifdef SPOT_LIGHT_SHADOWMAP_COUNT\nuniform sampler2D spotLightShadowMaps[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform mat4 spotLightMatrices[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform float spotLightShadowMapSizes[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\n#ifdef DIRECTIONAL_LIGHT_SHADOWMAP_COUNT\n#if defined(SHADOW_CASCADE)\nuniform sampler2D directionalLightShadowMaps[1]:unconfigurable;\nuniform mat4 directionalLightMatrices[SHADOW_CASCADE]:unconfigurable;\nuniform float directionalLightShadowMapSizes[1]:unconfigurable;\nuniform float shadowCascadeClipsNear[SHADOW_CASCADE]:unconfigurable;\nuniform float shadowCascadeClipsFar[SHADOW_CASCADE]:unconfigurable;\n#else\nuniform sampler2D directionalLightShadowMaps[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform mat4 directionalLightMatrices[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform float directionalLightShadowMapSizes[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\n#endif\n#ifdef POINT_LIGHT_SHADOWMAP_COUNT\nuniform samplerCube pointLightShadowMaps[POINT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\nuniform bool shadowEnabled : true;\n#ifdef PCF_KERNEL_SIZE\nuniform vec2 pcfKernel[PCF_KERNEL_SIZE];\n#endif\n@import clay.plugin.shadow_map_common\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\nvoid computeShadowOfSpotLights(vec3 position, inout float shadowContribs[SPOT_LIGHT_COUNT] ) {\n float shadowContrib;\n for(int _idx_ = 0; _idx_ < SPOT_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n shadowContrib = computeShadowContrib(\n spotLightShadowMaps[_idx_], spotLightMatrices[_idx_], position,\n spotLightShadowMapSizes[_idx_]\n );\n shadowContribs[_idx_] = shadowContrib;\n }}\n for(int _idx_ = SPOT_LIGHT_SHADOWMAP_COUNT; _idx_ < SPOT_LIGHT_COUNT; _idx_++){{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n#ifdef SHADOW_CASCADE\nvoid computeShadowOfDirectionalLights(vec3 position, inout float shadowContribs[DIRECTIONAL_LIGHT_COUNT]){\n float depth = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far)\n / (gl_DepthRange.far - gl_DepthRange.near);\n float shadowContrib;\n shadowContribs[0] = 1.0;\n for (int _idx_ = 0; _idx_ < SHADOW_CASCADE; _idx_++) {{\n if (\n depth >= shadowCascadeClipsNear[_idx_] &&\n depth <= shadowCascadeClipsFar[_idx_]\n ) {\n shadowContrib = computeShadowContrib(\n directionalLightShadowMaps[0], directionalLightMatrices[_idx_], position,\n directionalLightShadowMapSizes[0],\n vec2(1.0 / float(SHADOW_CASCADE), 1.0),\n vec2(float(_idx_) / float(SHADOW_CASCADE), 0.0)\n );\n shadowContribs[0] = shadowContrib;\n }\n }}\n for(int _idx_ = DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#else\nvoid computeShadowOfDirectionalLights(vec3 position, inout float shadowContribs[DIRECTIONAL_LIGHT_COUNT]){\n float shadowContrib;\n for(int _idx_ = 0; _idx_ < DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n shadowContrib = computeShadowContrib(\n directionalLightShadowMaps[_idx_], directionalLightMatrices[_idx_], position,\n directionalLightShadowMapSizes[_idx_]\n );\n shadowContribs[_idx_] = shadowContrib;\n }}\n for(int _idx_ = DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#endif\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\nvoid computeShadowOfPointLights(vec3 position, inout float shadowContribs[POINT_LIGHT_COUNT] ){\n vec3 lightPosition;\n vec3 direction;\n for(int _idx_ = 0; _idx_ < POINT_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n lightPosition = pointLightPosition[_idx_];\n direction = position - lightPosition;\n shadowContribs[_idx_] = computeShadowContribOmni(pointLightShadowMaps[_idx_], direction, pointLightRange[_idx_]);\n }}\n for(int _idx_ = POINT_LIGHT_SHADOWMAP_COUNT; _idx_ < POINT_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#endif\n@end"; var targets$2 = ['px', 'nx', 'py', 'ny', 'pz', 'nz']; Shader['import'](shadowmapEssl); function getDepthMaterialUniform(renderable, depthMaterial, symbol) { if (symbol === 'alphaMap') { return renderable.material.get('diffuseMap'); } else if (symbol === 'alphaCutoff') { if (renderable.material.isDefined('fragment', 'ALPHA_TEST') && renderable.material.get('diffuseMap') ) { var alphaCutoff = renderable.material.get('alphaCutoff'); return alphaCutoff || 0; } return 0; } else { return depthMaterial.get(symbol); } } function isDepthMaterialChanged(renderable, prevRenderable) { var matA = renderable.material; var matB = prevRenderable.material; return matA.get('diffuseMap') !== matB.get('diffuseMap') || (matA.get('alphaCutoff') || 0) !== (matB.get('alphaCutoff') || 0); } /** * Pass rendering shadow map. * * @constructor clay.prePass.ShadowMap * @extends clay.core.Base * @example * var shadowMapPass = new clay.prePass.ShadowMap({ * softShadow: clay.prePass.ShadowMap.VSM * }); * ... * animation.on('frame', function (frameTime) { * shadowMapPass.render(renderer, scene, camera); * renderer.render(scene, camera); * }); */ var ShadowMapPass = Base.extend(function () { return /** @lends clay.prePass.ShadowMap# */ { /** * Soft shadow technique. * Can be {@link clay.prePass.ShadowMap.PCF} or {@link clay.prePass.ShadowMap.VSM} * @type {number} */ softShadow: ShadowMapPass.PCF, /** * Soft shadow blur size * @type {number} */ shadowBlur: 1.0, lightFrustumBias: 'auto', kernelPCF: new Float32Array([ 1, 0, 1, 1, -1, 1, 0, 1, -1, 0, -1, -1, 1, -1, 0, -1 ]), precision: 'highp', _lastRenderNotCastShadow: false, _frameBuffer: new FrameBuffer(), _textures: {}, _shadowMapNumber: { 'POINT_LIGHT': 0, 'DIRECTIONAL_LIGHT': 0, 'SPOT_LIGHT': 0 }, _depthMaterials: {}, _distanceMaterials: {}, _receivers: [], _lightsCastShadow: [], _lightCameras: {}, _lightMaterials: {}, _texturePool: new TexturePool() }; }, function () { // Gaussian filter pass for VSM this._gaussianPassH = new Pass({ fragment: Shader.source('clay.compositor.gaussian_blur') }); this._gaussianPassV = new Pass({ fragment: Shader.source('clay.compositor.gaussian_blur') }); this._gaussianPassH.setUniform('blurSize', this.shadowBlur); this._gaussianPassH.setUniform('blurDir', 0.0); this._gaussianPassV.setUniform('blurSize', this.shadowBlur); this._gaussianPassV.setUniform('blurDir', 1.0); this._outputDepthPass = new Pass({ fragment: Shader.source('clay.sm.debug_depth') }); }, { /** * Render scene to shadow textures * @param {clay.Renderer} renderer * @param {clay.Scene} scene * @param {clay.Camera} sceneCamera * @param {boolean} [notUpdateScene=false] * @memberOf clay.prePass.ShadowMap.prototype */ render: function (renderer, scene, sceneCamera, notUpdateScene) { if (!sceneCamera) { sceneCamera = scene.getMainCamera(); } this.trigger('beforerender', this, renderer, scene, sceneCamera); this._renderShadowPass(renderer, scene, sceneCamera, notUpdateScene); this.trigger('afterrender', this, renderer, scene, sceneCamera); }, /** * Debug rendering of shadow textures * @param {clay.Renderer} renderer * @param {number} size * @memberOf clay.prePass.ShadowMap.prototype */ renderDebug: function (renderer, size) { renderer.saveClear(); var viewport = renderer.viewport; var x = 0, y = 0; var width = size || viewport.width / 4; var height = width; if (this.softShadow === ShadowMapPass.VSM) { this._outputDepthPass.material.define('fragment', 'USE_VSM'); } else { this._outputDepthPass.material.undefine('fragment', 'USE_VSM'); } for (var name in this._textures) { var texture = this._textures[name]; renderer.setViewport(x, y, width * texture.width / texture.height, height); this._outputDepthPass.setUniform('depthMap', texture); this._outputDepthPass.render(renderer); x += width * texture.width / texture.height; } renderer.setViewport(viewport); renderer.restoreClear(); }, _updateReceivers: function (renderer, mesh) { if (mesh.receiveShadow) { this._receivers.push(mesh); mesh.material.set('shadowEnabled', 1); mesh.material.set('pcfKernel', this.kernelPCF); } else { mesh.material.set('shadowEnabled', 0); } if (this.softShadow === ShadowMapPass.VSM) { mesh.material.define('fragment', 'USE_VSM'); mesh.material.undefine('fragment', 'PCF_KERNEL_SIZE'); } else { mesh.material.undefine('fragment', 'USE_VSM'); var kernelPCF = this.kernelPCF; if (kernelPCF && kernelPCF.length) { mesh.material.define('fragment', 'PCF_KERNEL_SIZE', kernelPCF.length / 2); } else { mesh.material.undefine('fragment', 'PCF_KERNEL_SIZE'); } } }, _update: function (renderer, scene) { var self = this; scene.traverse(function (renderable) { if (renderable.isRenderable()) { self._updateReceivers(renderer, renderable); } }); for (var i = 0; i < scene.lights.length; i++) { var light = scene.lights[i]; if (light.castShadow && !light.invisible) { this._lightsCastShadow.push(light); } } }, _renderShadowPass: function (renderer, scene, sceneCamera, notUpdateScene) { // reset for (var name in this._shadowMapNumber) { this._shadowMapNumber[name] = 0; } this._lightsCastShadow.length = 0; this._receivers.length = 0; var _gl = renderer.gl; if (!notUpdateScene) { scene.update(); } if (sceneCamera) { sceneCamera.update(); } scene.updateLights(); this._update(renderer, scene); // Needs to update the receivers again if shadows come from 1 to 0. if (!this._lightsCastShadow.length && this._lastRenderNotCastShadow) { return; } this._lastRenderNotCastShadow = this._lightsCastShadow === 0; _gl.enable(_gl.DEPTH_TEST); _gl.depthMask(true); _gl.disable(_gl.BLEND); // Clear with high-z, so the part not rendered will not been shadowed // TODO // TODO restore _gl.clearColor(1.0, 1.0, 1.0, 1.0); // Shadow uniforms var spotLightShadowMaps = []; var spotLightMatrices = []; var directionalLightShadowMaps = []; var directionalLightMatrices = []; var shadowCascadeClips = []; var pointLightShadowMaps = []; var dirLightHasCascade; // Create textures for shadow map for (var i = 0; i < this._lightsCastShadow.length; i++) { var light = this._lightsCastShadow[i]; if (light.type === 'DIRECTIONAL_LIGHT') { if (dirLightHasCascade) { console.warn('Only one direectional light supported with shadow cascade'); continue; } if (light.shadowCascade > 4) { console.warn('Support at most 4 cascade'); continue; } if (light.shadowCascade > 1) { dirLightHasCascade = light; } this.renderDirectionalLightShadow( renderer, scene, sceneCamera, light, shadowCascadeClips, directionalLightMatrices, directionalLightShadowMaps ); } else if (light.type === 'SPOT_LIGHT') { this.renderSpotLightShadow( renderer, scene, light, spotLightMatrices, spotLightShadowMaps ); } else if (light.type === 'POINT_LIGHT') { this.renderPointLightShadow( renderer, scene, light, pointLightShadowMaps ); } this._shadowMapNumber[light.type]++; } for (var lightType in this._shadowMapNumber) { var number = this._shadowMapNumber[lightType]; var key = lightType + '_SHADOWMAP_COUNT'; for (var i = 0; i < this._receivers.length; i++) { var mesh = this._receivers[i]; var material = mesh.material; if (material.fragmentDefines[key] !== number) { if (number > 0) { material.define('fragment', key, number); } else if (material.isDefined('fragment', key)) { material.undefine('fragment', key); } } } } for (var i = 0; i < this._receivers.length; i++) { var mesh = this._receivers[i]; var material = mesh.material; if (dirLightHasCascade) { material.define('fragment', 'SHADOW_CASCADE', dirLightHasCascade.shadowCascade); } else { material.undefine('fragment', 'SHADOW_CASCADE'); } } var shadowUniforms = scene.shadowUniforms; function getSize(texture) { return texture.height; } if (directionalLightShadowMaps.length > 0) { var directionalLightShadowMapSizes = directionalLightShadowMaps.map(getSize); shadowUniforms.directionalLightShadowMaps = { value: directionalLightShadowMaps, type: 'tv' }; shadowUniforms.directionalLightMatrices = { value: directionalLightMatrices, type: 'm4v' }; shadowUniforms.directionalLightShadowMapSizes = { value: directionalLightShadowMapSizes, type: '1fv' }; if (dirLightHasCascade) { var shadowCascadeClipsNear = shadowCascadeClips.slice(); var shadowCascadeClipsFar = shadowCascadeClips.slice(); shadowCascadeClipsNear.pop(); shadowCascadeClipsFar.shift(); // Iterate from far to near shadowCascadeClipsNear.reverse(); shadowCascadeClipsFar.reverse(); // directionalLightShadowMaps.reverse(); directionalLightMatrices.reverse(); shadowUniforms.shadowCascadeClipsNear = { value: shadowCascadeClipsNear, type: '1fv' }; shadowUniforms.shadowCascadeClipsFar = { value: shadowCascadeClipsFar, type: '1fv' }; } } if (spotLightShadowMaps.length > 0) { var spotLightShadowMapSizes = spotLightShadowMaps.map(getSize); var shadowUniforms = scene.shadowUniforms; shadowUniforms.spotLightShadowMaps = { value: spotLightShadowMaps, type: 'tv' }; shadowUniforms.spotLightMatrices = { value: spotLightMatrices, type: 'm4v' }; shadowUniforms.spotLightShadowMapSizes = { value: spotLightShadowMapSizes, type: '1fv' }; } if (pointLightShadowMaps.length > 0) { shadowUniforms.pointLightShadowMaps = { value: pointLightShadowMaps, type: 'tv' }; } }, renderDirectionalLightShadow: (function () { var splitFrustum = new Frustum(); var splitProjMatrix = new Matrix4(); var cropBBox = new BoundingBox(); var cropMatrix = new Matrix4(); var lightViewMatrix = new Matrix4(); var lightViewProjMatrix = new Matrix4(); var lightProjMatrix = new Matrix4(); return function (renderer, scene, sceneCamera, light, shadowCascadeClips, directionalLightMatrices, directionalLightShadowMaps) { var defaultShadowMaterial = this._getDepthMaterial(light); var passConfig = { getMaterial: function (renderable) { return renderable.shadowDepthMaterial || defaultShadowMaterial; }, isMaterialChanged: isDepthMaterialChanged, getUniform: getDepthMaterialUniform, ifRender: function (renderable) { return renderable.castShadow; }, sortCompare: Renderer.opaqueSortCompare }; // First frame if (!scene.viewBoundingBoxLastFrame.isFinite()) { var boundingBox = scene.getBoundingBox(); scene.viewBoundingBoxLastFrame .copy(boundingBox).applyTransform(sceneCamera.viewMatrix); } // Considering moving speed since the bounding box is from last frame // TODO: add a bias var clippedFar = Math.min(-scene.viewBoundingBoxLastFrame.min.z, sceneCamera.far); var clippedNear = Math.max(-scene.viewBoundingBoxLastFrame.max.z, sceneCamera.near); var lightCamera = this._getDirectionalLightCamera(light, scene, sceneCamera); var lvpMat4Arr = lightViewProjMatrix.array; lightProjMatrix.copy(lightCamera.projectionMatrix); mat4.invert(lightViewMatrix.array, lightCamera.worldTransform.array); mat4.multiply(lightViewMatrix.array, lightViewMatrix.array, sceneCamera.worldTransform.array); mat4.multiply(lvpMat4Arr, lightProjMatrix.array, lightViewMatrix.array); var clipPlanes = []; var isPerspective = sceneCamera instanceof Perspective$1; var scaleZ = (sceneCamera.near + sceneCamera.far) / (sceneCamera.near - sceneCamera.far); var offsetZ = 2 * sceneCamera.near * sceneCamera.far / (sceneCamera.near - sceneCamera.far); for (var i = 0; i <= light.shadowCascade; i++) { var clog = clippedNear * Math.pow(clippedFar / clippedNear, i / light.shadowCascade); var cuni = clippedNear + (clippedFar - clippedNear) * i / light.shadowCascade; var c = clog * light.cascadeSplitLogFactor + cuni * (1 - light.cascadeSplitLogFactor); clipPlanes.push(c); shadowCascadeClips.push(-(-c * scaleZ + offsetZ) / -c); } var texture = this._getTexture(light, light.shadowCascade); directionalLightShadowMaps.push(texture); var viewport = renderer.viewport; var _gl = renderer.gl; this._frameBuffer.attach(texture); this._frameBuffer.bind(renderer); _gl.clear(_gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT); for (var i = 0; i < light.shadowCascade; i++) { // Get the splitted frustum var nearPlane = clipPlanes[i]; var farPlane = clipPlanes[i + 1]; if (isPerspective) { mat4.perspective(splitProjMatrix.array, sceneCamera.fov / 180 * Math.PI, sceneCamera.aspect, nearPlane, farPlane); } else { mat4.ortho( splitProjMatrix.array, sceneCamera.left, sceneCamera.right, sceneCamera.bottom, sceneCamera.top, nearPlane, farPlane ); } splitFrustum.setFromProjection(splitProjMatrix); splitFrustum.getTransformedBoundingBox(cropBBox, lightViewMatrix); cropBBox.applyProjection(lightProjMatrix); var _min = cropBBox.min.array; var _max = cropBBox.max.array; _min[0] = Math.max(_min[0], -1); _min[1] = Math.max(_min[1], -1); _max[0] = Math.min(_max[0], 1); _max[1] = Math.min(_max[1], 1); cropMatrix.ortho(_min[0], _max[0], _min[1], _max[1], 1, -1); lightCamera.projectionMatrix.multiplyLeft(cropMatrix); var shadowSize = light.shadowResolution || 512; // Reversed, left to right => far to near renderer.setViewport((light.shadowCascade - i - 1) * shadowSize, 0, shadowSize, shadowSize, 1); var renderList = scene.updateRenderList(lightCamera); renderer.renderPass(renderList.opaque, lightCamera, passConfig); // Filter for VSM if (this.softShadow === ShadowMapPass.VSM) { this._gaussianFilter(renderer, texture, texture.width); } var matrix = new Matrix4(); matrix.copy(lightCamera.viewMatrix) .multiplyLeft(lightCamera.projectionMatrix); directionalLightMatrices.push(matrix.array); lightCamera.projectionMatrix.copy(lightProjMatrix); } this._frameBuffer.unbind(renderer); renderer.setViewport(viewport); }; })(), renderSpotLightShadow: function (renderer, scene, light, spotLightMatrices, spotLightShadowMaps) { var texture = this._getTexture(light); var lightCamera = this._getSpotLightCamera(light); var _gl = renderer.gl; this._frameBuffer.attach(texture); this._frameBuffer.bind(renderer); _gl.clear(_gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT); var defaultShadowMaterial = this._getDepthMaterial(light); var passConfig = { getMaterial: function (renderable) { return renderable.shadowDepthMaterial || defaultShadowMaterial; }, isMaterialChanged: isDepthMaterialChanged, getUniform: getDepthMaterialUniform, ifRender: function (renderable) { return renderable.castShadow; }, sortCompare: Renderer.opaqueSortCompare }; var renderList = scene.updateRenderList(lightCamera); renderer.renderPass(renderList.opaque, lightCamera, passConfig); this._frameBuffer.unbind(renderer); // Filter for VSM if (this.softShadow === ShadowMapPass.VSM) { this._gaussianFilter(renderer, texture, texture.width); } var matrix = new Matrix4(); matrix.copy(lightCamera.worldTransform) .invert() .multiplyLeft(lightCamera.projectionMatrix); spotLightShadowMaps.push(texture); spotLightMatrices.push(matrix.array); }, renderPointLightShadow: function (renderer, scene, light, pointLightShadowMaps) { var texture = this._getTexture(light); var _gl = renderer.gl; pointLightShadowMaps.push(texture); var defaultShadowMaterial = this._getDepthMaterial(light); var passConfig = { getMaterial: function (renderable) { return renderable.shadowDepthMaterial || defaultShadowMaterial; }, getUniform: getDepthMaterialUniform, sortCompare: Renderer.opaqueSortCompare }; var renderListEachSide = { px: [], py: [], pz: [], nx: [], ny: [], nz: [] }; var bbox = new BoundingBox(); var lightWorldPosition = light.getWorldPosition().array; var lightBBox = new BoundingBox(); var range = light.range; lightBBox.min.setArray(lightWorldPosition); lightBBox.max.setArray(lightWorldPosition); var extent = new Vector3(range, range, range); lightBBox.max.add(extent); lightBBox.min.sub(extent); var targetsNeedRender = { px: false, py: false, pz: false, nx: false, ny: false, nz: false }; scene.traverse(function (renderable) { if (renderable.isRenderable() && renderable.castShadow) { var geometry = renderable.geometry; if (!geometry.boundingBox) { for (var i = 0; i < targets$2.length; i++) { renderListEachSide[targets$2[i]].push(renderable); } return; } bbox.transformFrom(geometry.boundingBox, renderable.worldTransform); if (!bbox.intersectBoundingBox(lightBBox)) { return; } bbox.updateVertices(); for (var i = 0; i < targets$2.length; i++) { targetsNeedRender[targets$2[i]] = false; } for (var i = 0; i < 8; i++) { var vtx = bbox.vertices[i]; var x = vtx[0] - lightWorldPosition[0]; var y = vtx[1] - lightWorldPosition[1]; var z = vtx[2] - lightWorldPosition[2]; var absx = Math.abs(x); var absy = Math.abs(y); var absz = Math.abs(z); if (absx > absy) { if (absx > absz) { targetsNeedRender[x > 0 ? 'px' : 'nx'] = true; } else { targetsNeedRender[z > 0 ? 'pz' : 'nz'] = true; } } else { if (absy > absz) { targetsNeedRender[y > 0 ? 'py' : 'ny'] = true; } else { targetsNeedRender[z > 0 ? 'pz' : 'nz'] = true; } } } for (var i = 0; i < targets$2.length; i++) { if (targetsNeedRender[targets$2[i]]) { renderListEachSide[targets$2[i]].push(renderable); } } } }); for (var i = 0; i < 6; i++) { var target = targets$2[i]; var camera = this._getPointLightCamera(light, target); this._frameBuffer.attach(texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i); this._frameBuffer.bind(renderer); _gl.clear(_gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT); renderer.renderPass(renderListEachSide[target], camera, passConfig); } this._frameBuffer.unbind(renderer); }, _getDepthMaterial: function (light) { var shadowMaterial = this._lightMaterials[light.__uid__]; var isPointLight = light.type === 'POINT_LIGHT'; if (!shadowMaterial) { var shaderPrefix = isPointLight ? 'clay.sm.distance.' : 'clay.sm.depth.'; shadowMaterial = new Material({ precision: this.precision, shader: new Shader(Shader.source(shaderPrefix + 'vertex'), Shader.source(shaderPrefix + 'fragment')) }); this._lightMaterials[light.__uid__] = shadowMaterial; } if (light.shadowSlopeScale != null) { shadowMaterial.setUniform('slopeScale', light.shadowSlopeScale); } if (light.shadowBias != null) { shadowMaterial.setUniform('bias', light.shadowBias); } if (this.softShadow === ShadowMapPass.VSM) { shadowMaterial.define('fragment', 'USE_VSM'); } else { shadowMaterial.undefine('fragment', 'USE_VSM'); } if (isPointLight) { shadowMaterial.set('lightPosition', light.getWorldPosition().array); shadowMaterial.set('range', light.range); } return shadowMaterial; }, _gaussianFilter: function (renderer, texture, size) { var parameter = { width: size, height: size, type: Texture.FLOAT }; var tmpTexture = this._texturePool.get(parameter); this._frameBuffer.attach(tmpTexture); this._frameBuffer.bind(renderer); this._gaussianPassH.setUniform('texture', texture); this._gaussianPassH.setUniform('textureWidth', size); this._gaussianPassH.render(renderer); this._frameBuffer.attach(texture); this._gaussianPassV.setUniform('texture', tmpTexture); this._gaussianPassV.setUniform('textureHeight', size); this._gaussianPassV.render(renderer); this._frameBuffer.unbind(renderer); this._texturePool.put(tmpTexture); }, _getTexture: function (light, cascade) { var key = light.__uid__; var texture = this._textures[key]; var resolution = light.shadowResolution || 512; cascade = cascade || 1; if (!texture) { if (light.type === 'POINT_LIGHT') { texture = new TextureCube(); } else { texture = new Texture2D(); } // At most 4 cascade // TODO share with height ? texture.width = resolution * cascade; texture.height = resolution; if (this.softShadow === ShadowMapPass.VSM) { texture.type = Texture.FLOAT; texture.anisotropic = 4; } else { texture.minFilter = glenum.NEAREST; texture.magFilter = glenum.NEAREST; texture.useMipmap = false; } this._textures[key] = texture; } return texture; }, _getPointLightCamera: function (light, target) { if (!this._lightCameras.point) { this._lightCameras.point = { px: new Perspective$1(), nx: new Perspective$1(), py: new Perspective$1(), ny: new Perspective$1(), pz: new Perspective$1(), nz: new Perspective$1() }; } var camera = this._lightCameras.point[target]; camera.far = light.range; camera.fov = 90; camera.position.set(0, 0, 0); switch (target) { case 'px': camera.lookAt(Vector3.POSITIVE_X, Vector3.NEGATIVE_Y); break; case 'nx': camera.lookAt(Vector3.NEGATIVE_X, Vector3.NEGATIVE_Y); break; case 'py': camera.lookAt(Vector3.POSITIVE_Y, Vector3.POSITIVE_Z); break; case 'ny': camera.lookAt(Vector3.NEGATIVE_Y, Vector3.NEGATIVE_Z); break; case 'pz': camera.lookAt(Vector3.POSITIVE_Z, Vector3.NEGATIVE_Y); break; case 'nz': camera.lookAt(Vector3.NEGATIVE_Z, Vector3.NEGATIVE_Y); break; } light.getWorldPosition(camera.position); camera.update(); return camera; }, _getDirectionalLightCamera: (function () { var lightViewMatrix = new Matrix4(); var sceneViewBoundingBox = new BoundingBox(); var lightViewBBox = new BoundingBox(); // Camera of directional light will be adjusted // to contain the view frustum and scene bounding box as tightly as possible return function (light, scene, sceneCamera) { if (!this._lightCameras.directional) { this._lightCameras.directional = new Orthographic$1(); } var camera = this._lightCameras.directional; sceneViewBoundingBox.copy(scene.viewBoundingBoxLastFrame); sceneViewBoundingBox.intersection(sceneCamera.frustum.boundingBox); // Move to the center of frustum(in world space) camera.position .copy(sceneViewBoundingBox.min) .add(sceneViewBoundingBox.max) .scale(0.5) .transformMat4(sceneCamera.worldTransform); camera.rotation.copy(light.rotation); camera.scale.copy(light.scale); camera.updateWorldTransform(); // Transform to light view space Matrix4.invert(lightViewMatrix, camera.worldTransform); Matrix4.multiply(lightViewMatrix, lightViewMatrix, sceneCamera.worldTransform); lightViewBBox.copy(sceneViewBoundingBox).applyTransform(lightViewMatrix); var min = lightViewBBox.min.array; var max = lightViewBBox.max.array; // Move camera to adjust the near to 0 camera.position.set((min[0] + max[0]) / 2, (min[1] + max[1]) / 2, max[2]) .transformMat4(camera.worldTransform); camera.near = 0; camera.far = -min[2] + max[2]; // Make sure receivers not in the frustum will stil receive the shadow. if (isNaN(this.lightFrustumBias)) { camera.far *= 4; } else { camera.far += this.lightFrustumBias; } camera.left = min[0]; camera.right = max[0]; camera.top = max[1]; camera.bottom = min[1]; camera.update(true); return camera; }; })(), _getSpotLightCamera: function (light) { if (!this._lightCameras.spot) { this._lightCameras.spot = new Perspective$1(); } var camera = this._lightCameras.spot; // Update properties camera.fov = light.penumbraAngle * 2; camera.far = light.range; camera.worldTransform.copy(light.worldTransform); camera.updateProjectionMatrix(); mat4.invert(camera.viewMatrix.array, camera.worldTransform.array); return camera; }, /** * @param {clay.Renderer|WebGLRenderingContext} [renderer] * @memberOf clay.prePass.ShadowMap.prototype */ // PENDING Renderer or WebGLRenderingContext dispose: function (renderer) { var _gl = renderer.gl || renderer; if (this._frameBuffer) { this._frameBuffer.dispose(_gl); } for (var name in this._textures) { this._textures[name].dispose(_gl); } this._texturePool.clear(renderer.gl); this._depthMaterials = {}; this._distanceMaterials = {}; this._textures = {}; this._lightCameras = {}; this._shadowMapNumber = { 'POINT_LIGHT': 0, 'DIRECTIONAL_LIGHT': 0, 'SPOT_LIGHT': 0 }; this._meshMaterials = {}; for (var i = 0; i < this._receivers.length; i++) { var mesh = this._receivers[i]; // Mesh may be disposed if (mesh.material) { var material = mesh.material; material.undefine('fragment', 'POINT_LIGHT_SHADOW_COUNT'); material.undefine('fragment', 'DIRECTIONAL_LIGHT_SHADOW_COUNT'); material.undefine('fragment', 'AMBIENT_LIGHT_SHADOW_COUNT'); material.set('shadowEnabled', 0); } } this._receivers = []; this._lightsCastShadow = []; } }); /** * @name clay.prePass.ShadowMap.VSM * @type {number} */ ShadowMapPass.VSM = 1; /** * @name clay.prePass.ShadowMap.PCF * @type {number} */ ShadowMapPass.PCF = 2; /** * @constructor clay.picking.RayPicking * @extends clay.core.Base */ var RayPicking = Base.extend(/** @lends clay.picking.RayPicking# */{ /** * Target scene * @type {clay.Scene} */ scene: null, /** * Target camera * @type {clay.Camera} */ camera: null, /** * Target renderer * @type {clay.Renderer} */ renderer: null }, function () { this._ray = new Ray(); this._ndc = new Vector2(); }, /** @lends clay.picking.RayPicking.prototype */ { /** * Pick the nearest intersection object in the scene * @param {number} x Mouse position x * @param {number} y Mouse position y * @param {boolean} [forcePickAll=false] ignore ignorePicking * @return {clay.picking.RayPicking~Intersection} */ pick: function (x, y, forcePickAll) { var out = this.pickAll(x, y, [], forcePickAll); return out[0] || null; }, /** * Pick all intersection objects, wich will be sorted from near to far * @param {number} x Mouse position x * @param {number} y Mouse position y * @param {Array} [output] * @param {boolean} [forcePickAll=false] ignore ignorePicking * @return {Array.} */ pickAll: function (x, y, output, forcePickAll) { this.renderer.screenToNDC(x, y, this._ndc); this.camera.castRay(this._ndc, this._ray); output = output || []; this._intersectNode(this.scene, output, forcePickAll || false); output.sort(this._intersectionCompareFunc); return output; }, _intersectNode: function (node, out, forcePickAll) { if ((node instanceof Renderable) && node.isRenderable()) { if ((!node.ignorePicking || forcePickAll) && ( // Only triangle mesh support ray picking (node.mode === glenum.TRIANGLES && node.geometry.isUseIndices()) // Or if geometry has it's own pickByRay, pick, implementation || node.geometry.pickByRay || node.geometry.pick ) ) { this._intersectRenderable(node, out); } } for (var i = 0; i < node._children.length; i++) { this._intersectNode(node._children[i], out, forcePickAll); } }, _intersectRenderable: (function () { var v1 = new Vector3(); var v2 = new Vector3(); var v3 = new Vector3(); var ray = new Ray(); var worldInverse = new Matrix4(); return function (renderable, out) { var isSkinnedMesh = renderable.isSkinnedMesh(); ray.copy(this._ray); Matrix4.invert(worldInverse, renderable.worldTransform); // Skinned mesh will ignore the world transform. if (!isSkinnedMesh) { ray.applyTransform(worldInverse); } var geometry = renderable.geometry; var bbox = isSkinnedMesh ? renderable.skeleton.boundingBox : geometry.boundingBox; if (bbox && !ray.intersectBoundingBox(bbox)) { return; } // Use user defined picking algorithm if (geometry.pick) { geometry.pick( this._ndc.x, this._ndc.y, this.renderer, this.camera, renderable, out ); return; } // Use user defined ray picking algorithm else if (geometry.pickByRay) { geometry.pickByRay(ray, renderable, out); return; } var cullBack = (renderable.cullFace === glenum.BACK && renderable.frontFace === glenum.CCW) || (renderable.cullFace === glenum.FRONT && renderable.frontFace === glenum.CW); var point; var indices = geometry.indices; var positionAttr = geometry.attributes.position; var weightAttr = geometry.attributes.weight; var jointAttr = geometry.attributes.joint; var skinMatricesArray; var skinMatrices = []; // Check if valid. if (!positionAttr || !positionAttr.value || !indices) { return; } if (isSkinnedMesh) { skinMatricesArray = renderable.skeleton.getSubSkinMatrices(renderable.__uid__, renderable.joints); for (var i = 0; i < renderable.joints.length; i++) { skinMatrices[i] = skinMatrices[i] || []; for (var k = 0; k < 16; k++) { skinMatrices[i][k] = skinMatricesArray[i * 16 + k]; } } var pos = []; var weight = []; var joint = []; var skinnedPos = []; var tmp = []; var skinnedPositionAttr = geometry.attributes.skinnedPosition; if (!skinnedPositionAttr || !skinnedPositionAttr.value) { geometry.createAttribute('skinnedPosition', 'f', 3); skinnedPositionAttr = geometry.attributes.skinnedPosition; skinnedPositionAttr.init(geometry.vertexCount); } for (var i = 0; i < geometry.vertexCount; i++) { positionAttr.get(i, pos); weightAttr.get(i, weight); jointAttr.get(i, joint); weight[3] = 1 - weight[0] - weight[1] - weight[2]; vec3.set(skinnedPos, 0, 0, 0); for (var k = 0; k < 4; k++) { if (joint[k] >= 0 && weight[k] > 1e-4) { vec3.transformMat4(tmp, pos, skinMatrices[joint[k]]); vec3.scaleAndAdd(skinnedPos, skinnedPos, tmp, weight[k]); } } skinnedPositionAttr.set(i, skinnedPos); } } for (var i = 0; i < indices.length; i += 3) { var i1 = indices[i]; var i2 = indices[i + 1]; var i3 = indices[i + 2]; var finalPosAttr = isSkinnedMesh ? geometry.attributes.skinnedPosition : positionAttr; finalPosAttr.get(i1, v1.array); finalPosAttr.get(i2, v2.array); finalPosAttr.get(i3, v3.array); if (cullBack) { point = ray.intersectTriangle(v1, v2, v3, renderable.culling); } else { point = ray.intersectTriangle(v1, v3, v2, renderable.culling); } if (point) { var pointW = new Vector3(); if (!isSkinnedMesh) { Vector3.transformMat4(pointW, point, renderable.worldTransform); } else { // TODO point maybe not right. Vector3.copy(pointW, point); } out.push(new RayPicking.Intersection( point, pointW, renderable, [i1, i2, i3], i / 3, Vector3.dist(pointW, this._ray.origin) )); } } }; })(), _intersectionCompareFunc: function (a, b) { return a.distance - b.distance; } }); /** * @constructor clay.picking.RayPicking~Intersection * @param {clay.Vector3} point * @param {clay.Vector3} pointWorld * @param {clay.Node} target * @param {Array.} triangle * @param {number} triangleIndex * @param {number} distance */ RayPicking.Intersection = function (point, pointWorld, target, triangle, triangleIndex, distance) { /** * Intersection point in local transform coordinates * @type {clay.Vector3} */ this.point = point; /** * Intersection point in world transform coordinates * @type {clay.Vector3} */ this.pointWorld = pointWorld; /** * Intersection scene node * @type {clay.Node} */ this.target = target; /** * Intersection triangle, which is an array of vertex index * @type {Array.} */ this.triangle = triangle; /** * Index of intersection triangle. */ this.triangleIndex = triangleIndex; /** * Distance from intersection point to ray origin * @type {number} */ this.distance = distance; }; // Spherical Harmonic Helpers var sh = {}; var targets$3 = ['px', 'nx', 'py', 'ny', 'pz', 'nz']; function harmonics(normal, index){ var x = normal[0]; var y = normal[1]; var z = normal[2]; if (index === 0) { return 1.0; } else if (index === 1) { return x; } else if (index === 2) { return y; } else if (index === 3) { return z; } else if (index === 4) { return x * z; } else if (index === 5) { return y * z; } else if (index === 6) { return x * y; } else if (index === 7) { return 3.0 * z * z - 1.0; } else { return x * x - y * y; } } var normalTransform = { px: [2, 1, 0, -1, -1, 1], nx: [2, 1, 0, 1, -1, -1], py: [0, 2, 1, 1, -1, -1], ny: [0, 2, 1, 1, 1, 1], pz: [0, 1, 2, -1, -1, -1], nz: [0, 1, 2, 1, -1, 1] }; // Project on cpu. function projectEnvironmentMapCPU(renderer, cubePixels, width, height) { var coeff = new vendor.Float32Array(9 * 3); var normal = vec3.create(); var texel = vec3.create(); var fetchNormal = vec3.create(); for (var m = 0; m < 9; m++) { var result = vec3.create(); for (var k = 0; k < targets$3.length; k++) { var pixels = cubePixels[targets$3[k]]; var sideResult = vec3.create(); var divider = 0; var i = 0; var transform = normalTransform[targets$3[k]]; for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { normal[0] = x / (width - 1.0) * 2.0 - 1.0; // TODO Flip y? normal[1] = y / (height - 1.0) * 2.0 - 1.0; normal[2] = -1.0; vec3.normalize(normal, normal); fetchNormal[0] = normal[transform[0]] * transform[3]; fetchNormal[1] = normal[transform[1]] * transform[4]; fetchNormal[2] = normal[transform[2]] * transform[5]; texel[0] = pixels[i++] / 255; texel[1] = pixels[i++] / 255; texel[2] = pixels[i++] / 255; // RGBM Decode var scale = pixels[i++] / 255 * 8.12; texel[0] *= scale; texel[1] *= scale; texel[2] *= scale; vec3.scaleAndAdd(sideResult, sideResult, texel, harmonics(fetchNormal, m) * -normal[2]); // -normal.z equals cos(theta) of Lambertian divider += -normal[2]; } } vec3.scaleAndAdd(result, result, sideResult, 1 / divider); } coeff[m * 3] = result[0] / 6.0; coeff[m * 3 + 1] = result[1] / 6.0; coeff[m * 3 + 2] = result[2] / 6.0; } return coeff; } /** * @param {clay.Renderer} renderer * @param {clay.Texture} envMap * @param {Object} [textureOpts] * @param {Object} [textureOpts.lod] * @param {boolean} [textureOpts.decodeRGBM] */ sh.projectEnvironmentMap = function (renderer, envMap, opts) { // TODO sRGB opts = opts || {}; opts.lod = opts.lod || 0; var skybox; var dummyScene = new Scene(); var size = 64; if (envMap.textureType === 'texture2D') { skybox = new Skybox$1({ scene: dummyScene, environmentMap: envMap }); } else { size = (envMap.image && envMap.image.px) ? envMap.image.px.width : envMap.width; skybox = new Skybox$1({ scene: dummyScene, environmentMap: envMap }); } // Convert to rgbm var width = Math.ceil(size / Math.pow(2, opts.lod)); var height = Math.ceil(size / Math.pow(2, opts.lod)); var rgbmTexture = new Texture2D({ width: width, height: height }); var framebuffer = new FrameBuffer(); skybox.material.define('fragment', 'RGBM_ENCODE'); if (opts.decodeRGBM) { skybox.material.define('fragment', 'RGBM_DECODE'); } skybox.material.set('lod', opts.lod); var envMapPass = new EnvironmentMapPass({ texture: rgbmTexture }); var cubePixels = {}; for (var i = 0; i < targets$3.length; i++) { cubePixels[targets$3[i]] = new Uint8Array(width * height * 4); var camera = envMapPass.getCamera(targets$3[i]); camera.fov = 90; framebuffer.attach(rgbmTexture); framebuffer.bind(renderer); renderer.render(dummyScene, camera); renderer.gl.readPixels( 0, 0, width, height, Texture.RGBA, Texture.UNSIGNED_BYTE, cubePixels[targets$3[i]] ); framebuffer.unbind(renderer); } skybox.dispose(renderer); framebuffer.dispose(renderer); rgbmTexture.dispose(renderer); return projectEnvironmentMapCPU(renderer, cubePixels, width, height); }; /** * Helpers for creating a common 3d application. * @namespace clay.application */ // TODO createCompositor // TODO Dispose test. geoCache test. // TODO Tonemapping exposure // TODO fitModel. // TODO Particle ? var parseColor = colorUtil.parseToFloat; var EVE_NAMES = ['click', 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'touchstart', 'touchend', 'touchmove', 'mousewheel', 'DOMMouseScroll' ]; /** * @typedef {string|HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} ImageLike */ /** * @typedef {string|HTMLCanvasElement|HTMLImageElement|HTMLVideoElement|clay.Texture2D} TextureLike */ /** * @typedef {string|Array.} Color */ /** * @typedef {HTMLElement|string} DomQuery */ /** * @typedef {Object} App3DNamespace * @property {Function} init Initialization callback that will be called when initing app. * You can return a promise in init to start the loop asynchronously when the promise is resolved. * @property {Function} loop Loop callback that will be called each frame. * @property {boolean} [autoRender=true] If render automatically each frame. * @property {Function} [beforeRender] * @property {Function} [afterRender] * @property {number} [width] Container width. * @property {number} [height] Container height. * @property {number} [devicePixelRatio] * @property {Object.} [methods] Methods that will be injected to App3D#methods. * @property {Object} [graphic] Graphic configuration including shadow, color space. * @property {boolean} [graphic.shadow=false] If enable shadow * @property {boolean} [graphic.linear=false] If use linear color space * @property {boolean} [graphic.tonemapping=false] If enable ACES tone mapping. * @property {boolean} [event=false] If enable mouse/touch event. It will slow down the system if geometries are complex. */ /** * @typedef {Object} StandardMaterialMRConfig * @property {string} [shader='standardMR'] * @property {Color} [color] * @property {number} [alpha] * @property {number} [metalness] * @property {number} [roughness] * @property {Color} [emission] * @property {number} [emissionIntensity] * @property {boolean} [transparent] * @property {TextureLike} [diffuseMap] * @property {TextureLike} [normalMap] * @property {TextureLike} [roughnessMap] * @property {TextureLike} [metalnessMap] * @property {TextureLike} [emissiveMap] */ /** * Using App3D is a much more convenient way to create and manage your 3D application. * * It provides the abilities to: * * + Manage application loop and rendering. * + Collect GPU resource automatically without memory leak concern. * + Mouse event management. * + Create scene objects, materials, textures with simpler code. * + Load models with one line of code. * + Promised interfaces. * * Here is a basic example to create a rotating cube. * ```js var app = clay.application.create('#viewport', { init: function (app) { // Create a perspective camera. // First parameter is the camera position. Which is in front of the cube. // Second parameter is the camera lookAt target. Which is the origin of the world, and where the cube puts. this._camera = app.createCamera([0, 2, 5], [0, 0, 0]); // Create a sample cube this._cube = app.createCube(); // Create a directional light. The direction is from top right to left bottom, away from camera. this._mainLight = app.createDirectionalLight([-1, -1, -1]); }, loop: function (app) { // Simply rotating the cube every frame. this._cube.rotation.rotateY(app.frameTime / 1000); } }); ``` * @constructor * @alias clay.application.App3D * @param {DomQuery} dom Container dom element or a selector string that can be used in `querySelector` * @param {App3DNamespace} appNS Options and namespace used in creating app3D */ function App3D(dom, appNS) { appNS = appNS || {}; appNS.graphic = appNS.graphic || {}; if (appNS.autoRender == null) { appNS.autoRender = true; } if (typeof dom === 'string') { dom = document.querySelector(dom); } if (!dom) { throw new Error('Invalid dom'); } var isDomCanvas = dom.nodeName.toUpperCase() === 'CANVAS'; var rendererOpts = {}; isDomCanvas && (rendererOpts.canvas = dom); appNS.devicePixelRatio && (rendererOpts.devicePixelRatio = appNS.devicePixelRatio); var gRenderer = new Renderer(rendererOpts); var gWidth = appNS.width || dom.clientWidth; var gHeight = appNS.height || dom.clientHeight; var gScene = new Scene(); var gTimeline = new Timeline(); var gShadowPass = appNS.graphic.shadow && new ShadowMapPass(); var gRayPicking = appNS.event && new RayPicking({ scene: gScene, renderer: gRenderer }); !isDomCanvas && dom.appendChild(gRenderer.canvas); gRenderer.resize(gWidth, gHeight); var gFrameTime = 0; var gElapsedTime = 0; gTimeline.start(); var userMethods = {}; for (var key in appNS.methods) { userMethods[key] = appNS.methods[key].bind(appNS, this); } Object.defineProperties(this, { /** * Container dom element * @name clay.application.App3D#container * @type {HTMLElement} */ container: { get: function () { return dom; } }, /** * @name clay.application.App3D#renderer * @type {clay.Renderer} */ renderer: { get: function () { return gRenderer; }}, /** * @name clay.application.App3D#scene * @type {clay.Renderer} */ scene: { get: function () { return gScene; }}, /** * @name clay.application.App3D#timeline * @type {clay.Renderer} */ timeline: { get: function () { return gTimeline; }}, /** * Time elapsed since last frame. Can be used in loop to calculate the movement. * @name clay.application.App3D#frameTime * @type {number} */ frameTime: { get: function () { return gFrameTime; }}, /** * Time elapsed since application created. * @name clay.application.App3D#elapsedTime * @type {number} */ elapsedTime: { get: function () { return gElapsedTime; }}, /** * Width of viewport. * @name clay.application.App3D#width * @type {number} */ width: { get: function () { return gRenderer.getWidth(); }}, /** * Height of viewport. * @name clay.application.App3D#height * @type {number} */ height: { get: function () { return gRenderer.getHeight(); }}, /** * Methods from {@link clay.application.create} * @name clay.application.App3D#methods * @type {number} */ methods: { get: function () { return userMethods; } }, _shadowPass: { get: function () { return gShadowPass; } }, _appNS: { get: function () { return appNS; } }, }); /** * Resize the application. Will use the container clientWidth/clientHeight if width/height in parameters are not given. * @function * @memberOf {clay.application.App3D} * @param {number} [width] * @param {number} [height] */ this.resize = function (width, height) { gWidth = width || appNS.width || dom.clientWidth; gHeight = height || dom.height || dom.clientHeight; gRenderer.resize(gWidth, gHeight); }; /** * Dispose the application * @function */ this.dispose = function () { this._disposed = true; if (appNS.dispose) { appNS.dispose(this); } gTimeline.stop(); gRenderer.disposeScene(gScene); gShadowPass && gShadowPass.dispose(gRenderer); dom.innerHTML = ''; EVE_NAMES.forEach(function (eveType) { this[makeHandlerName(eveType)] && vendor.removeEventListener(dom, makeHandlerName(eveType)); }, this); }; gRayPicking && this._initMouseEvents(gRayPicking); this._geoCache = new LRU$1(20); this._texCache = new LRU$1(20); // GPU Resources. this._texturesList = {}; this._geometriesList = {}; // Do init the application. var initPromise = Promise.resolve(appNS.init && appNS.init(this)); // Use the inited camera. gRayPicking && (gRayPicking.camera = gScene.getMainCamera()); if (!appNS.loop) { console.warn('Miss loop method.'); } var self = this; initPromise.then(function () { gTimeline.on('frame', function (frameTime) { gFrameTime = frameTime; gElapsedTime += frameTime; var camera = gScene.getMainCamera(); if (camera) { camera.aspect = gRenderer.getViewportAspect(); } gRayPicking && (gRayPicking.camera = camera); appNS.loop && appNS.loop(self); if (appNS.autoRender) { self.render(); } self.collectResources(); }, this); }); gScene.on('beforerender', function (renderer, scene, camera, renderList) { if (this._inRender) { // Only update graphic options when using #render function. this._updateGraphicOptions(appNS.graphic, renderList.opaque, false); this._updateGraphicOptions(appNS.graphic, renderList.transparent, false); } }, this); } function isImageLikeElement(val) { return (typeof Image !== 'undefined' && val instanceof Image) || (typeof HTMLCanvasElement !== 'undefined' && val instanceof HTMLCanvasElement) || (typeof HTMLVideoElement !== 'undefined' && val instanceof HTMLVideoElement); } function getKeyFromImageLike(val) { return typeof val === 'string' ? val : (val.__key__ || (val.__key__ = util$1.genGUID())); } function makeHandlerName(eveType) { return '_' + eveType + 'Handler'; } function packageEvent(eventType, pickResult, offsetX, offsetY, wheelDelta) { var event = util$1.clone(pickResult); event.type = eventType; event.offsetX = offsetX; event.offsetY = offsetY; if (wheelDelta !== null) { event.wheelDelta = wheelDelta; } return event; } function bubblingEvent(target, event) { while (target && !event.cancelBubble) { target.trigger(event.type, event); target = target.getParent(); } } App3D.prototype._initMouseEvents = function (rayPicking) { var dom = this.container; var oldTarget = null; EVE_NAMES.forEach(function (_eveType) { vendor.addEventListener(dom, _eveType, this[makeHandlerName(_eveType)] = function (e) { if (!rayPicking.camera) { // Not have camera yet. return; } e.preventDefault && e.preventDefault(); var box = dom.getBoundingClientRect(); var offsetX, offsetY; var eveType = _eveType; if (eveType.indexOf('touch') >= 0) { var touch = eveType !== 'touchend' ? e.targetTouches[0] : e.changedTouches[0]; if (eveType === 'touchstart') { eveType = 'mousedown'; } else if (eveType === 'touchend') { eveType = 'mouseup'; } else if (eveType === 'touchmove') { eveType = 'mousemove'; } offsetX = touch.clientX - box.left; offsetY = touch.clientY - box.top; } else { offsetX = e.clientX - box.left; offsetY = e.clientY - box.top; } var pickResult = rayPicking.pick(offsetX, offsetY); var delta; if (eveType === 'DOMMouseScroll' || eveType === 'mousewheel') { delta = (e.wheelDelta) ? e.wheelDelta / 120 : -(e.detail || 0) / 3; } if (pickResult) { // Just ignore silent element. if (pickResult.target.silent) { return; } if (eveType === 'mousemove') { // PENDING touchdown should trigger mouseover event ? var targetChanged = pickResult.target !== oldTarget; if (targetChanged) { oldTarget && bubblingEvent(oldTarget, packageEvent('mouseout', { target: oldTarget }, offsetX, offsetY)); } bubblingEvent(pickResult.target, packageEvent('mousemove', pickResult, offsetX, offsetY)); if (targetChanged) { bubblingEvent(pickResult.target, packageEvent('mouseover', pickResult, offsetX, offsetY)); } } else { bubblingEvent(pickResult.target, packageEvent(eveType, pickResult, offsetX, offsetY, delta)); } oldTarget = pickResult.target; } else if (oldTarget) { bubblingEvent(oldTarget, packageEvent('mouseout', { target: oldTarget }, offsetX, offsetY)); oldTarget = null; } }); }, this); }; App3D.prototype._updateGraphicOptions = function (graphicOpts, list, isSkybox) { var enableTonemapping = !!graphicOpts.tonemapping; var isLinearSpace = !!graphicOpts.linear; var prevMaterial; for (var i = 0; i < list.length; i++) { var mat = list[i].material; if (mat === prevMaterial) { continue; } enableTonemapping ? mat.define('fragment', 'TONEMAPPING') : mat.undefine('fragment', 'TONEMAPPING'); if (isLinearSpace) { var decodeSRGB = true; if (isSkybox && mat.get('environmentMap') && !mat.get('environmentMap').sRGB) { decodeSRGB = false; } decodeSRGB && mat.define('fragment', 'SRGB_DECODE'); mat.define('fragment', 'SRGB_ENCODE'); } else { mat.undefine('fragment', 'SRGB_DECODE'); mat.undefine('fragment', 'SRGB_ENCODE'); } prevMaterial = mat; } }; App3D.prototype._doRender = function (renderer, scene) { var camera = scene.getMainCamera(); renderer.render(scene, camera, true); }; /** * Do render */ App3D.prototype.render = function () { this._inRender = true; var appNS = this._appNS; appNS.beforeRender && appNS.beforeRender(self); var scene = this.scene; var renderer = this.renderer; var shadowPass = this._shadowPass; scene.update(); var skyboxList = []; scene.skybox && skyboxList.push(scene.skybox); scene.skydome && skyboxList.push(scene.skydome); this._updateGraphicOptions(appNS.graphic, skyboxList, true); // Render shadow pass shadowPass && shadowPass.render(renderer, scene, null, true); this._doRender(renderer, scene, true); appNS.afterRender && appNS.afterRender(self); this._inRender = false; }; App3D.prototype.collectResources = function () { var renderer = this.renderer; var scene = this.scene; var texturesList = this._texturesList; var geometriesList = this._geometriesList; // Mark all resources unused; markUnused(texturesList); markUnused(geometriesList); // Collect resources used in this frame. var newTexturesList = []; var newGeometriesList = []; collectResources(scene, newTexturesList, newGeometriesList); // Dispose those unsed resources. checkAndDispose(renderer, texturesList); checkAndDispose(renderer, geometriesList); this._texturesList = newTexturesList; this._geometriesList = newGeometriesList; }; function markUnused(resourceList) { for (var i = 0; i < resourceList.length; i++) { resourceList[i].__used = 0; } } function checkAndDispose(renderer, resourceList) { for (var i = 0; i < resourceList.length; i++) { if (!resourceList[i].__used) { resourceList[i].dispose(renderer); } } } function updateUsed(resource, list) { resource.__used = resource.__used || 0; resource.__used++; if (resource.__used === 1) { // Don't push to the list twice. list.push(resource); } } function collectResources(scene, textureResourceList, geometryResourceList) { var prevMaterial; var prevGeometry; scene.traverse(function (renderable) { if (renderable.isRenderable()) { var geometry = renderable.geometry; var material = renderable.material; // TODO optimize!! if (material !== prevMaterial) { var textureUniforms = material.getTextureUniforms(); for (var u = 0; u < textureUniforms.length; u++) { var uniformName = textureUniforms[u]; var val = material.uniforms[uniformName].value; var uniformType = material.uniforms[uniformName].type; if (!val) { continue; } if (uniformType === 't') { updateUsed(val, textureResourceList); } else if (uniformType === 'tv') { for (var k = 0; k < val.length; k++) { if (val[k]) { updateUsed(val[k], textureResourceList); } } } } } if (geometry !== prevGeometry) { updateUsed(geometry, geometryResourceList); } prevMaterial = material; prevGeometry = geometry; } }); for (var k = 0; k < scene.lights.length; k++) { // Track AmbientCubemap if (scene.lights[k].cubemap) { updateUsed(scene.lights[k].cubemap, textureResourceList); } } } /** * Load a texture from image or string. * @param {ImageLike} img * @param {Object} [opts] Texture options. * @param {boolean} [opts.flipY=true] If flipY. See {@link clay.Texture.flipY} * @param {boolean} [opts.convertToPOT=false] Force convert None Power of Two texture to Power of two so it can be tiled. * @param {number} [opts.anisotropic] Anisotropic filtering. See {@link clay.Texture.anisotropic} * @param {number} [opts.wrapS=clay.Texture.REPEAT] See {@link clay.Texture.wrapS} * @param {number} [opts.wrapT=clay.Texture.REPEAT] See {@link clay.Texture.wrapT} * @param {number} [opts.minFilter=clay.Texture.LINEAR_MIPMAP_LINEAR] See {@link clay.Texture.minFilter} * @param {number} [opts.magFilter=clay.Texture.LINEAR] See {@link clay.Texture.magFilter} * @param {number} [opts.exposure] Only be used when source is a HDR image. * @param {boolean} [useCache] If use cache. * @return {Promise} * @example * app.loadTexture('diffuseMap.jpg') * .then(function (texture) { * material.set('diffuseMap', texture); * }); */ App3D.prototype.loadTexture = function (urlOrImg, opts, useCache) { var self = this; var key = getKeyFromImageLike(urlOrImg); if (useCache) { if (this._texCache.get(key)) { return this._texCache.get(key); } } // TODO Promise ? var promise = new Promise(function (resolve, reject) { var texture = self.loadTextureSync(urlOrImg, opts); if (!texture.isRenderable()) { texture.success(function () { if (self._disposed) { return; } resolve(texture); }); texture.error(function () { if (self._disposed) { return; } reject(); }); } else { resolve(texture); } }); if (useCache) { this._texCache.put(key, promise); } return promise; }; /** * Create a texture from image or string synchronously. Texture can be use directly and don't have to wait for it's loaded. * @param {ImageLike} img * @param {Object} [opts] Texture options. * @param {boolean} [opts.flipY=true] If flipY. See {@link clay.Texture.flipY} * @param {boolean} [opts.convertToPOT=false] Force convert None Power of Two texture to Power of two so it can be tiled. * @param {number} [opts.anisotropic] Anisotropic filtering. See {@link clay.Texture.anisotropic} * @param {number} [opts.wrapS=clay.Texture.REPEAT] See {@link clay.Texture.wrapS} * @param {number} [opts.wrapT=clay.Texture.REPEAT] See {@link clay.Texture.wrapT} * @param {number} [opts.minFilter=clay.Texture.LINEAR_MIPMAP_LINEAR] See {@link clay.Texture.minFilter} * @param {number} [opts.magFilter=clay.Texture.LINEAR] See {@link clay.Texture.magFilter} * @param {number} [opts.exposure] Only be used when source is a HDR image. * @return {clay.Texture2D} * @example * var texture = app.loadTexture('diffuseMap.jpg', { * anisotropic: 8, * flipY: false * }); * material.set('diffuseMap', texture); */ App3D.prototype.loadTextureSync = function (urlOrImg, opts) { var texture = new Texture2D(opts); if (typeof urlOrImg === 'string') { if (urlOrImg.match(/.hdr$|^data:application\/octet-stream/)) { texture = textureUtil.loadTexture(urlOrImg, { exposure: opts && opts.exposure, fileType: 'hdr' }, function () { texture.dirty(); texture.trigger('success'); }); for (var key in opts) { texture[key] = opts[key]; } } else { texture.load(urlOrImg); } } else if (isImageLikeElement(urlOrImg)) { texture.image = urlOrImg; texture.dynamic = urlOrImg instanceof HTMLVideoElement; } return texture; }; /** * Create a texture from image or string synchronously. Texture can be use directly and don't have to wait for it's loaded. * @param {ImageLike} img * @param {Object} [opts] Texture options. * @param {boolean} [opts.flipY=false] If flipY. See {@link clay.Texture.flipY} * @return {Promise} * @example * app.loadTextureCube({ * px: 'skybox/px.jpg', py: 'skybox/py.jpg', pz: 'skybox/pz.jpg', * nx: 'skybox/nx.jpg', ny: 'skybox/ny.jpg', nz: 'skybox/nz.jpg' * }).then(function (texture) { * skybox.setEnvironmentMap(texture); * }) */ App3D.prototype.loadTextureCube = function (imgList, opts) { var textureCube = this.loadTextureCubeSync(imgList, opts); return new Promise(function (resolve, reject) { if (textureCube.isRenderable()) { resolve(textureCube); } else { textureCube.success(function () { resolve(textureCube); }).error(function () { reject(); }); } }); }; /** * Create a texture from image or string synchronously. Texture can be use directly and don't have to wait for it's loaded. * @param {ImageLike} img * @param {Object} [opts] Texture options. * @param {boolean} [opts.flipY=false] If flipY. See {@link clay.Texture.flipY} * @return {clay.TextureCube} * @example * var texture = app.loadTextureCubeSync({ * px: 'skybox/px.jpg', py: 'skybox/py.jpg', pz: 'skybox/pz.jpg', * nx: 'skybox/nx.jpg', ny: 'skybox/ny.jpg', nz: 'skybox/nz.jpg' * }); * skybox.setEnvironmentMap(texture); */ App3D.prototype.loadTextureCubeSync = function (imgList, opts) { opts = opts || {}; opts.flipY = opts.flipY || false; var textureCube = new TextureCube(opts); if (!imgList || !imgList.px || !imgList.nx || !imgList.py || !imgList.ny || !imgList.pz || !imgList.nz) { throw new Error('Invalid cubemap format. Should be an object including px,nx,py,ny,pz,nz'); } if (typeof imgList.px === 'string') { textureCube.load(imgList); } else { textureCube.image = util$1.clone(imgList); } return textureCube; }; /** * Create a material. * @param {Object|StandardMaterialMRConfig} materialConfig. materialConfig contains `shader`, `transparent` and uniforms that used in corresponding uniforms. * Uniforms can be `color`, `alpha` `diffuseMap` etc. * @param {string|clay.Shader} [shader='clay.standardMR'] Default to be standard shader with metalness and roughness workflow. * @param {boolean} [transparent=false] If material is transparent. * @param {boolean} [textureConvertToPOT=false] Force convert None Power of Two texture to Power of two so it can be tiled. * @param {boolean} [textureFlipY=true] If flip y of texture. * @param {Function} [textureLoaded] Callback when single texture loaded. * @param {Function} [texturesReady] Callback when all texture loaded. * @return {clay.Material} */ App3D.prototype.createMaterial = function (matConfig) { matConfig = matConfig || {}; matConfig.shader = matConfig.shader || 'clay.standardMR'; var shader = matConfig.shader instanceof Shader ? matConfig.shader : library.get(matConfig.shader); var material = new Material({ shader: shader }); var texturesLoading = []; function makeTextureSetter(key) { return function (texture) { material.setUniform(key, texture); matConfig.textureLoaded && matConfig.textureLoaded(key, texture); return texture; }; } for (var key in matConfig) { if (material.uniforms[key]) { var val = matConfig[key]; if ((material.uniforms[key].type === 't' || isImageLikeElement(val)) && !(val instanceof Texture) ) { // Try to load a texture. texturesLoading.push(this.loadTexture(val, { convertToPOT: matConfig.textureConvertToPOT || false, flipY: matConfig.textureFlipY == null ? true : matConfig.textureFlipY }).then(makeTextureSetter(key))); } else { material.setUniform(key, val); } } } if (matConfig.transparent) { matConfig.depthMask = false; matConfig.transparent = true; } if (matConfig.texturesReady) { Promise.all(texturesLoading).then(function (textures) { matConfig.texturesReady(textures); }); } return material; }; /** * Create a cube mesh and add it to the scene or the given parent node. * @function * @param {Object|clay.Material} [material] * @param {clay.Node} [parentNode] Parent node to append. Default to be scene. * @param {Array.|number} [subdivision=1] Subdivision of cube. * Can be a number to represent both width, height and depth dimensions. Or an array to represent them respectively. * @return {clay.Mesh} * @example * // Create a white cube. * app.createCube() */ App3D.prototype.createCube = function (material, parentNode, subdiv) { if (subdiv == null) { subdiv = 1; } if (typeof subdiv === 'number') { subdiv = [subdiv, subdiv, subdiv]; } var geoKey = 'cube-' + subdiv.join('-'); var cube = this._geoCache.get(geoKey); if (!cube) { cube = new Cube$1({ widthSegments: subdiv[0], heightSegments: subdiv[1], depthSegments: subdiv[2] }); cube.generateTangents(); this._geoCache.put(geoKey, cube); } return this.createMesh(cube, material, parentNode); }; /** * Create a cube mesh that camera is inside the cube. * @function * @param {Object|clay.Material} [material] * @param {clay.Node} [parentNode] Parent node to append. Default to be scene. * @param {Array.|number} [subdivision=1] Subdivision of cube. * Can be a number to represent both width, height and depth dimensions. Or an array to represent them respectively. * @return {clay.Mesh} * @example * // Create a white cube inside. * app.createCubeInside() */ App3D.prototype.createCubeInside = function (material, parentNode, subdiv) { if (subdiv == null) { subdiv = 1; } if (typeof subdiv === 'number') { subdiv = [subdiv, subdiv, subdiv]; } var geoKey = 'cubeInside-' + subdiv.join('-'); var cube = this._geoCache.get(geoKey); if (!cube) { cube = new Cube$1({ inside: true, widthSegments: subdiv[0], heightSegments: subdiv[1], depthSegments: subdiv[2] }); cube.generateTangents(); this._geoCache.put(geoKey, cube); } return this.createMesh(cube, material, parentNode); }; /** * Create a sphere mesh and add it to the scene or the given parent node. * @function * @param {Object|clay.Material} [material] * @param {clay.Node} [parentNode] Parent node to append. Default to be scene. * @param {number} [subdivision=20] Subdivision of sphere. * @return {clay.Mesh} * @example * // Create a semi-transparent sphere. * app.createSphere({ * color: [0, 0, 1], * transparent: true, * alpha: 0.5 * }) */ App3D.prototype.createSphere = function (material, parentNode, subdivision) { if (subdivision == null) { subdivision = 20; } var geoKey = 'sphere-' + subdivision; var sphere = this._geoCache.get(geoKey); if (!sphere) { sphere = new Sphere$1({ widthSegments: subdivision * 2, heightSegments: subdivision }); sphere.generateTangents(); this._geoCache.put(geoKey, sphere); } return this.createMesh(sphere, material, parentNode); }; /** * Create a plane mesh and add it to the scene or the given parent node. * @function * @param {Object|clay.Material} [material] * @param {clay.Node} [parentNode] Parent node to append. Default to be scene. * @param {Array.|number} [subdivision=1] Subdivision of plane. * Can be a number to represent both width and height dimensions. Or an array to represent them respectively. * @return {clay.Mesh} * @example * // Create a red color plane. * app.createPlane({ * color: [1, 0, 0] * }) */ App3D.prototype.createPlane = function (material, parentNode, subdiv) { if (subdiv == null) { subdiv = 1; } if (typeof subdiv === 'number') { subdiv = [subdiv, subdiv]; } var geoKey = 'plane-' + subdiv.join('-'); var planeGeo = this._geoCache.get(geoKey); if (!planeGeo) { planeGeo = new Plane$3({ widthSegments: subdiv[0], heightSegments: subdiv[1] }); planeGeo.generateTangents(); this._geoCache.put(geoKey, planeGeo); } return this.createMesh(planeGeo, material, parentNode); }; /** * Create mesh with parametric surface function * @param {Object|clay.Material} [material] * @param {clay.Node} [parentNode] Parent node to append. Default to be scene. * @param {Object} generator * @param {Function} generator.x * @param {Function} generator.y * @param {Function} generator.z * @param {Array} [generator.u=[0, 1, 0.05]] * @param {Array} [generator.v=[0, 1, 0.05]] * @return {clay.Mesh} */ App3D.prototype.createParametricSurface = function (material, parentNode, generator) { var geo = new ParametricSurface$1({ generator: generator }); geo.generateTangents(); return this.createMesh(geo, material, parentNode); }; /** * Create a general mesh with given geometry instance and material config. * @param {clay.Geometry} geometry * @return {clay.Mesh} */ App3D.prototype.createMesh = function (geometry, mat, parentNode) { var mesh = new Mesh({ geometry: geometry, material: mat instanceof Material ? mat : this.createMaterial(mat) }); parentNode = parentNode || this.scene; parentNode.add(mesh); return mesh; }; /** * Create an empty node * @param {clay.Node} parentNode * @return {clay.Node} */ App3D.prototype.createNode = function (parentNode) { var node = new Node(); parentNode = parentNode || this.scene; parentNode.add(node); return node; }; /** * Create a perspective or orthographic camera and add it to the scene. * @param {Array.|clay.Vector3} position * @param {Array.|clay.Vector3} target * @param {string} [type="perspective"] Can be 'perspective' or 'orthographic'(in short 'ortho') * @param {Array.|clay.Vector3} [extent] Extent is available only if type is orthographic. * @return {clay.camera.Perspective|clay.camera.Orthographic} */ App3D.prototype.createCamera = function (position, target, type, extent) { var CameraCtor; var isOrtho = false; if (type === 'ortho' || type === 'orthographic') { isOrtho = true; CameraCtor = Orthographic$1; } else { if (type && type !== 'perspective') { console.error('Unkown camera type ' + type + '. Use default perspective camera'); } CameraCtor = Perspective$1; } var camera = new CameraCtor(); if (position instanceof Vector3) { camera.position.copy(position); } else if (position instanceof Array) { camera.position.setArray(position); } if (target instanceof Array) { target = new Vector3(target[0], target[1], target[2]); } if (target instanceof Vector3) { camera.lookAt(target); } if (extent && isOrtho) { extent = extent.array || extent; camera.left = -extent[0] / 2; camera.right = extent[0] / 2; camera.top = extent[1] / 2; camera.bottom = -extent[1] / 2; camera.near = 0; camera.far = extent[2]; } else { camera.aspect = this.renderer.getViewportAspect(); } this.scene.add(camera); return camera; }; /** * Create a directional light and add it to the scene. * @param {Array.|clay.Vector3} dir A Vector3 or array to represent the direction. * @param {Color} [color='#fff'] Color of directional light, default to be white. * @param {number} [intensity] Intensity of directional light, default to be 1. * * @example * app.createDirectionalLight([-1, -1, -1], '#fff', 2); */ App3D.prototype.createDirectionalLight = function (dir, color, intensity) { var light = new DirectionalLight(); if (dir instanceof Vector3) { dir = dir.array; } light.position.setArray(dir).negate(); light.lookAt(Vector3.ZERO); if (typeof color === 'string') { color = parseColor(color); } color != null && (light.color = color); intensity != null && (light.intensity = intensity); this.scene.add(light); return light; }; /** * Create a spot light and add it to the scene. * @param {Array.|clay.Vector3} position Position of the spot light. * @param {Array.|clay.Vector3} [target] Target position where spot light points to. * @param {number} [range=20] Falloff range of spot light. Default to be 20. * @param {Color} [color='#fff'] Color of spot light, default to be white. * @param {number} [intensity=1] Intensity of spot light, default to be 1. * @param {number} [umbraAngle=30] Umbra angle of spot light. Default to be 30 degree from the middle line. * @param {number} [penumbraAngle=45] Penumbra angle of spot light. Default to be 45 degree from the middle line. * * @example * app.createSpotLight([5, 5, 5], [0, 0, 0], 20, #900); */ App3D.prototype.createSpotLight = function (position, target, range, color, intensity, umbraAngle, penumbraAngle) { var light = new SpotLight(); light.position.setArray(position instanceof Vector3 ? position.array : position); if (target instanceof Array) { target = new Vector3(target[0], target[1], target[2]); } if (target instanceof Vector3) { light.lookAt(target); } if (typeof color === 'string') { color = parseColor(color); } range != null && (light.range = range); color != null && (light.color = color); intensity != null && (light.intensity = intensity); umbraAngle != null && (light.umbraAngle = umbraAngle); penumbraAngle != null && (light.penumbraAngle = penumbraAngle); this.scene.add(light); return light; }; /** * Create a point light. * @param {Array.|clay.Vector3} position Position of point light.. * @param {number} [range=100] Falloff range of point light. * @param {Color} [color='#fff'] Color of point light. * @param {number} [intensity=1] Intensity of point light. */ App3D.prototype.createPointLight = function (position, range, color, intensity) { var light = new PointLight(); light.position.setArray(position instanceof Vector3 ? position.array : position); if (typeof color === 'string') { color = parseColor(color); } range != null && (light.range = range); color != null && (light.color = color); intensity != null && (light.intensity = intensity); this.scene.add(light); return light; }; /** * Create a ambient light. * @param {Color} [color='#fff'] Color of ambient light. * @param {number} [intensity=1] Intensity of ambient light. */ App3D.prototype.createAmbientLight = function (color, intensity) { var light = new AmbientLight(); if (typeof color === 'string') { color = parseColor(color); } color != null && (light.color = color); intensity != null && (light.intensity = intensity); this.scene.add(light); return light; }; /** * Create an cubemap ambient light and an spherical harmonic ambient light * for specular and diffuse lighting in PBR rendering * @param {ImageLike|TextureCube} [envImage] Panorama environment image, HDR format is better. Or a pre loaded texture cube * @param {number} [specularIntenstity=0.7] Intensity of specular light. * @param {number} [diffuseIntenstity=0.7] Intensity of diffuse light. * @param {number} [exposure=1] Exposure of HDR image. Only if image in first paramter is HDR. * @param {number} [prefilteredCubemapSize=32] The size of prefilerted cubemap. Larger value will take more time to do expensive prefiltering. * @return {Promise} */ App3D.prototype.createAmbientCubemapLight = function (envImage, specIntensity, diffIntensity, exposure, prefilteredCubemapSize) { var self = this; if (exposure == null) { exposure = 0; } if (prefilteredCubemapSize == null) { prefilteredCubemapSize = 32; } var scene = this.scene; var loadPromise; if (envImage.textureType === 'textureCube') { loadPromise = envImage.isRenderable() ? Promise.resolve(envImage) : new Promise(function (resolve, reject) { envImage.success(function () { resolve(envImage); }); }); } else { loadPromise = this.loadTexture(envImage, { exposure: exposure }); } return loadPromise.then(function (envTexture) { var specLight = new AmbientCubemapLight({ intensity: specIntensity != null ? specIntensity : 0.7 }); specLight.cubemap = envTexture; envTexture.flipY = false; // TODO Cache prefilter ? specLight.prefilter(self.renderer, 32); var diffLight = new AmbientSHLight({ intensity: diffIntensity != null ? diffIntensity : 0.7, coefficients: sh.projectEnvironmentMap( self.renderer, specLight.cubemap, { lod: 1 } ) }); scene.add(specLight); scene.add(diffLight); return { specular: specLight, diffuse: diffLight, // Original environment map environmentMap: envTexture }; }); }; /** * Load a [glTF](https://github.com/KhronosGroup/glTF) format model. * You can convert FBX/DAE/OBJ format models to [glTF](https://github.com/KhronosGroup/glTF) with [fbx2gltf](https://github.com/pissang/claygl#fbx-to-gltf20-converter) python script, * or simply using the [Clay Viewer](https://github.com/pissang/clay-viewer) client application. * @param {string} url * @param {Object} opts * @param {string|clay.Shader} [opts.shader='clay.standard'] 'basic'|'lambert'|'standard'. * @param {boolean} [opts.waitTextureLoaded=false] If add to scene util textures are all loaded. * @param {boolean} [opts.autoPlayAnimation=true] If autoplay the animation of model. * @param {boolean} [opts.upAxis='y'] Change model to y up if upAxis is 'z' * @param {boolean} [opts.textureFlipY=false] * @param {boolean} [opts.textureConvertToPOT=false] If convert texture to power-of-two * @param {string} [opts.textureRootPath] Root path of texture. Default to be relative with glTF file. * @param {clay.Node} [parentNode] Parent node that model will be mounted. Default to be scene * @return {Promise} */ App3D.prototype.loadModel = function (url, opts, parentNode) { if (typeof url !== 'string') { throw new Error('Invalid URL.'); } opts = opts || {}; if (opts.autoPlayAnimation == null) { opts.autoPlayAnimation = true; } var shader = opts.shader || 'clay.standard'; var loaderOpts = { rootNode: new Node(), shader: shader, textureRootPath: opts.textureRootPath, crossOrigin: 'Anonymous', textureFlipY: opts.textureFlipY, textureConvertToPOT: opts.textureConvertToPOT }; if (opts.upAxis && opts.upAxis.toLowerCase() === 'z') { loaderOpts.rootNode.rotation.identity().rotateX(-Math.PI / 2); } var loader = new GLTFLoader(loaderOpts); parentNode = parentNode || this.scene; var timeline = this.timeline; var self = this; return new Promise(function (resolve, reject) { function afterLoad(result) { if (self._disposed) { return; } parentNode.add(result.rootNode); if (opts.autoPlayAnimation) { result.clips.forEach(function (clip) { timeline.addClip(clip); }); } resolve(result); } loader.success(function (result) { if (self._disposed) { return; } if (!opts.waitTextureLoaded) { afterLoad(result); } else { Promise.all(result.textures.map(function (texture) { if (texture.isRenderable()) { return Promise.resolve(texture); } return new Promise(function (resolve) { texture.success(resolve); texture.error(resolve); }); })).then(function () { afterLoad(result); }).catch(function () { afterLoad(result); }); } }); loader.error(function () { reject(); }); loader.load(url); }); }; // TODO cloneModel /** * Similar to `app.scene.cloneNode`, except it will mount the cloned node to the scene automatically. * See more in {@link clay.Scene#cloneNode} * * @param {clay.Node} node * @param {clay.Node} [parentNode] Parent node that new cloned node will be mounted. * Default to have same parent with source node. * @return {clay.Node} */ App3D.prototype.cloneNode = function (node, parentNode) { parentNode = parentNode || node.getParent(); var newNode = this.scene.cloneNode(node, parentNode); if (parentNode) { parentNode.add(newNode); } return newNode; }; var application = { App3D: App3D, /** * Create a 3D application that will manage the app initialization and loop. * * See more details at {@link clay.application.App3D} * * @name clay.application.create * @method * @param {HTMLElement|string} dom Container dom element or a selector string that can be used in `querySelector` * @param {App3DNamespace} appNS Options and namespace used in creating app3D * * @return {clay.application.App3D} * * @example * clay.application.create('#app', { * init: function (app) { * app.createCube(); * var camera = app.createCamera(); * camera.position.set(0, 0, 2); * }, * loop: function () { // noop } * }) */ create: function (dom, appNS) { return new App3D(dom, appNS); } }; /** * @constructor * @alias clay.async.Task * @mixes clay.core.mixin.notifier */ function Task() { this._fullfilled = false; this._rejected = false; } /** * Task successed * @param {} data */ Task.prototype.resolve = function(data) { this._fullfilled = true; this._rejected = false; this.trigger('success', data); }; /** * Task failed * @param {} err */ Task.prototype.reject = function(err) { this._rejected = true; this._fullfilled = false; this.trigger('error', err); }; /** * If task successed * @return {boolean} */ Task.prototype.isFullfilled = function() { return this._fullfilled; }; /** * If task failed * @return {boolean} */ Task.prototype.isRejected = function() { return this._rejected; }; /** * If task finished, either successed or failed * @return {boolean} */ Task.prototype.isSettled = function() { return this._fullfilled || this._rejected; }; util$1.extend(Task.prototype, notifier); function makeRequestTask(url, responseType) { var task = new Task(); vendor.request.get({ url: url, responseType: responseType, onload: function(res) { task.resolve(res); }, onerror: function(error) { task.reject(error); } }); return task; } /** * Make a vendor.request task * @param {string|object|object[]|string[]} url * @param {string} [responseType] * @example * var task = Task.makeRequestTask('./a.json'); * var task = Task.makeRequestTask({ * url: 'b.bin', * responseType: 'arraybuffer' * }); * var tasks = Task.makeRequestTask(['./a.json', './b.json']); * var tasks = Task.makeRequestTask([ * {url: 'a.json'}, * {url: 'b.bin', responseType: 'arraybuffer'} * ]); * @return {clay.async.Task|clay.async.Task[]} */ Task.makeRequestTask = function(url, responseType) { if (typeof url === 'string') { return makeRequestTask(url, responseType); } else if (url.url) { // Configure object var obj = url; return makeRequestTask(obj.url, obj.responseType); } else if (Array.isArray(url)) { // Url list var urlList = url; var tasks = []; urlList.forEach(function(obj) { var url, responseType; if (typeof obj === 'string') { url = obj; } else if (Object(obj) === obj) { url = obj.url; responseType = obj.responseType; } tasks.push(makeRequestTask(url, responseType)); }); return tasks; } }; /** * @return {clay.async.Task} */ Task.makeTask = function() { return new Task(); }; util$1.extend(Task.prototype, notifier); /** * @constructor * @alias clay.async.TaskGroup * @extends clay.async.Task */ var TaskGroup = function () { Task.apply(this, arguments); this._tasks = []; this._fulfilledNumber = 0; this._rejectedNumber = 0; }; var Ctor = function (){}; Ctor.prototype = Task.prototype; TaskGroup.prototype = new Ctor(); TaskGroup.prototype.constructor = TaskGroup; /** * Wait for all given tasks successed, task can also be any notifier object which will trigger success and error events. Like {@link clay.Texture2D}, {@link clay.TextureCube}, {@link clay.loader.GLTF}. * @param {Array.} tasks * @chainable * @example * // Load texture list * var list = ['a.jpg', 'b.jpg', 'c.jpg'] * var textures = list.map(function (src) { * var texture = new clay.Texture2D(); * texture.load(src); * return texture; * }); * var taskGroup = new clay.async.TaskGroup(); * taskGroup.all(textures).success(function () { * // Do some thing after all textures loaded * }); */ TaskGroup.prototype.all = function (tasks) { var count = 0; var self = this; var data = []; this._tasks = tasks; this._fulfilledNumber = 0; this._rejectedNumber = 0; util$1.each(tasks, function (task, idx) { if (!task || !task.once) { return; } count++; task.once('success', function (res) { count--; self._fulfilledNumber++; // TODO // Some tasks like texture, loader are not inherited from task // We need to set the states here task._fulfilled = true; task._rejected = false; data[idx] = res; if (count === 0) { self.resolve(data); } }); task.once('error', function () { self._rejectedNumber ++; task._fulfilled = false; task._rejected = true; self.reject(task); }); }); if (count === 0) { setTimeout(function () { self.resolve(data); }); return this; } return this; }; /** * Wait for all given tasks finished, either successed or failed * @param {Array.} tasks * @return {clay.async.TaskGroup} */ TaskGroup.prototype.allSettled = function (tasks) { var count = 0; var self = this; var data = []; if (tasks.length === 0) { setTimeout(function () { self.trigger('success', data); }); return this; } this._tasks = tasks; util$1.each(tasks, function (task, idx) { if (!task || !task.once) { return; } count++; task.once('success', function (res) { count--; self._fulfilledNumber++; task._fulfilled = true; task._rejected = false; data[idx] = res; if (count === 0) { self.resolve(data); } }); task.once('error', function (err) { count--; self._rejectedNumber++; task._fulfilled = false; task._rejected = true; // TODO data[idx] = null; if (count === 0) { self.resolve(data); } }); }); return this; }; /** * Get successed sub tasks number, recursive can be true if sub task is also a TaskGroup. * @param {boolean} [recursive] * @return {number} */ TaskGroup.prototype.getFulfilledNumber = function (recursive) { if (recursive) { var nFulfilled = 0; for (var i = 0; i < this._tasks.length; i++) { var task = this._tasks[i]; if (task instanceof TaskGroup) { nFulfilled += task.getFulfilledNumber(recursive); } else if(task._fulfilled) { nFulfilled += 1; } } return nFulfilled; } else { return this._fulfilledNumber; } }; /** * Get failed sub tasks number, recursive can be true if sub task is also a TaskGroup. * @param {boolean} [recursive] * @return {number} */ TaskGroup.prototype.getRejectedNumber = function (recursive) { if (recursive) { var nRejected = 0; for (var i = 0; i < this._tasks.length; i++) { var task = this._tasks[i]; if (task instanceof TaskGroup) { nRejected += task.getRejectedNumber(recursive); } else if(task._rejected) { nRejected += 1; } } return nRejected; } else { return this._rejectedNumber; } }; /** * Get finished sub tasks number, recursive can be true if sub task is also a TaskGroup. * @param {boolean} [recursive] * @return {number} */ TaskGroup.prototype.getSettledNumber = function (recursive) { if (recursive) { var nSettled = 0; for (var i = 0; i < this._tasks.length; i++) { var task = this._tasks[i]; if (task instanceof TaskGroup) { nSettled += task.getSettledNumber(recursive); } else if(task._rejected || task._fulfilled) { nSettled += 1; } } return nSettled; } else { return this._fulfilledNumber + this._rejectedNumber; } }; /** * Get all sub tasks number, recursive can be true if sub task is also a TaskGroup. * @param {boolean} [recursive] * @return {number} */ TaskGroup.prototype.getTaskNumber = function (recursive) { if (recursive) { var nTask = 0; for (var i = 0; i < this._tasks.length; i++) { var task = this._tasks[i]; if (task instanceof TaskGroup) { nTask += task.getTaskNumber(recursive); } else { nTask += 1; } } return nTask; } else { return this._tasks.length; } }; // PENDING // Use topological sort ? /** * Node of graph based post processing. * * @constructor clay.compositor.CompositorNode * @extends clay.core.Base * */ var CompositorNode = Base.extend(function () { return /** @lends clay.compositor.CompositorNode# */ { /** * @type {string} */ name: '', /** * Input links, will be updated by the graph * @example: * inputName: { * node: someNode, * pin: 'xxxx' * } * @type {Object} */ inputLinks: {}, /** * Output links, will be updated by the graph * @example: * outputName: { * node: someNode, * pin: 'xxxx' * } * @type {Object} */ outputLinks: {}, // Save the output texture of previous frame // Will be used when there exist a circular reference _prevOutputTextures: {}, _outputTextures: {}, // Example: { name: 2 } _outputReferences: {}, _rendering: false, // If rendered in this frame _rendered: false, _compositor: null }; }, /** @lends clay.compositor.CompositorNode.prototype */ { // TODO Remove parameter function callback updateParameter: function (outputName, renderer) { var outputInfo = this.outputs[outputName]; var parameters = outputInfo.parameters; var parametersCopy = outputInfo._parametersCopy; if (!parametersCopy) { parametersCopy = outputInfo._parametersCopy = {}; } if (parameters) { for (var key in parameters) { if (key !== 'width' && key !== 'height') { parametersCopy[key] = parameters[key]; } } } var width, height; if (parameters.width instanceof Function) { width = parameters.width.call(this, renderer); } else { width = parameters.width; } if (parameters.height instanceof Function) { height = parameters.height.call(this, renderer); } else { height = parameters.height; } if ( parametersCopy.width !== width || parametersCopy.height !== height ) { if (this._outputTextures[outputName]) { this._outputTextures[outputName].dispose(renderer.gl); } } parametersCopy.width = width; parametersCopy.height = height; return parametersCopy; }, /** * Set parameter * @param {string} name * @param {} value */ setParameter: function (name, value) {}, /** * Get parameter value * @param {string} name * @return {} */ getParameter: function (name) {}, /** * Set parameters * @param {Object} obj */ setParameters: function (obj) { for (var name in obj) { this.setParameter(name, obj[name]); } }, render: function () {}, getOutput: function (renderer /*optional*/, name) { if (name == null) { // Return the output texture without rendering name = renderer; return this._outputTextures[name]; } var outputInfo = this.outputs[name]; if (!outputInfo) { return ; } // Already been rendered in this frame if (this._rendered) { // Force return texture in last frame if (outputInfo.outputLastFrame) { return this._prevOutputTextures[name]; } else { return this._outputTextures[name]; } } else if ( // TODO this._rendering // Solve Circular Reference ) { if (!this._prevOutputTextures[name]) { // Create a blank texture at first pass this._prevOutputTextures[name] = this._compositor.allocateTexture(outputInfo.parameters || {}); } return this._prevOutputTextures[name]; } this.render(renderer); return this._outputTextures[name]; }, removeReference: function (outputName) { this._outputReferences[outputName]--; if (this._outputReferences[outputName] === 0) { var outputInfo = this.outputs[outputName]; if (outputInfo.keepLastFrame) { if (this._prevOutputTextures[outputName]) { this._compositor.releaseTexture(this._prevOutputTextures[outputName]); } this._prevOutputTextures[outputName] = this._outputTextures[outputName]; } else { // Output of this node have alreay been used by all other nodes // Put the texture back to the pool. this._compositor.releaseTexture(this._outputTextures[outputName]); } } }, link: function (inputPinName, fromNode, fromPinName) { // The relationship from output pin to input pin is one-on-multiple this.inputLinks[inputPinName] = { node: fromNode, pin: fromPinName }; if (!fromNode.outputLinks[fromPinName]) { fromNode.outputLinks[fromPinName] = []; } fromNode.outputLinks[fromPinName].push({ node: this, pin: inputPinName }); // Enabled the pin texture in shader this.pass.material.enableTexture(inputPinName); }, clear: function () { this.inputLinks = {}; this.outputLinks = {}; }, updateReference: function (outputName) { if (!this._rendering) { this._rendering = true; for (var inputName in this.inputLinks) { var link = this.inputLinks[inputName]; link.node.updateReference(link.pin); } this._rendering = false; } if (outputName) { this._outputReferences[outputName] ++; } }, beforeFrame: function () { this._rendered = false; for (var name in this.outputLinks) { this._outputReferences[name] = 0; } }, afterFrame: function () { // Put back all the textures to pool for (var name in this.outputLinks) { if (this._outputReferences[name] > 0) { var outputInfo = this.outputs[name]; if (outputInfo.keepLastFrame) { if (this._prevOutputTextures[name]) { this._compositor.releaseTexture(this._prevOutputTextures[name]); } this._prevOutputTextures[name] = this._outputTextures[name]; } else { this._compositor.releaseTexture(this._outputTextures[name]); } } } } }); /** * @constructor clay.compositor.Graph * @extends clay.core.Base */ var Graph = Base.extend(function () { return /** @lends clay.compositor.Graph# */ { /** * @type {Array.} */ nodes: [] }; }, /** @lends clay.compositor.Graph.prototype */ { /** * Mark to update */ dirty: function () { this._dirty = true; }, /** * @param {clay.compositor.CompositorNode} node */ addNode: function (node) { if (this.nodes.indexOf(node) >= 0) { return; } this.nodes.push(node); this._dirty = true; }, /** * @param {clay.compositor.CompositorNode|string} node */ removeNode: function (node) { if (typeof node === 'string') { node = this.getNodeByName(node); } var idx = this.nodes.indexOf(node); if (idx >= 0) { this.nodes.splice(idx, 1); this._dirty = true; } }, /** * @param {string} name * @return {clay.compositor.CompositorNode} */ getNodeByName: function (name) { for (var i = 0; i < this.nodes.length; i++) { if (this.nodes[i].name === name) { return this.nodes[i]; } } }, /** * Update links of graph */ update: function () { for (var i = 0; i < this.nodes.length; i++) { this.nodes[i].clear(); } // Traverse all the nodes and build the graph for (var i = 0; i < this.nodes.length; i++) { var node = this.nodes[i]; if (!node.inputs) { continue; } for (var inputName in node.inputs) { if (!node.inputs[inputName]) { continue; } if (node.pass && !node.pass.material.isUniformEnabled(inputName)) { console.warn('Pin ' + node.name + '.' + inputName + ' not used.'); continue; } var fromPinInfo = node.inputs[inputName]; var fromPin = this.findPin(fromPinInfo); if (fromPin) { node.link(inputName, fromPin.node, fromPin.pin); } else { if (typeof fromPinInfo === 'string') { console.warn('Node ' + fromPinInfo + ' not exist'); } else { console.warn('Pin of ' + fromPinInfo.node + '.' + fromPinInfo.pin + ' not exist'); } } } } }, findPin: function (input) { var node; // Try to take input as a directly a node if (typeof input === 'string' || input instanceof CompositorNode) { input = { node: input }; } if (typeof input.node === 'string') { for (var i = 0; i < this.nodes.length; i++) { var tmp = this.nodes[i]; if (tmp.name === input.node) { node = tmp; } } } else { node = input.node; } if (node) { var inputPin = input.pin; if (!inputPin) { // Use first pin defaultly if (node.outputs) { inputPin = Object.keys(node.outputs)[0]; } } if (node.outputs[inputPin]) { return { node: node, pin: inputPin }; } } } }); /** * Compositor provide graph based post processing * * @constructor clay.compositor.Compositor * @extends clay.compositor.Graph * */ var Compositor = Graph.extend(function() { return { // Output node _outputs: [], _texturePool: new TexturePool(), _frameBuffer: new FrameBuffer({ depthBuffer: false }) }; }, /** @lends clay.compositor.Compositor.prototype */ { addNode: function(node) { Graph.prototype.addNode.call(this, node); node._compositor = this; }, /** * @param {clay.Renderer} renderer */ render: function(renderer, frameBuffer) { if (this._dirty) { this.update(); this._dirty = false; this._outputs.length = 0; for (var i = 0; i < this.nodes.length; i++) { if (!this.nodes[i].outputs) { this._outputs.push(this.nodes[i]); } } } for (var i = 0; i < this.nodes.length; i++) { // Update the reference number of each output texture this.nodes[i].beforeFrame(); } for (var i = 0; i < this._outputs.length; i++) { this._outputs[i].updateReference(); } for (var i = 0; i < this._outputs.length; i++) { this._outputs[i].render(renderer, frameBuffer); } for (var i = 0; i < this.nodes.length; i++) { // Clear up this.nodes[i].afterFrame(); } }, allocateTexture: function (parameters) { return this._texturePool.get(parameters); }, releaseTexture: function (parameters) { this._texturePool.put(parameters); }, getFrameBuffer: function () { return this._frameBuffer; }, /** * Dispose compositor * @param {clay.Renderer} renderer */ dispose: function (renderer) { this._texturePool.clear(renderer); } }); /** * @constructor clay.compositor.SceneNode * @extends clay.compositor.CompositorNode */ var SceneNode$1 = CompositorNode.extend( /** @lends clay.compositor.SceneNode# */ { name: 'scene', /** * @type {clay.Scene} */ scene: null, /** * @type {clay.Camera} */ camera: null, /** * @type {boolean} */ autoUpdateScene: true, /** * @type {boolean} */ preZ: false }, function() { this.frameBuffer = new FrameBuffer(); }, { render: function(renderer) { this._rendering = true; var _gl = renderer.gl; this.trigger('beforerender'); var renderInfo; if (!this.outputs) { renderInfo = renderer.render(this.scene, this.camera, !this.autoUpdateScene, this.preZ); } else { var frameBuffer = this.frameBuffer; for (var name in this.outputs) { var parameters = this.updateParameter(name, renderer); var outputInfo = this.outputs[name]; var texture = this._compositor.allocateTexture(parameters); this._outputTextures[name] = texture; var attachment = outputInfo.attachment || _gl.COLOR_ATTACHMENT0; if (typeof(attachment) == 'string') { attachment = _gl[attachment]; } frameBuffer.attach(texture, attachment); } frameBuffer.bind(renderer); // MRT Support in chrome // https://www.khronos.org/registry/webgl/sdk/tests/conformance/extensions/ext-draw-buffers.html var ext = renderer.getGLExtension('EXT_draw_buffers'); if (ext) { var bufs = []; for (var attachment in this.outputs) { attachment = parseInt(attachment); if (attachment >= _gl.COLOR_ATTACHMENT0 && attachment <= _gl.COLOR_ATTACHMENT0 + 8) { bufs.push(attachment); } } ext.drawBuffersEXT(bufs); } // Always clear // PENDING renderer.saveClear(); renderer.clearBit = glenum.DEPTH_BUFFER_BIT | glenum.COLOR_BUFFER_BIT; renderInfo = renderer.render(this.scene, this.camera, !this.autoUpdateScene, this.preZ); renderer.restoreClear(); frameBuffer.unbind(renderer); } this.trigger('afterrender', renderInfo); this._rendering = false; this._rendered = true; } }); /** * @constructor clay.compositor.TextureNode * @extends clay.compositor.CompositorNode */ var TextureNode$1 = CompositorNode.extend(function() { return /** @lends clay.compositor.TextureNode# */ { /** * @type {clay.Texture2D} */ texture: null, // Texture node must have output without parameters outputs: { color: {} } }; }, function () { }, { getOutput: function (renderer, name) { return this.texture; }, // Do nothing beforeFrame: function () {}, afterFrame: function () {} }); // TODO Shader library // TODO curlnoise demo wrong // PENDING // Use topological sort ? /** * Filter node * * @constructor clay.compositor.FilterNode * @extends clay.compositor.CompositorNode * * @example var node = new clay.compositor.FilterNode({ name: 'fxaa', shader: clay.Shader.source('clay.compositor.fxaa'), inputs: { texture: { node: 'scene', pin: 'color' } }, // Multiple outputs is preserved for MRT support in WebGL2.0 outputs: { color: { attachment: clay.FrameBuffer.COLOR_ATTACHMENT0 parameters: { format: clay.Texture.RGBA, width: 512, height: 512 }, // Node will keep the RTT rendered in last frame keepLastFrame: true, // Force the node output the RTT rendered in last frame outputLastFrame: true } } }); * */ var FilterNode$1 = CompositorNode.extend(function () { return /** @lends clay.compositor.FilterNode# */ { /** * @type {string} */ name: '', /** * @type {Object} */ inputs: {}, /** * @type {Object} */ outputs: null, /** * @type {string} */ shader: '', /** * Input links, will be updated by the graph * @example: * inputName: { * node: someNode, * pin: 'xxxx' * } * @type {Object} */ inputLinks: {}, /** * Output links, will be updated by the graph * @example: * outputName: { * node: someNode, * pin: 'xxxx' * } * @type {Object} */ outputLinks: {}, /** * @type {clay.compositor.Pass} */ pass: null, // Save the output texture of previous frame // Will be used when there exist a circular reference _prevOutputTextures: {}, _outputTextures: {}, // Example: { name: 2 } _outputReferences: {}, _rendering: false, // If rendered in this frame _rendered: false, _compositor: null }; }, function () { var pass = new Pass({ fragment: this.shader }); this.pass = pass; }, /** @lends clay.compositor.FilterNode.prototype */ { /** * @param {clay.Renderer} renderer */ render: function (renderer, frameBuffer) { this.trigger('beforerender', renderer); this._rendering = true; var _gl = renderer.gl; for (var inputName in this.inputLinks) { var link = this.inputLinks[inputName]; var inputTexture = link.node.getOutput(renderer, link.pin); this.pass.setUniform(inputName, inputTexture); } // Output if (!this.outputs) { this.pass.outputs = null; this._compositor.getFrameBuffer().unbind(renderer); this.pass.render(renderer, frameBuffer); } else { this.pass.outputs = {}; var attachedTextures = {}; for (var name in this.outputs) { var parameters = this.updateParameter(name, renderer); if (isNaN(parameters.width)) { this.updateParameter(name, renderer); } var outputInfo = this.outputs[name]; var texture = this._compositor.allocateTexture(parameters); this._outputTextures[name] = texture; var attachment = outputInfo.attachment || _gl.COLOR_ATTACHMENT0; if (typeof(attachment) === 'string') { attachment = _gl[attachment]; } attachedTextures[attachment] = texture; } this._compositor.getFrameBuffer().bind(renderer); for (var attachment in attachedTextures) { // FIXME attachment changes in different nodes this._compositor.getFrameBuffer().attach( attachedTextures[attachment], attachment ); } this.pass.render(renderer); // Because the data of texture is changed over time, // Here update the mipmaps of texture each time after rendered; this._compositor.getFrameBuffer().updateMipmap(renderer); } for (var inputName in this.inputLinks) { var link = this.inputLinks[inputName]; link.node.removeReference(link.pin); } this._rendering = false; this._rendered = true; this.trigger('afterrender', renderer); }, // TODO Remove parameter function callback updateParameter: function (outputName, renderer) { var outputInfo = this.outputs[outputName]; var parameters = outputInfo.parameters; var parametersCopy = outputInfo._parametersCopy; if (!parametersCopy) { parametersCopy = outputInfo._parametersCopy = {}; } if (parameters) { for (var key in parameters) { if (key !== 'width' && key !== 'height') { parametersCopy[key] = parameters[key]; } } } var width, height; if (typeof parameters.width === 'function') { width = parameters.width.call(this, renderer); } else { width = parameters.width; } if (typeof parameters.height === 'function') { height = parameters.height.call(this, renderer); } else { height = parameters.height; } width = Math.ceil(width); height = Math.ceil(height); if ( parametersCopy.width !== width || parametersCopy.height !== height ) { if (this._outputTextures[outputName]) { this._outputTextures[outputName].dispose(renderer); } } parametersCopy.width = width; parametersCopy.height = height; return parametersCopy; }, /** * Set parameter * @param {string} name * @param {} value */ setParameter: function (name, value) { this.pass.setUniform(name, value); }, /** * Get parameter value * @param {string} name * @return {} */ getParameter: function (name) { return this.pass.getUniform(name); }, /** * Set parameters * @param {Object} obj */ setParameters: function (obj) { for (var name in obj) { this.setParameter(name, obj[name]); } }, // /** // * Set shader code // * @param {string} shaderStr // */ // setShader: function (shaderStr) { // var material = this.pass.material; // material.shader.setFragment(shaderStr); // material.attachShader(material.shader, true); // }, /** * Proxy of pass.material.define('fragment', xxx); * @param {string} symbol * @param {number} [val] */ define: function (symbol, val) { this.pass.material.define('fragment', symbol, val); }, /** * Proxy of pass.material.undefine('fragment', xxx) * @param {string} symbol */ undefine: function (symbol) { this.pass.material.undefine('fragment', symbol); }, removeReference: function (outputName) { this._outputReferences[outputName]--; if (this._outputReferences[outputName] === 0) { var outputInfo = this.outputs[outputName]; if (outputInfo.keepLastFrame) { if (this._prevOutputTextures[outputName]) { this._compositor.releaseTexture(this._prevOutputTextures[outputName]); } this._prevOutputTextures[outputName] = this._outputTextures[outputName]; } else { // Output of this node have alreay been used by all other nodes // Put the texture back to the pool. this._compositor.releaseTexture(this._outputTextures[outputName]); } } }, clear: function () { CompositorNode.prototype.clear.call(this); // Default disable all texture this.pass.material.disableTexturesAll(); } }); var coloradjustEssl = "@export clay.compositor.coloradjust\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float brightness : 0.0;\nuniform float contrast : 1.0;\nuniform float exposure : 0.0;\nuniform float gamma : 1.0;\nuniform float saturation : 1.0;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = clamp(tex.rgb + vec3(brightness), 0.0, 1.0);\n color = clamp( (color-vec3(0.5))*contrast+vec3(0.5), 0.0, 1.0);\n color = clamp( color * pow(2.0, exposure), 0.0, 1.0);\n color = clamp( pow(color, vec3(gamma)), 0.0, 1.0);\n float luminance = dot( color, w );\n color = mix(vec3(luminance), color, saturation);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.brightness\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float brightness : 0.0;\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = tex.rgb + vec3(brightness);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.contrast\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float contrast : 1.0;\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = (tex.rgb-vec3(0.5))*contrast+vec3(0.5);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.exposure\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float exposure : 0.0;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = tex.rgb * pow(2.0, exposure);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.gamma\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float gamma : 1.0;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = pow(tex.rgb, vec3(gamma));\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.saturation\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float saturation : 1.0;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = tex.rgb;\n float luminance = dot(color, w);\n color = mix(vec3(luminance), color, saturation);\n gl_FragColor = vec4(color, tex.a);\n}\n@end"; var blurEssl = "@export clay.compositor.kernel.gaussian_9\nfloat gaussianKernel[9];\ngaussianKernel[0] = 0.07;\ngaussianKernel[1] = 0.09;\ngaussianKernel[2] = 0.12;\ngaussianKernel[3] = 0.14;\ngaussianKernel[4] = 0.16;\ngaussianKernel[5] = 0.14;\ngaussianKernel[6] = 0.12;\ngaussianKernel[7] = 0.09;\ngaussianKernel[8] = 0.07;\n@end\n@export clay.compositor.kernel.gaussian_13\nfloat gaussianKernel[13];\ngaussianKernel[0] = 0.02;\ngaussianKernel[1] = 0.03;\ngaussianKernel[2] = 0.06;\ngaussianKernel[3] = 0.08;\ngaussianKernel[4] = 0.11;\ngaussianKernel[5] = 0.13;\ngaussianKernel[6] = 0.14;\ngaussianKernel[7] = 0.13;\ngaussianKernel[8] = 0.11;\ngaussianKernel[9] = 0.08;\ngaussianKernel[10] = 0.06;\ngaussianKernel[11] = 0.03;\ngaussianKernel[12] = 0.02;\n@end\n@export clay.compositor.gaussian_blur\n#define SHADER_NAME gaussian_blur\nuniform sampler2D texture;varying vec2 v_Texcoord;\nuniform float blurSize : 2.0;\nuniform vec2 textureSize : [512.0, 512.0];\nuniform float blurDir : 0.0;\n@import clay.util.rgbm\n@import clay.util.clamp_sample\nvoid main (void)\n{\n @import clay.compositor.kernel.gaussian_9\n vec2 off = blurSize / textureSize;\n off *= vec2(1.0 - blurDir, blurDir);\n vec4 sum = vec4(0.0);\n float weightAll = 0.0;\n for (int i = 0; i < 9; i++) {\n float w = gaussianKernel[i];\n vec4 texel = decodeHDR(clampSample(texture, v_Texcoord + float(i - 4) * off));\n sum += texel * w;\n weightAll += w;\n }\n gl_FragColor = encodeHDR(sum / max(weightAll, 0.01));\n}\n@end\n"; var lumEssl = "@export clay.compositor.hdr.log_lum\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = decodeHDR(texture2D(texture, v_Texcoord));\n float luminance = dot(tex.rgb, w);\n luminance = log(luminance + 0.001);\n gl_FragColor = encodeHDR(vec4(vec3(luminance), 1.0));\n}\n@end\n@export clay.compositor.hdr.lum_adaption\nvarying vec2 v_Texcoord;\nuniform sampler2D adaptedLum;\nuniform sampler2D currentLum;\nuniform float frameTime : 0.02;\n@import clay.util.rgbm\nvoid main()\n{\n float fAdaptedLum = decodeHDR(texture2D(adaptedLum, vec2(0.5, 0.5))).r;\n float fCurrentLum = exp(encodeHDR(texture2D(currentLum, vec2(0.5, 0.5))).r);\n fAdaptedLum += (fCurrentLum - fAdaptedLum) * (1.0 - pow(0.98, 30.0 * frameTime));\n gl_FragColor = encodeHDR(vec4(vec3(fAdaptedLum), 1.0));\n}\n@end\n@export clay.compositor.lum\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord );\n float luminance = dot(tex.rgb, w);\n gl_FragColor = vec4(vec3(luminance), 1.0);\n}\n@end"; var lutEssl = "\n@export clay.compositor.lut\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform sampler2D lookup;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n float blueColor = tex.b * 63.0;\n vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.g);\n vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.g);\n vec4 newColor1 = texture2D(lookup, texPos1);\n vec4 newColor2 = texture2D(lookup, texPos2);\n vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n gl_FragColor = vec4(newColor.rgb, tex.w);\n}\n@end"; var vigentteEssl = "@export clay.compositor.vignette\n#define OUTPUT_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float darkness: 1;\nuniform float offset: 1;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 texel = decodeHDR(texture2D(texture, v_Texcoord));\n gl_FragColor.rgb = texel.rgb;\n vec2 uv = (v_Texcoord - vec2(0.5)) * vec2(offset);\n gl_FragColor = encodeHDR(vec4(mix(texel.rgb, vec3(1.0 - darkness), dot(uv, uv)), texel.a));\n}\n@end"; var outputEssl = "@export clay.compositor.output\n#define OUTPUT_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = decodeHDR(texture2D(texture, v_Texcoord));\n gl_FragColor.rgb = tex.rgb;\n#ifdef OUTPUT_ALPHA\n gl_FragColor.a = tex.a;\n#else\n gl_FragColor.a = 1.0;\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n#ifdef PREMULTIPLY_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif\n}\n@end"; var brightEssl = "@export clay.compositor.bright\nuniform sampler2D texture;\nuniform float threshold : 1;\nuniform float scale : 1.0;\nuniform vec2 textureSize: [512, 512];\nvarying vec2 v_Texcoord;\nconst vec3 lumWeight = vec3(0.2125, 0.7154, 0.0721);\n@import clay.util.rgbm\nvec4 median(vec4 a, vec4 b, vec4 c)\n{\n return a + b + c - min(min(a, b), c) - max(max(a, b), c);\n}\nvoid main()\n{\n vec4 texel = decodeHDR(texture2D(texture, v_Texcoord));\n#ifdef ANTI_FLICKER\n vec3 d = 1.0 / textureSize.xyx * vec3(1.0, 1.0, 0.0);\n vec4 s1 = decodeHDR(texture2D(texture, v_Texcoord - d.xz));\n vec4 s2 = decodeHDR(texture2D(texture, v_Texcoord + d.xz));\n vec4 s3 = decodeHDR(texture2D(texture, v_Texcoord - d.zy));\n vec4 s4 = decodeHDR(texture2D(texture, v_Texcoord + d.zy));\n texel = median(median(texel, s1, s2), s3, s4);\n#endif\n float lum = dot(texel.rgb , lumWeight);\n vec4 color;\n if (lum > threshold && texel.a > 0.0)\n {\n color = vec4(texel.rgb * scale, texel.a * scale);\n }\n else\n {\n color = vec4(0.0);\n }\n gl_FragColor = encodeHDR(color);\n}\n@end\n"; var downsampleEssl = "@export clay.compositor.downsample\nuniform sampler2D texture;\nuniform vec2 textureSize : [512, 512];\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nfloat brightness(vec3 c)\n{\n return max(max(c.r, c.g), c.b);\n}\n@import clay.util.clamp_sample\nvoid main()\n{\n vec4 d = vec4(-1.0, -1.0, 1.0, 1.0) / textureSize.xyxy;\n#ifdef ANTI_FLICKER\n vec3 s1 = decodeHDR(clampSample(texture, v_Texcoord + d.xy)).rgb;\n vec3 s2 = decodeHDR(clampSample(texture, v_Texcoord + d.zy)).rgb;\n vec3 s3 = decodeHDR(clampSample(texture, v_Texcoord + d.xw)).rgb;\n vec3 s4 = decodeHDR(clampSample(texture, v_Texcoord + d.zw)).rgb;\n float s1w = 1.0 / (brightness(s1) + 1.0);\n float s2w = 1.0 / (brightness(s2) + 1.0);\n float s3w = 1.0 / (brightness(s3) + 1.0);\n float s4w = 1.0 / (brightness(s4) + 1.0);\n float oneDivideSum = 1.0 / (s1w + s2w + s3w + s4w);\n vec4 color = vec4(\n (s1 * s1w + s2 * s2w + s3 * s3w + s4 * s4w) * oneDivideSum,\n 1.0\n );\n#else\n vec4 color = decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.xw));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.zw));\n color *= 0.25;\n#endif\n gl_FragColor = encodeHDR(color);\n}\n@end"; var upsampleEssl = "\n@export clay.compositor.upsample\n#define HIGH_QUALITY\nuniform sampler2D texture;\nuniform vec2 textureSize : [512, 512];\nuniform float sampleScale: 0.5;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\n@import clay.util.clamp_sample\nvoid main()\n{\n#ifdef HIGH_QUALITY\n vec4 d = vec4(1.0, 1.0, -1.0, 0.0) / textureSize.xyxy * sampleScale;\n vec4 s;\n s = decodeHDR(clampSample(texture, v_Texcoord - d.xy));\n s += decodeHDR(clampSample(texture, v_Texcoord - d.wy)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord - d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zw)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord )) * 4.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xw)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.wy)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n gl_FragColor = encodeHDR(s / 16.0);\n#else\n vec4 d = vec4(-1.0, -1.0, +1.0, +1.0) / textureSize.xyxy;\n vec4 s;\n s = decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xw));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zw));\n gl_FragColor = encodeHDR(s / 4.0);\n#endif\n}\n@end"; var hdrEssl = "@export clay.compositor.hdr.composite\n#define TONEMAPPING\nuniform sampler2D texture;\n#ifdef BLOOM_ENABLED\nuniform sampler2D bloom;\n#endif\n#ifdef LENSFLARE_ENABLED\nuniform sampler2D lensflare;\nuniform sampler2D lensdirt;\n#endif\n#ifdef LUM_ENABLED\nuniform sampler2D lum;\n#endif\n#ifdef LUT_ENABLED\nuniform sampler2D lut;\n#endif\n#ifdef COLOR_CORRECTION\nuniform float brightness : 0.0;\nuniform float contrast : 1.0;\nuniform float saturation : 1.0;\n#endif\n#ifdef VIGNETTE\nuniform float vignetteDarkness: 1.0;\nuniform float vignetteOffset: 1.0;\n#endif\nuniform float exposure : 1.0;\nuniform float bloomIntensity : 0.25;\nuniform float lensflareIntensity : 1;\nvarying vec2 v_Texcoord;\n@import clay.util.srgb\nvec3 ACESToneMapping(vec3 color)\n{\n const float A = 2.51;\n const float B = 0.03;\n const float C = 2.43;\n const float D = 0.59;\n const float E = 0.14;\n return (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nfloat eyeAdaption(float fLum)\n{\n return mix(0.2, fLum, 0.5);\n}\n#ifdef LUT_ENABLED\nvec3 lutTransform(vec3 color) {\n float blueColor = color.b * 63.0;\n vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);\n vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);\n vec4 newColor1 = texture2D(lut, texPos1);\n vec4 newColor2 = texture2D(lut, texPos2);\n vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n return newColor.rgb;\n}\n#endif\n@import clay.util.rgbm\nvoid main()\n{\n vec4 texel = vec4(0.0);\n vec4 originalTexel = vec4(0.0);\n#ifdef TEXTURE_ENABLED\n texel = decodeHDR(texture2D(texture, v_Texcoord));\n originalTexel = texel;\n#endif\n#ifdef BLOOM_ENABLED\n vec4 bloomTexel = decodeHDR(texture2D(bloom, v_Texcoord));\n texel.rgb += bloomTexel.rgb * bloomIntensity;\n texel.a += bloomTexel.a * bloomIntensity;\n#endif\n#ifdef LENSFLARE_ENABLED\n texel += decodeHDR(texture2D(lensflare, v_Texcoord)) * texture2D(lensdirt, v_Texcoord) * lensflareIntensity;\n#endif\n texel.a = min(texel.a, 1.0);\n#ifdef LUM_ENABLED\n float fLum = texture2D(lum, vec2(0.5, 0.5)).r;\n float adaptedLumDest = 3.0 / (max(0.1, 1.0 + 10.0*eyeAdaption(fLum)));\n float exposureBias = adaptedLumDest * exposure;\n#else\n float exposureBias = exposure;\n#endif\n#ifdef TONEMAPPING\n texel.rgb *= exposureBias;\n texel.rgb = ACESToneMapping(texel.rgb);\n#endif\n texel = linearTosRGB(texel);\n#ifdef LUT_ENABLED\n texel.rgb = lutTransform(clamp(texel.rgb,vec3(0.0),vec3(1.0)));\n#endif\n#ifdef COLOR_CORRECTION\n texel.rgb = clamp(texel.rgb + vec3(brightness), 0.0, 1.0);\n texel.rgb = clamp((texel.rgb - vec3(0.5))*contrast+vec3(0.5), 0.0, 1.0);\n float lum = dot(texel.rgb, vec3(0.2125, 0.7154, 0.0721));\n texel.rgb = mix(vec3(lum), texel.rgb, saturation);\n#endif\n#ifdef VIGNETTE\n vec2 uv = (v_Texcoord - vec2(0.5)) * vec2(vignetteOffset);\n texel.rgb = mix(texel.rgb, vec3(1.0 - vignetteDarkness), dot(uv, uv));\n#endif\n gl_FragColor = encodeHDR(texel);\n#ifdef DEBUG\n #if DEBUG == 1\n gl_FragColor = encodeHDR(decodeHDR(texture2D(texture, v_Texcoord)));\n #elif DEBUG == 2\n gl_FragColor = encodeHDR(decodeHDR(texture2D(bloom, v_Texcoord)) * bloomIntensity);\n #elif DEBUG == 3\n gl_FragColor = encodeHDR(decodeHDR(texture2D(lensflare, v_Texcoord) * lensflareIntensity));\n #endif\n#endif\n if (originalTexel.a <= 0.01 && gl_FragColor.a > 1e-5) {\n gl_FragColor.a = dot(gl_FragColor.rgb, vec3(0.2125, 0.7154, 0.0721));\n }\n#ifdef PREMULTIPLY_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif\n}\n@end"; var lensflareEssl = "@export clay.compositor.lensflare\n#define SAMPLE_NUMBER 8\nuniform sampler2D texture;\nuniform sampler2D lenscolor;\nuniform vec2 textureSize : [512, 512];\nuniform float dispersal : 0.3;\nuniform float haloWidth : 0.4;\nuniform float distortion : 1.0;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nvec4 textureDistorted(\n in vec2 texcoord,\n in vec2 direction,\n in vec3 distortion\n) {\n return vec4(\n decodeHDR(texture2D(texture, texcoord + direction * distortion.r)).r,\n decodeHDR(texture2D(texture, texcoord + direction * distortion.g)).g,\n decodeHDR(texture2D(texture, texcoord + direction * distortion.b)).b,\n 1.0\n );\n}\nvoid main()\n{\n vec2 texcoord = -v_Texcoord + vec2(1.0); vec2 textureOffset = 1.0 / textureSize;\n vec2 ghostVec = (vec2(0.5) - texcoord) * dispersal;\n vec2 haloVec = normalize(ghostVec) * haloWidth;\n vec3 distortion = vec3(-textureOffset.x * distortion, 0.0, textureOffset.x * distortion);\n vec4 result = vec4(0.0);\n for (int i = 0; i < SAMPLE_NUMBER; i++)\n {\n vec2 offset = fract(texcoord + ghostVec * float(i));\n float weight = length(vec2(0.5) - offset) / length(vec2(0.5));\n weight = pow(1.0 - weight, 10.0);\n result += textureDistorted(offset, normalize(ghostVec), distortion) * weight;\n }\n result *= texture2D(lenscolor, vec2(length(vec2(0.5) - texcoord)) / length(vec2(0.5)));\n float weight = length(vec2(0.5) - fract(texcoord + haloVec)) / length(vec2(0.5));\n weight = pow(1.0 - weight, 10.0);\n vec2 offset = fract(texcoord + haloVec);\n result += textureDistorted(offset, normalize(ghostVec), distortion) * weight;\n gl_FragColor = result;\n}\n@end"; var blendEssl = "@export clay.compositor.blend\n#define SHADER_NAME blend\n#ifdef TEXTURE1_ENABLED\nuniform sampler2D texture1;\nuniform float weight1 : 1.0;\n#endif\n#ifdef TEXTURE2_ENABLED\nuniform sampler2D texture2;\nuniform float weight2 : 1.0;\n#endif\n#ifdef TEXTURE3_ENABLED\nuniform sampler2D texture3;\nuniform float weight3 : 1.0;\n#endif\n#ifdef TEXTURE4_ENABLED\nuniform sampler2D texture4;\nuniform float weight4 : 1.0;\n#endif\n#ifdef TEXTURE5_ENABLED\nuniform sampler2D texture5;\nuniform float weight5 : 1.0;\n#endif\n#ifdef TEXTURE6_ENABLED\nuniform sampler2D texture6;\nuniform float weight6 : 1.0;\n#endif\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = vec4(0.0);\n#ifdef TEXTURE1_ENABLED\n tex += decodeHDR(texture2D(texture1, v_Texcoord)) * weight1;\n#endif\n#ifdef TEXTURE2_ENABLED\n tex += decodeHDR(texture2D(texture2, v_Texcoord)) * weight2;\n#endif\n#ifdef TEXTURE3_ENABLED\n tex += decodeHDR(texture2D(texture3, v_Texcoord)) * weight3;\n#endif\n#ifdef TEXTURE4_ENABLED\n tex += decodeHDR(texture2D(texture4, v_Texcoord)) * weight4;\n#endif\n#ifdef TEXTURE5_ENABLED\n tex += decodeHDR(texture2D(texture5, v_Texcoord)) * weight5;\n#endif\n#ifdef TEXTURE6_ENABLED\n tex += decodeHDR(texture2D(texture6, v_Texcoord)) * weight6;\n#endif\n gl_FragColor = encodeHDR(tex);\n}\n@end"; var fxaaEssl = "@export clay.compositor.fxaa\nuniform sampler2D texture;\nuniform vec4 viewport : VIEWPORT;\nvarying vec2 v_Texcoord;\n#define FXAA_REDUCE_MIN (1.0/128.0)\n#define FXAA_REDUCE_MUL (1.0/8.0)\n#define FXAA_SPAN_MAX 8.0\n@import clay.util.rgbm\nvoid main()\n{\n vec2 resolution = 1.0 / viewport.zw;\n vec3 rgbNW = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ) ).xyz;\n vec3 rgbNE = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ) ).xyz;\n vec3 rgbSW = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ) ).xyz;\n vec3 rgbSE = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ) ).xyz;\n vec4 rgbaM = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution ) );\n vec3 rgbM = rgbaM.xyz;\n float opacity = rgbaM.w;\n vec3 luma = vec3( 0.299, 0.587, 0.114 );\n float lumaNW = dot( rgbNW, luma );\n float lumaNE = dot( rgbNE, luma );\n float lumaSW = dot( rgbSW, luma );\n float lumaSE = dot( rgbSE, luma );\n float lumaM = dot( rgbM, luma );\n float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );\n float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );\n vec2 dir;\n dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\n dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\n float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );\n float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );\n dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),\n max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\n dir * rcpDirMin)) * resolution;\n vec3 rgbA = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * ( 1.0 / 3.0 - 0.5 ) ) ).xyz;\n rgbA += decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * ( 2.0 / 3.0 - 0.5 ) ) ).xyz;\n rgbA *= 0.5;\n vec3 rgbB = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * -0.5 ) ).xyz;\n rgbB += decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * 0.5 ) ).xyz;\n rgbB *= 0.25;\n rgbB += rgbA * 0.5;\n float lumaB = dot( rgbB, luma );\n if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) )\n {\n gl_FragColor = vec4( rgbA, opacity );\n }\n else {\n gl_FragColor = vec4( rgbB, opacity );\n }\n}\n@end"; // import fxaa3Essl from './source/compositor/fxaa3.glsl.js'; // TODO Must export a module and be used in the other modules. Or it will be tree shaked function register(Shader) { // Some build in shaders Shader['import'](coloradjustEssl); Shader['import'](blurEssl); Shader['import'](lumEssl); Shader['import'](lutEssl); Shader['import'](vigentteEssl); Shader['import'](outputEssl); Shader['import'](brightEssl); Shader['import'](downsampleEssl); Shader['import'](upsampleEssl); Shader['import'](hdrEssl); Shader['import'](lensflareEssl); Shader['import'](blendEssl); Shader['import'](fxaaEssl); } register(Shader); var shaderSourceReg = /^#source\((.*?)\)/; /** * @name clay.createCompositor * @function * @param {Object} json * @param {Object} [opts] * @return {clay.compositor.Compositor} */ function createCompositor(json, opts) { var compositor = new Compositor(); opts = opts || {}; var lib = { textures: {}, parameters: {} }; var afterLoad = function(shaderLib, textureLib) { for (var i = 0; i < json.nodes.length; i++) { var nodeInfo = json.nodes[i]; var node = createNode(nodeInfo, lib, opts); if (node) { compositor.addNode(node); } } }; for (var name in json.parameters) { var paramInfo = json.parameters[name]; lib.parameters[name] = convertParameter(paramInfo); } // TODO load texture asynchronous loadTextures(json, lib, opts, function(textureLib) { lib.textures = textureLib; afterLoad(); }); return compositor; } function createNode(nodeInfo, lib, opts) { var type = nodeInfo.type || 'filter'; var shaderSource; var inputs; var outputs; if (type === 'filter') { var shaderExp = nodeInfo.shader.trim(); var res = shaderSourceReg.exec(shaderExp); if (res) { shaderSource = Shader.source(res[1].trim()); } else if (shaderExp.charAt(0) === '#') { shaderSource = lib.shaders[shaderExp.substr(1)]; } if (!shaderSource) { shaderSource = shaderExp; } if (!shaderSource) { return; } } if (nodeInfo.inputs) { inputs = {}; for (var name in nodeInfo.inputs) { if (typeof nodeInfo.inputs[name] === 'string') { inputs[name] = nodeInfo.inputs[name]; } else { inputs[name] = { node: nodeInfo.inputs[name].node, pin: nodeInfo.inputs[name].pin }; } } } if (nodeInfo.outputs) { outputs = {}; for (var name in nodeInfo.outputs) { var outputInfo = nodeInfo.outputs[name]; outputs[name] = {}; if (outputInfo.attachment != null) { outputs[name].attachment = outputInfo.attachment; } if (outputInfo.keepLastFrame != null) { outputs[name].keepLastFrame = outputInfo.keepLastFrame; } if (outputInfo.outputLastFrame != null) { outputs[name].outputLastFrame = outputInfo.outputLastFrame; } if (outputInfo.parameters) { outputs[name].parameters = convertParameter(outputInfo.parameters); } } } var node; if (type === 'scene') { node = new SceneNode$1({ name: nodeInfo.name, scene: opts.scene, camera: opts.camera, outputs: outputs }); } else if (type === 'texture') { node = new TextureNode$1({ name: nodeInfo.name, outputs: outputs }); } // Default is filter else { node = new FilterNode$1({ name: nodeInfo.name, shader: shaderSource, inputs: inputs, outputs: outputs }); } if (node) { if (nodeInfo.parameters) { for (var name in nodeInfo.parameters) { var val = nodeInfo.parameters[name]; if (typeof val === 'string') { val = val.trim(); if (val.charAt(0) === '#') { val = lib.textures[val.substr(1)]; } else { node.on( 'beforerender', createSizeSetHandler( name, tryConvertExpr(val) ) ); } } else if (typeof val === 'function') { node.on('beforerender', val); } node.setParameter(name, val); } } if (nodeInfo.defines && node.pass) { for (var name in nodeInfo.defines) { var val = nodeInfo.defines[name]; node.pass.material.define('fragment', name, val); } } } return node; } function defaultWidthFunc(width, height) { return width; } function defaultHeightFunc(width, height) { return height; } function convertParameter(paramInfo) { var param = {}; if (!paramInfo) { return param; } ['type', 'minFilter', 'magFilter', 'wrapS', 'wrapT', 'flipY', 'useMipmap'] .forEach(function(name) { var val = paramInfo[name]; if (val != null) { // Convert string to enum if (typeof val === 'string') { val = Texture[val]; } param[name] = val; } }); var sizeScale = paramInfo.scale || 1; ['width', 'height'] .forEach(function(name) { if (paramInfo[name] != null) { var val = paramInfo[name]; if (typeof val === 'string') { val = val.trim(); param[name] = createSizeParser( name, tryConvertExpr(val), sizeScale ); } else { param[name] = val; } } }); if (!param.width) { param.width = defaultWidthFunc; } if (!param.height) { param.height = defaultHeightFunc; } if (paramInfo.useMipmap != null) { param.useMipmap = paramInfo.useMipmap; } return param; } function loadTextures(json, lib, opts, callback) { if (!json.textures) { callback({}); return; } var textures = {}; var loading = 0; var cbd = false; var textureRootPath = opts.textureRootPath; util$1.each(json.textures, function(textureInfo, name) { var texture; var path = textureInfo.path; var parameters = convertParameter(textureInfo.parameters); if (Array.isArray(path) && path.length === 6) { if (textureRootPath) { path = path.map(function(item) { return util$1.relative2absolute(item, textureRootPath); }); } texture = new TextureCube(parameters); } else if(typeof path === 'string') { if (textureRootPath) { path = util$1.relative2absolute(path, textureRootPath); } texture = new Texture2D(parameters); } else { return; } texture.load(path); loading++; texture.once('success', function() { textures[name] = texture; loading--; if (loading === 0) { callback(textures); cbd = true; } }); }); if (loading === 0 && !cbd) { callback(textures); } } function createSizeSetHandler(name, exprFunc) { return function (renderer) { // PENDING viewport size or window size var dpr = renderer.getDevicePixelRatio(); // PENDING If multiply dpr ? var width = renderer.getWidth(); var height = renderer.getHeight(); var result = exprFunc(width, height, dpr); this.setParameter(name, result); }; } function createSizeParser(name, exprFunc, scale) { scale = scale || 1; return function (renderer) { var dpr = renderer.getDevicePixelRatio(); var width = renderer.getWidth() * scale; var height = renderer.getHeight() * scale; return exprFunc(width, height, dpr); }; } function tryConvertExpr(string) { // PENDING var exprRes = /^expr\((.*)\)$/.exec(string); if (exprRes) { try { var func = new Function('width', 'height', 'dpr', 'return ' + exprRes[1]); // Try run t func(1, 1); return func; } catch (e) { throw new Error('Invalid expression.'); } } } // DEPRECATED var gbufferEssl = "@export clay.deferred.gbuffer.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\n#if defined(SECOND_PASS) || defined(FIRST_PASS)\nattribute vec2 texcoord : TEXCOORD_0;\nuniform vec2 uvRepeat;\nuniform vec2 uvOffset;\nvarying vec2 v_Texcoord;\n#endif\n#ifdef FIRST_PASS\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\nvarying vec3 v_Normal;\nattribute vec3 normal : NORMAL;\nattribute vec4 tangent : TANGENT;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\nvarying vec3 v_WorldPosition;\n#endif\n@import clay.chunk.skinning_header\n#ifdef THIRD_PASS\nuniform mat4 prevWorldViewProjection;\nvarying vec4 v_ViewPosition;\nvarying vec4 v_PrevViewPosition;\n#ifdef SKINNING\n#ifdef USE_SKIN_MATRICES_TEXTURE\nuniform sampler2D prevSkinMatricesTexture;\nmat4 getPrevSkinMatrix(float idx) {\n return getSkinMatrix(prevSkinMatricesTexture, idx);\n}\n#else\nuniform mat4 prevSkinMatrix[JOINT_COUNT];\nmat4 getPrevSkinMatrix(float idx) {\n return prevSkinMatrix[int(idx)];\n}\n#endif\n#endif\n#endif\nvoid main()\n{\n vec3 skinnedPosition = position;\n vec3 prevSkinnedPosition = position;\n#ifdef FIRST_PASS\n vec3 skinnedNormal = normal;\n vec3 skinnedTangent = tangent.xyz;\n bool hasTangent = dot(tangent, tangent) > 0.0;\n#endif\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n #ifdef FIRST_PASS\n skinnedNormal = (skinMatrixWS * vec4(normal, 0.0)).xyz;\n if (hasTangent) {\n skinnedTangent = (skinMatrixWS * vec4(tangent.xyz, 0.0)).xyz;\n }\n #endif\n #ifdef THIRD_PASS\n {\n mat4 prevSkinMatrixWS = getPrevSkinMatrix(joint.x) * weight.x;\n if (weight.y > 1e-4) { prevSkinMatrixWS += getPrevSkinMatrix(joint.y) * weight.y; }\n if (weight.z > 1e-4) { prevSkinMatrixWS += getPrevSkinMatrix(joint.z) * weight.z; }\n float weightW = 1.0-weight.x-weight.y-weight.z;\n if (weightW > 1e-4) { prevSkinMatrixWS += getPrevSkinMatrix(joint.w) * weightW; }\n prevSkinnedPosition = (prevSkinMatrixWS * vec4(position, 1.0)).xyz;\n }\n #endif\n#endif\n#if defined(SECOND_PASS) || defined(FIRST_PASS)\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n#endif\n#ifdef FIRST_PASS\n v_Normal = normalize((worldInverseTranspose * vec4(skinnedNormal, 0.0)).xyz);\n if (hasTangent) {\n v_Tangent = normalize((worldInverseTranspose * vec4(skinnedTangent, 0.0)).xyz);\n v_Bitangent = normalize(cross(v_Normal, v_Tangent) * tangent.w);\n }\n v_WorldPosition = (world * vec4(skinnedPosition, 1.0)).xyz;\n#endif\n#ifdef THIRD_PASS\n v_ViewPosition = worldViewProjection * vec4(skinnedPosition, 1.0);\n v_PrevViewPosition = prevWorldViewProjection * vec4(prevSkinnedPosition, 1.0);\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0);\n}\n@end\n@export clay.deferred.gbuffer1.fragment\nuniform mat4 viewInverse : VIEWINVERSE;\nuniform float glossiness;\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nuniform sampler2D normalMap;\nuniform sampler2D diffuseMap;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\nuniform sampler2D roughGlossMap;\nuniform bool useRoughGlossMap;\nuniform bool useRoughness;\nuniform bool doubleSided;\nuniform float alphaCutoff: 0.0;\nuniform float alpha: 1.0;\nuniform int roughGlossChannel: 0;\nfloat indexingTexel(in vec4 texel, in int idx) {\n if (idx == 3) return texel.a;\n else if (idx == 1) return texel.g;\n else if (idx == 2) return texel.b;\n else return texel.r;\n}\nvoid main()\n{\n vec3 N = v_Normal;\n if (doubleSided) {\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = eyePos - v_WorldPosition;\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n }\n if (alphaCutoff > 0.0) {\n float a = texture2D(diffuseMap, v_Texcoord).a * alpha;\n if (a < alphaCutoff) {\n discard;\n }\n }\n if (dot(v_Tangent, v_Tangent) > 0.0) {\n vec3 normalTexel = texture2D(normalMap, v_Texcoord).xyz;\n if (dot(normalTexel, normalTexel) > 0.0) { N = normalTexel * 2.0 - 1.0;\n mat3 tbn = mat3(v_Tangent, v_Bitangent, v_Normal);\n N = normalize(tbn * N);\n }\n }\n gl_FragColor.rgb = (N + 1.0) * 0.5;\n float g = glossiness;\n if (useRoughGlossMap) {\n float g2 = indexingTexel(texture2D(roughGlossMap, v_Texcoord), roughGlossChannel);\n if (useRoughness) {\n g2 = 1.0 - g2;\n }\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n }\n gl_FragColor.a = g + 0.005;\n}\n@end\n@export clay.deferred.gbuffer2.fragment\nuniform sampler2D diffuseMap;\nuniform sampler2D metalnessMap;\nuniform vec3 color;\nuniform float metalness;\nuniform bool useMetalnessMap;\nuniform bool linear;\nuniform float alphaCutoff: 0.0;\nuniform float alpha: 1.0;\nvarying vec2 v_Texcoord;\n@import clay.util.srgb\nvoid main()\n{\n float m = metalness;\n if (useMetalnessMap) {\n vec4 metalnessTexel = texture2D(metalnessMap, v_Texcoord);\n m = clamp(metalnessTexel.r + (m * 2.0 - 1.0), 0.0, 1.0);\n }\n vec4 texel = texture2D(diffuseMap, v_Texcoord);\n if (linear) {\n texel = sRGBToLinear(texel);\n }\n if (alphaCutoff > 0.0) {\n float a = texel.a * alpha;\n if (a < alphaCutoff) {\n discard;\n }\n }\n gl_FragColor.rgb = texel.rgb * color;\n gl_FragColor.a = m + 0.005;\n}\n@end\n@export clay.deferred.gbuffer3.fragment\nuniform bool firstRender;\nvarying vec4 v_ViewPosition;\nvarying vec4 v_PrevViewPosition;\nvoid main()\n{\n vec2 a = v_ViewPosition.xy / v_ViewPosition.w;\n vec2 b = v_PrevViewPosition.xy / v_PrevViewPosition.w;\n if (firstRender) {\n gl_FragColor = vec4(0.0);\n }\n else {\n gl_FragColor = vec4((a - b) * 0.5 + 0.5, 0.0, 1.0);\n }\n}\n@end\n@export clay.deferred.gbuffer.debug\n@import clay.deferred.chunk.light_head\nuniform sampler2D gBufferTexture4;\nuniform int debug: 0;\nvoid main ()\n{\n @import clay.deferred.chunk.gbuffer_read\n if (debug == 0) {\n gl_FragColor = vec4(N, 1.0);\n }\n else if (debug == 1) {\n gl_FragColor = vec4(vec3(z), 1.0);\n }\n else if (debug == 2) {\n gl_FragColor = vec4(position, 1.0);\n }\n else if (debug == 3) {\n gl_FragColor = vec4(vec3(glossiness), 1.0);\n }\n else if (debug == 4) {\n gl_FragColor = vec4(vec3(metalness), 1.0);\n }\n else if (debug == 5) {\n gl_FragColor = vec4(albedo, 1.0);\n }\n else {\n vec4 color = texture2D(gBufferTexture4, uv);\n color.rg -= 0.5;\n color.rg *= 2.0;\n gl_FragColor = color;\n }\n}\n@end"; var chunkEssl = "@export clay.deferred.chunk.light_head\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture2;\nuniform sampler2D gBufferTexture3;\nuniform vec2 windowSize: WINDOW_SIZE;\nuniform vec4 viewport: VIEWPORT;\nuniform mat4 viewProjectionInv;\n#ifdef DEPTH_ENCODED\n@import clay.util.decode_float\n#endif\n@end\n@export clay.deferred.chunk.gbuffer_read\n vec2 uv = gl_FragCoord.xy / windowSize;\n vec2 uv2 = (gl_FragCoord.xy - viewport.xy) / viewport.zw;\n vec4 texel1 = texture2D(gBufferTexture1, uv);\n vec4 texel3 = texture2D(gBufferTexture3, uv);\n if (dot(texel1.rgb, vec3(1.0)) == 0.0) {\n discard;\n }\n float glossiness = texel1.a;\n float metalness = texel3.a;\n vec3 N = texel1.rgb * 2.0 - 1.0;\n float z = texture2D(gBufferTexture2, uv).r * 2.0 - 1.0;\n vec2 xy = uv2 * 2.0 - 1.0;\n vec4 projectedPos = vec4(xy, z, 1.0);\n vec4 p4 = viewProjectionInv * projectedPos;\n vec3 position = p4.xyz / p4.w;\n vec3 albedo = texel3.rgb;\n vec3 diffuseColor = albedo * (1.0 - metalness);\n vec3 specularColor = mix(vec3(0.04), albedo, metalness);\n@end\n@export clay.deferred.chunk.light_equation\nfloat D_Phong(in float g, in float ndh) {\n float a = pow(8192.0, g);\n return (a + 2.0) / 8.0 * pow(ndh, a);\n}\nfloat D_GGX(in float g, in float ndh) {\n float r = 1.0 - g;\n float a = r * r;\n float tmp = ndh * ndh * (a - 1.0) + 1.0;\n return a / (3.1415926 * tmp * tmp);\n}\nvec3 F_Schlick(in float ndv, vec3 spec) {\n return spec + (1.0 - spec) * pow(1.0 - ndv, 5.0);\n}\nvec3 lightEquation(\n in vec3 lightColor, in vec3 diffuseColor, in vec3 specularColor,\n in float ndl, in float ndh, in float ndv, in float g\n)\n{\n return ndl * lightColor\n * (diffuseColor + D_Phong(g, ndh) * F_Schlick(ndv, specularColor));\n}\n@end"; Shader.import(gbufferEssl); Shader.import(chunkEssl); function createFillCanvas(color) { var canvas = document.createElement('canvas'); canvas.width = canvas.height = 1; var ctx = canvas.getContext('2d'); ctx.fillStyle = color || '#000'; ctx.fillRect(0, 0, 1, 1); return canvas; } // TODO specularColor // TODO Performance improvement function getGetUniformHook1(defaultNormalMap, defaultRoughnessMap, defaultDiffuseMap) { return function (renderable, gBufferMat, symbol) { var standardMaterial = renderable.material; if (symbol === 'doubleSided') { return standardMaterial.isDefined('fragment', 'DOUBLE_SIDED'); } else if (symbol === 'uvRepeat' || symbol === 'uvOffset' || symbol === 'alpha') { return standardMaterial.get(symbol); } else if (symbol === 'normalMap') { return standardMaterial.get(symbol) || defaultNormalMap; } else if (symbol === 'diffuseMap') { return standardMaterial.get(symbol) || defaultDiffuseMap; } else if (symbol === 'alphaCutoff') { // TODO DIFFUSEMAP_ALPHA_ALPHA if (standardMaterial.isDefined('fragment', 'ALPHA_TEST')) { var alphaCutoff = standardMaterial.get('alphaCutoff'); return alphaCutoff || 0; } return 0; } else { var useRoughnessWorkflow = standardMaterial.isDefined('fragment', 'USE_ROUGHNESS'); var roughGlossMap = useRoughnessWorkflow ? standardMaterial.get('roughnessMap') : standardMaterial.get('glossinessMap'); switch (symbol) { case 'glossiness': return useRoughnessWorkflow ? (1.0 - standardMaterial.get('roughness')) : standardMaterial.get('glossiness'); case 'roughGlossMap': return roughGlossMap; case 'useRoughGlossMap': return !!roughGlossMap; case 'useRoughness': return useRoughnessWorkflow; case 'roughGlossChannel': return useRoughnessWorkflow ? standardMaterial.getDefine('fragment', 'ROUGHNESS_CHANNEL') : standardMaterial.getDefine('fragment', 'GLOSSINESS_CHANNEL'); } } }; } function getGetUniformHook2(defaultDiffuseMap, defaultMetalnessMap) { return function (renderable, gBufferMat, symbol) { var standardMaterial = renderable.material; switch (symbol) { case 'color': case 'uvRepeat': case 'uvOffset': case 'alpha': return standardMaterial.get(symbol); case 'metalness': return standardMaterial.get('metalness') || 0; case 'diffuseMap': return standardMaterial.get(symbol) || defaultDiffuseMap; case 'metalnessMap': return standardMaterial.get(symbol) || defaultMetalnessMap; case 'useMetalnessMap': return !!standardMaterial.get('metalnessMap'); case 'linear': return standardMaterial.isDefined('SRGB_DECODE'); case 'alphaCutoff': // TODO DIFFUSEMAP_ALPHA_ALPHA if (standardMaterial.isDefined('fragment', 'ALPHA_TEST')) { var alphaCutoff = standardMaterial.get('alphaCutoff'); return alphaCutoff || 0.0; } return 0.0; } }; } /** * GBuffer is provided for deferred rendering and SSAO, SSR pass. * It will do three passes rendering to four target textures. See * + {@link clay.deferred.GBuffer#getTargetTexture1} * + {@link clay.deferred.GBuffer#getTargetTexture2} * + {@link clay.deferred.GBuffer#getTargetTexture3} * + {@link clay.deferred.GBuffer#getTargetTexture4} * @constructor * @alias clay.deferred.GBuffer * @extends clay.core.Base */ var GBuffer = Base.extend(function () { var commonTextureOpts = { minFilter: Texture.NEAREST, magFilter: Texture.NEAREST, wrapS: Texture.CLAMP_TO_EDGE, wrapT: Texture.CLAMP_TO_EDGE, }; return /** @lends clay.deferred.GBuffer# */ { /** * If enable gbuffer texture 1. * @type {boolean} */ enableTargetTexture1: true, /** * If enable gbuffer texture 2. * @type {boolean} */ enableTargetTexture2: true, /** * If enable gbuffer texture 3. * @type {boolean} */ enableTargetTexture3: true, /** * If enable gbuffer texture 4. * @type {boolean} */ enableTargetTexture4: false, renderTransparent: false, _gBufferRenderList: [], // - R: normal.x // - G: normal.y // - B: normal.z // - A: glossiness _gBufferTex1: new Texture2D(Object.assign({ // PENDING type: Texture.HALF_FLOAT }, commonTextureOpts)), // - R: depth _gBufferTex2: new Texture2D(Object.assign({ // format: Texture.DEPTH_COMPONENT, // type: Texture.UNSIGNED_INT format: Texture.DEPTH_STENCIL, type: Texture.UNSIGNED_INT_24_8_WEBGL }, commonTextureOpts)), // - R: albedo.r // - G: albedo.g // - B: albedo.b // - A: metalness _gBufferTex3: new Texture2D(commonTextureOpts), _gBufferTex4: new Texture2D(Object.assign({ // FLOAT Texture has bug on iOS. is HALF_FLOAT enough? type: Texture.HALF_FLOAT }, commonTextureOpts)), _defaultNormalMap: new Texture2D({ image: createFillCanvas('#000') }), _defaultRoughnessMap: new Texture2D({ image: createFillCanvas('#fff') }), _defaultMetalnessMap: new Texture2D({ image: createFillCanvas('#fff') }), _defaultDiffuseMap: new Texture2D({ image: createFillCanvas('#fff') }), _frameBuffer: new FrameBuffer(), _gBufferMaterial1: new Material({ shader: new Shader( Shader.source('clay.deferred.gbuffer.vertex'), Shader.source('clay.deferred.gbuffer1.fragment') ), vertexDefines: { FIRST_PASS: null }, fragmentDefines: { FIRST_PASS: null } }), _gBufferMaterial2: new Material({ shader: new Shader( Shader.source('clay.deferred.gbuffer.vertex'), Shader.source('clay.deferred.gbuffer2.fragment') ), vertexDefines: { SECOND_PASS: null }, fragmentDefines: { SECOND_PASS: null } }), _gBufferMaterial3: new Material({ shader: new Shader( Shader.source('clay.deferred.gbuffer.vertex'), Shader.source('clay.deferred.gbuffer3.fragment') ), vertexDefines: { THIRD_PASS: null }, fragmentDefines: { THIRD_PASS: null } }), _debugPass: new Pass({ fragment: Shader.source('clay.deferred.gbuffer.debug') }) }; }, /** @lends clay.deferred.GBuffer# */{ /** * Set G Buffer size. * @param {number} width * @param {number} height */ resize: function (width, height) { if (this._gBufferTex1.width === width && this._gBufferTex1.height === height ) { return; } this._gBufferTex1.width = width; this._gBufferTex1.height = height; this._gBufferTex2.width = width; this._gBufferTex2.height = height; this._gBufferTex3.width = width; this._gBufferTex3.height = height; this._gBufferTex4.width = width; this._gBufferTex4.height = height; }, // TODO is dpr needed? setViewport: function (x, y, width, height, dpr) { var viewport; if (typeof x === 'object') { viewport = x; } else { viewport = { x: x, y: y, width: width, height: height, devicePixelRatio: dpr || 1 }; } this._frameBuffer.viewport = viewport; }, getViewport: function () { if (this._frameBuffer.viewport) { return this._frameBuffer.viewport; } else { return { x: 0, y: 0, width: this._gBufferTex1.width, height: this._gBufferTex1.height, devicePixelRatio: 1 }; } }, /** * Update GBuffer * @param {clay.Renderer} renderer * @param {clay.Scene} scene * @param {clay.Camera} camera * @param {Object} opts */ update: function (renderer, scene, camera, opts) { opts = opts || {}; var gl = renderer.gl; var frameBuffer = this._frameBuffer; var viewport = frameBuffer.viewport; var renderList = scene.updateRenderList(camera, true); var opaqueList = renderList.opaque; var transparentList = renderList.transparent; var offset = 0; var gBufferRenderList = this._gBufferRenderList; for (var i = 0; i < opaqueList.length; i++) { if (!opaqueList[i].ignoreGBuffer) { gBufferRenderList[offset++] = opaqueList[i]; } } if (this.renderTransparent) { for (var i = 0; i < transparentList.length; i++) { if (!transparentList[i].ignoreGBuffer) { gBufferRenderList[offset++] = transparentList[i]; } } } gBufferRenderList.length = offset; gl.clearColor(0, 0, 0, 0); gl.depthMask(true); gl.colorMask(true, true, true, true); gl.disable(gl.BLEND); var enableTargetTexture1 = this.enableTargetTexture1; var enableTargetTexture2 = this.enableTargetTexture2; var enableTargetTexture3 = this.enableTargetTexture3; var enableTargetTexture4 = this.enableTargetTexture4; if (!enableTargetTexture1 && !enableTargetTexture3 && !enableTargetTexture4) { console.warn('Can\'t disable targetTexture1, targetTexture3, targetTexture4 both'); enableTargetTexture1 = true; } if (enableTargetTexture2) { frameBuffer.attach(opts.targetTexture2 || this._gBufferTex2, renderer.gl.DEPTH_STENCIL_ATTACHMENT); } function clearViewport() { if (viewport) { var dpr = viewport.devicePixelRatio; // use scissor to make sure only clear the viewport gl.enable(gl.SCISSOR_TEST); gl.scissor(viewport.x * dpr, viewport.y * dpr, viewport.width * dpr, viewport.height * dpr); } gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); if (viewport) { gl.disable(gl.SCISSOR_TEST); } } function isMaterialChanged(renderable, prevRenderable) { return renderable.material !== prevRenderable.material; } // PENDING, scene.boundingBoxLastFrame needs be updated if have shadow renderer.bindSceneRendering(scene); if (enableTargetTexture1) { // Pass 1 frameBuffer.attach(opts.targetTexture1 || this._gBufferTex1); frameBuffer.bind(renderer); clearViewport(); var gBufferMaterial1 = this._gBufferMaterial1; var passConfig = { getMaterial: function () { return gBufferMaterial1; }, getUniform: getGetUniformHook1(this._defaultNormalMap, this._defaultRoughnessMap, this._defaultDiffuseMap), isMaterialChanged: isMaterialChanged, sortCompare: renderer.opaqueSortCompare }; // FIXME Use MRT if possible renderer.renderPass(gBufferRenderList, camera, passConfig); } if (enableTargetTexture3) { // Pass 2 frameBuffer.attach(opts.targetTexture3 || this._gBufferTex3); frameBuffer.bind(renderer); clearViewport(); var gBufferMaterial2 = this._gBufferMaterial2; var passConfig = { getMaterial: function () { return gBufferMaterial2; }, getUniform: getGetUniformHook2(this._defaultDiffuseMap, this._defaultMetalnessMap), isMaterialChanged: isMaterialChanged, sortCompare: renderer.opaqueSortCompare }; renderer.renderPass(gBufferRenderList, camera, passConfig); } if (enableTargetTexture4) { frameBuffer.bind(renderer); frameBuffer.attach(opts.targetTexture4 || this._gBufferTex4); clearViewport(); // Remove jittering in temporal aa. // PENDING. Better solution? camera.update(); var gBufferMaterial3 = this._gBufferMaterial3; var cameraViewProj = mat4.create(); mat4.multiply(cameraViewProj, camera.projectionMatrix.array, camera.viewMatrix.array); var passConfig = { getMaterial: function () { return gBufferMaterial3; }, afterRender: function (renderer, renderable) { var isSkinnedMesh = renderable.isSkinnedMesh(); if (isSkinnedMesh) { var skeleton = renderable.skeleton; var joints = renderable.joints; if (joints.length > renderer.getMaxJointNumber()) { var skinMatricesTexture = skeleton.getSubSkinMatricesTexture(renderable.__uid__, joints); var prevSkinMatricesTexture = renderable.__prevSkinMatricesTexture; if (!prevSkinMatricesTexture) { prevSkinMatricesTexture = renderable.__prevSkinMatricesTexture = new Texture2D({ type: Texture.FLOAT, minFilter: Texture.NEAREST, magFilter: Texture.NEAREST, useMipmap: false, flipY: false }); } if (!prevSkinMatricesTexture.pixels || prevSkinMatricesTexture.pixels.length !== skinMatricesTexture.pixels.length ) { prevSkinMatricesTexture.pixels = new Float32Array(skinMatricesTexture.pixels); } else { for (var i = 0; i < skinMatricesTexture.pixels.length; i++) { prevSkinMatricesTexture.pixels[i] = skinMatricesTexture.pixels[i]; } } prevSkinMatricesTexture.width = skinMatricesTexture.width; prevSkinMatricesTexture.height = skinMatricesTexture.height; } else { var skinMatricesArray = skeleton.getSubSkinMatrices(renderable.__uid__, joints); if (!renderable.__prevSkinMatricesArray || renderable.__prevSkinMatricesArray.length !== skinMatricesArray.length) { renderable.__prevSkinMatricesArray = new Float32Array(skinMatricesArray.length); } renderable.__prevSkinMatricesArray.set(skinMatricesArray); } } renderable.__prevWorldViewProjection = renderable.__prevWorldViewProjection || mat4.create(); if (isSkinnedMesh) { // Ignore world transform of skinned mesh. mat4.copy(renderable.__prevWorldViewProjection, cameraViewProj); } else { mat4.multiply(renderable.__prevWorldViewProjection, cameraViewProj, renderable.worldTransform.array); } }, getUniform: function (renderable, gBufferMat, symbol) { if (symbol === 'prevWorldViewProjection') { return renderable.__prevWorldViewProjection; } else if (symbol === 'prevSkinMatrix') { return renderable.__prevSkinMatricesArray; } else if (symbol === 'prevSkinMatricesTexture') { return renderable.__prevSkinMatricesTexture; } else if (symbol === 'firstRender') { return !renderable.__prevWorldViewProjection; } else { return gBufferMat.get(symbol); } }, isMaterialChanged: function () { // Always update prevWorldViewProjection return true; }, sortCompare: renderer.opaqueSortCompare }; renderer.renderPass(gBufferRenderList, camera, passConfig); } renderer.bindSceneRendering(null); frameBuffer.unbind(renderer); }, /** * Debug output of gBuffer. Use `type` parameter to choos the debug output type, which can be: * * + 'normal' * + 'depth' * + 'position' * + 'glossiness' * + 'metalness' * + 'albedo' * + 'velocity' * * @param {clay.Renderer} renderer * @param {clay.Camera} camera * @param {string} [type='normal'] */ renderDebug: function (renderer, camera, type, viewport) { var debugTypes = { normal: 0, depth: 1, position: 2, glossiness: 3, metalness: 4, albedo: 5, velocity: 6 }; if (debugTypes[type] == null) { console.warn('Unkown type "' + type + '"'); // Default use normal type = 'normal'; } renderer.saveClear(); renderer.saveViewport(); renderer.clearBit = renderer.gl.DEPTH_BUFFER_BIT; if (viewport) { renderer.setViewport(viewport); } var viewProjectionInv = new Matrix4(); Matrix4.multiply(viewProjectionInv, camera.worldTransform, camera.invProjectionMatrix); var debugPass = this._debugPass; debugPass.setUniform('viewportSize', [renderer.getWidth(), renderer.getHeight()]); debugPass.setUniform('gBufferTexture1', this._gBufferTex1); debugPass.setUniform('gBufferTexture2', this._gBufferTex2); debugPass.setUniform('gBufferTexture3', this._gBufferTex3); debugPass.setUniform('gBufferTexture4', this._gBufferTex4); debugPass.setUniform('debug', debugTypes[type]); debugPass.setUniform('viewProjectionInv', viewProjectionInv.array); debugPass.render(renderer); renderer.restoreViewport(); renderer.restoreClear(); }, /** * Get first target texture. * Channel storage: * + R: normal.x * 0.5 + 0.5 * + G: normal.y * 0.5 + 0.5 * + B: normal.z * 0.5 + 0.5 * + A: glossiness * @return {clay.Texture2D} */ getTargetTexture1: function () { return this._gBufferTex1; }, /** * Get second target texture. * Channel storage: * + R: depth * @return {clay.Texture2D} */ getTargetTexture2: function () { return this._gBufferTex2; }, /** * Get third target texture. * Channel storage: * + R: albedo.r * + G: albedo.g * + B: albedo.b * + A: metalness * @return {clay.Texture2D} */ getTargetTexture3: function () { return this._gBufferTex3; }, /** * Get fourth target texture. * Channel storage: * + R: velocity.r * + G: velocity.g * @return {clay.Texture2D} */ getTargetTexture4: function () { return this._gBufferTex4; }, /** * @param {clay.Renderer} renderer */ dispose: function (renderer) { this._gBufferTex1.dispose(renderer); this._gBufferTex2.dispose(renderer); this._gBufferTex3.dispose(renderer); this._defaultNormalMap.dispose(renderer); this._defaultRoughnessMap.dispose(renderer); this._defaultMetalnessMap.dispose(renderer); this._defaultDiffuseMap.dispose(renderer); this._frameBuffer.dispose(renderer); } }); /** * @constructor clay.geometry.Cone * @extends clay.Geometry * @param {Object} [opt] * @param {number} [opt.topRadius] * @param {number} [opt.bottomRadius] * @param {number} [opt.height] * @param {number} [opt.capSegments] * @param {number} [opt.heightSegments] */ var Cone$1 = Geometry.extend(/** @lends clay.geometry.Cone# */ { dynamic: false, /** * @type {number} */ topRadius: 0, /** * @type {number} */ bottomRadius: 1, /** * @type {number} */ height: 2, /** * @type {number} */ capSegments: 20, /** * @type {number} */ heightSegments: 1 }, function() { this.build(); }, /** @lends clay.geometry.Cone.prototype */ { /** * Build cone geometry */ build: function() { var positions = []; var texcoords = []; var faces = []; positions.length = 0; texcoords.length = 0; faces.length = 0; // Top cap var capSegRadial = Math.PI * 2 / this.capSegments; var topCap = []; var bottomCap = []; var r1 = this.topRadius; var r2 = this.bottomRadius; var y = this.height / 2; var c1 = vec3.fromValues(0, y, 0); var c2 = vec3.fromValues(0, -y, 0); for (var i = 0; i < this.capSegments; i++) { var theta = i * capSegRadial; var x = r1 * Math.sin(theta); var z = r1 * Math.cos(theta); topCap.push(vec3.fromValues(x, y, z)); x = r2 * Math.sin(theta); z = r2 * Math.cos(theta); bottomCap.push(vec3.fromValues(x, -y, z)); } // Build top cap positions.push(c1); // FIXME texcoords.push(vec2.fromValues(0, 1)); var n = this.capSegments; for (var i = 0; i < n; i++) { positions.push(topCap[i]); // FIXME texcoords.push(vec2.fromValues(i / n, 0)); faces.push([0, i+1, (i+1) % n + 1]); } // Build bottom cap var offset = positions.length; positions.push(c2); texcoords.push(vec2.fromValues(0, 1)); for (var i = 0; i < n; i++) { positions.push(bottomCap[i]); // FIXME texcoords.push(vec2.fromValues(i / n, 0)); faces.push([offset, offset+((i+1) % n + 1), offset+i+1]); } // Build side offset = positions.length; var n2 = this.heightSegments; for (var i = 0; i < n; i++) { for (var j = 0; j < n2+1; j++) { var v = j / n2; positions.push(vec3.lerp(vec3.create(), topCap[i], bottomCap[i], v)); texcoords.push(vec2.fromValues(i / n, v)); } } for (var i = 0; i < n; i++) { for (var j = 0; j < n2; j++) { var i1 = i * (n2 + 1) + j; var i2 = ((i + 1) % n) * (n2 + 1) + j; var i3 = ((i + 1) % n) * (n2 + 1) + j + 1; var i4 = i * (n2 + 1) + j + 1; faces.push([offset+i2, offset+i1, offset+i4]); faces.push([offset+i4, offset+i3, offset+i2]); } } this.attributes.position.fromArray(positions); this.attributes.texcoord0.fromArray(texcoords); this.initIndicesFromArray(faces); this.generateVertexNormals(); this.boundingBox = new BoundingBox(); var r = Math.max(this.topRadius, this.bottomRadius); this.boundingBox.min.set(-r, -this.height/2, -r); this.boundingBox.max.set(r, this.height/2, r); } }); /** * @constructor clay.geometry.Cylinder * @extends clay.Geometry * @param {Object} [opt] * @param {number} [opt.radius] * @param {number} [opt.height] * @param {number} [opt.capSegments] * @param {number} [opt.heightSegments] */ var Cylinder$1 = Geometry.extend( /** @lends clay.geometry.Cylinder# */ { dynamic: false, /** * @type {number} */ radius: 1, /** * @type {number} */ height: 2, /** * @type {number} */ capSegments: 50, /** * @type {number} */ heightSegments: 1 }, function() { this.build(); }, /** @lends clay.geometry.Cylinder.prototype */ { /** * Build cylinder geometry */ build: function() { var cone = new Cone$1({ topRadius: this.radius, bottomRadius: this.radius, capSegments: this.capSegments, heightSegments: this.heightSegments, height: this.height }); this.attributes.position.value = cone.attributes.position.value; this.attributes.normal.value = cone.attributes.normal.value; this.attributes.texcoord0.value = cone.attributes.texcoord0.value; this.indices = cone.indices; this.boundingBox = cone.boundingBox; } }); var lightvolumeGlsl = "@export clay.deferred.light_volume.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\nvarying vec3 v_Position;\nvoid main()\n{\n gl_Position = worldViewProjection * vec4(position, 1.0);\n v_Position = position;\n}\n@end"; var spotGlsl = "@export clay.deferred.spot_light\n@import clay.deferred.chunk.light_head\n@import clay.deferred.chunk.light_equation\n@import clay.util.calculate_attenuation\nuniform vec3 lightPosition;\nuniform vec3 lightDirection;\nuniform vec3 lightColor;\nuniform float umbraAngleCosine;\nuniform float penumbraAngleCosine;\nuniform float lightRange;\nuniform float falloffFactor;\nuniform vec3 eyePosition;\n#ifdef SHADOWMAP_ENABLED\nuniform sampler2D lightShadowMap;\nuniform mat4 lightMatrix;\nuniform float lightShadowMapSize;\n#endif\n@import clay.plugin.shadow_map_common\nvoid main()\n{\n @import clay.deferred.chunk.gbuffer_read\n vec3 L = lightPosition - position;\n vec3 V = normalize(eyePosition - position);\n float dist = length(L);\n L /= dist;\n float attenuation = lightAttenuation(dist, lightRange);\n float c = dot(-normalize(lightDirection), L);\n float falloff = clamp((c - umbraAngleCosine) / (penumbraAngleCosine - umbraAngleCosine), 0.0, 1.0);\n falloff = pow(falloff, falloffFactor);\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n gl_FragColor.rgb = (1.0 - falloff) * attenuation * lightEquation(\n lightColor, diffuseColor, specularColor, ndl, ndh, ndv, glossiness\n );\n#ifdef SHADOWMAP_ENABLED\n float shadowContrib = computeShadowContrib(\n lightShadowMap, lightMatrix, position, lightShadowMapSize\n );\n gl_FragColor.rgb *= shadowContrib;\n#endif\n gl_FragColor.a = 1.0;\n}\n@end\n"; var directionalGlsl = "@export clay.deferred.directional_light\n@import clay.deferred.chunk.light_head\n@import clay.deferred.chunk.light_equation\nuniform vec3 lightDirection;\nuniform vec3 lightColor;\nuniform vec3 eyePosition;\n#ifdef SHADOWMAP_ENABLED\nuniform sampler2D lightShadowMap;\nuniform float lightShadowMapSize;\nuniform mat4 lightMatrices[SHADOW_CASCADE];\nuniform float shadowCascadeClipsNear[SHADOW_CASCADE];\nuniform float shadowCascadeClipsFar[SHADOW_CASCADE];\n#endif\n@import clay.plugin.shadow_map_common\nvoid main()\n{\n @import clay.deferred.chunk.gbuffer_read\n vec3 L = -normalize(lightDirection);\n vec3 V = normalize(eyePosition - position);\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n gl_FragColor.rgb = lightEquation(\n lightColor, diffuseColor, specularColor, ndl, ndh, ndv, glossiness\n );\n#ifdef SHADOWMAP_ENABLED\n float shadowContrib = 1.0;\n for (int _idx_ = 0; _idx_ < SHADOW_CASCADE; _idx_++) {{\n if (\n z >= shadowCascadeClipsNear[_idx_] &&\n z <= shadowCascadeClipsFar[_idx_]\n ) {\n shadowContrib = computeShadowContrib(\n lightShadowMap, lightMatrices[_idx_], position, lightShadowMapSize,\n vec2(1.0 / float(SHADOW_CASCADE), 1.0),\n vec2(float(_idx_) / float(SHADOW_CASCADE), 0.0)\n );\n }\n }}\n gl_FragColor.rgb *= shadowContrib;\n#endif\n gl_FragColor.a = 1.0;\n}\n@end\n"; var ambientGlsl = "@export clay.deferred.ambient_light\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture3;\nuniform vec3 lightColor;\nuniform vec2 windowSize: WINDOW_SIZE;\nvoid main()\n{\n vec2 uv = gl_FragCoord.xy / windowSize;\n vec4 texel1 = texture2D(gBufferTexture1, uv);\n if (dot(texel1.rgb, vec3(1.0)) == 0.0) {\n discard;\n }\n vec3 albedo = texture2D(gBufferTexture3, uv).rgb;\n gl_FragColor.rgb = lightColor * albedo;\n gl_FragColor.a = 1.0;\n}\n@end"; var ambientshGlsl = "@export clay.deferred.ambient_sh_light\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture3;\nuniform vec3 lightColor;\nuniform vec3 lightCoefficients[9];\nuniform vec2 windowSize: WINDOW_SIZE;\nvec3 calcAmbientSHLight(vec3 N) {\n return lightCoefficients[0]\n + lightCoefficients[1] * N.x\n + lightCoefficients[2] * N.y\n + lightCoefficients[3] * N.z\n + lightCoefficients[4] * N.x * N.z\n + lightCoefficients[5] * N.z * N.y\n + lightCoefficients[6] * N.y * N.x\n + lightCoefficients[7] * (3.0 * N.z * N.z - 1.0)\n + lightCoefficients[8] * (N.x * N.x - N.y * N.y);\n}\nvoid main()\n{\n vec2 uv = gl_FragCoord.xy / windowSize;\n vec4 texel1 = texture2D(gBufferTexture1, uv);\n if (dot(texel1.rgb, vec3(1.0)) == 0.0) {\n discard;\n }\n vec3 N = texel1.rgb * 2.0 - 1.0;\n vec3 albedo = texture2D(gBufferTexture3, uv).rgb;\n gl_FragColor.rgb = lightColor * albedo * calcAmbientSHLight(N);\n gl_FragColor.a = 1.0;\n}\n@end"; var ambientcubemapGlsl = "@export clay.deferred.ambient_cubemap_light\n@import clay.deferred.chunk.light_head\nuniform vec3 lightColor;\nuniform samplerCube lightCubemap;\nuniform sampler2D brdfLookup;\nuniform vec3 eyePosition;\n@import clay.util.rgbm\nvoid main()\n{\n @import clay.deferred.chunk.gbuffer_read\n vec3 V = normalize(eyePosition - position);\n vec3 L = reflect(-V, N);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n float rough = clamp(1.0 - glossiness, 0.0, 1.0);\n float bias = rough * 5.0;\n vec2 brdfParam = texture2D(brdfLookup, vec2(rough, ndv)).xy;\n vec3 envWeight = specularColor * brdfParam.x + brdfParam.y;\n vec3 envTexel = RGBMDecode(textureCubeLodEXT(lightCubemap, L, bias), 8.12);\n gl_FragColor.rgb = lightColor * envTexel * envWeight;\n gl_FragColor.a = 1.0;\n}\n@end"; var pointGlsl = "@export clay.deferred.point_light\n@import clay.deferred.chunk.light_head\n@import clay.util.calculate_attenuation\n@import clay.deferred.chunk.light_equation\nuniform vec3 lightPosition;\nuniform vec3 lightColor;\nuniform float lightRange;\nuniform vec3 eyePosition;\n#ifdef SHADOWMAP_ENABLED\nuniform samplerCube lightShadowMap;\nuniform float lightShadowMapSize;\n#endif\nvarying vec3 v_Position;\n@import clay.plugin.shadow_map_common\nvoid main()\n{\n @import clay.deferred.chunk.gbuffer_read\n vec3 L = lightPosition - position;\n vec3 V = normalize(eyePosition - position);\n float dist = length(L);\n L /= dist;\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n float attenuation = lightAttenuation(dist, lightRange);\n gl_FragColor.rgb = attenuation * lightEquation(\n lightColor, diffuseColor, specularColor, ndl, ndh, ndv, glossiness\n );\n#ifdef SHADOWMAP_ENABLED\n float shadowContrib = computeShadowContribOmni(\n lightShadowMap, -L * dist, lightRange\n );\n gl_FragColor.rgb *= clamp(shadowContrib, 0.0, 1.0);\n#endif\n gl_FragColor.a = 1.0;\n}\n@end"; var sphereGlsl = "@export clay.deferred.sphere_light\n@import clay.deferred.chunk.light_head\n@import clay.util.calculate_attenuation\n@import clay.deferred.chunk.light_equation\nuniform vec3 lightPosition;\nuniform vec3 lightColor;\nuniform float lightRange;\nuniform float lightRadius;\nuniform vec3 eyePosition;\nvarying vec3 v_Position;\nvoid main()\n{\n @import clay.deferred.chunk.gbuffer_read\n vec3 L = lightPosition - position;\n vec3 V = normalize(eyePosition - position);\n float dist = length(L);\n vec3 R = reflect(V, N);\n float tmp = dot(L, R);\n vec3 cToR = tmp * R - L;\n float d = length(cToR);\n L = L + cToR * clamp(lightRadius / d, 0.0, 1.0);\n L = normalize(L);\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n float attenuation = lightAttenuation(dist, lightRange);\n gl_FragColor.rgb = lightColor * ndl * attenuation;\n glossiness = clamp(glossiness - lightRadius / 2.0 / dist, 0.0, 1.0);\n gl_FragColor.rgb = attenuation * lightEquation(\n lightColor, diffuseColor, specularColor, ndl, ndh, ndv, glossiness\n );\n gl_FragColor.a = 1.0;\n}\n@end"; var tubeGlsl = "@export clay.deferred.tube_light\n@import clay.deferred.chunk.light_head\n@import clay.util.calculate_attenuation\n@import clay.deferred.chunk.light_equation\nuniform vec3 lightPosition;\nuniform vec3 lightColor;\nuniform float lightRange;\nuniform vec3 lightExtend;\nuniform vec3 eyePosition;\nvarying vec3 v_Position;\nvoid main()\n{\n @import clay.deferred.chunk.gbuffer_read\n vec3 L = lightPosition - position;\n vec3 V = normalize(eyePosition - position);\n vec3 R = reflect(V, N);\n vec3 L0 = lightPosition - lightExtend - position;\n vec3 L1 = lightPosition + lightExtend - position;\n vec3 LD = L1 - L0;\n float len0 = length(L0);\n float len1 = length(L1);\n float irra = 2.0 * clamp(dot(N, L0) / (2.0 * len0) + dot(N, L1) / (2.0 * len1), 0.0, 1.0);\n float LDDotR = dot(R, LD);\n float t = (LDDotR * dot(R, L0) - dot(L0, LD)) / (dot(LD, LD) - LDDotR * LDDotR);\n t = clamp(t, 0.0, 1.0);\n L = L0 + t * LD;\n float dist = length(L);\n L /= dist;\n vec3 H = normalize(L + V);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n glossiness = clamp(glossiness - 0.0 / 2.0 / dist, 0.0, 1.0);\n gl_FragColor.rgb = lightColor * irra * lightAttenuation(dist, lightRange)\n * (diffuseColor + D_Phong(glossiness, ndh) * F_Schlick(ndv, specularColor));\n gl_FragColor.a = 1.0;\n}\n@end"; // Light-pre pass deferred rendering // http://www.realtimerendering.com/blog/deferred-lighting-approaches/ // Light shaders Shader.import(prezGlsl); Shader.import(utilGlsl); Shader.import(lightvolumeGlsl); // Light shaders Shader.import(spotGlsl); Shader.import(directionalGlsl); Shader.import(ambientGlsl); Shader.import(ambientshGlsl); Shader.import(ambientcubemapGlsl); Shader.import(pointGlsl); Shader.import(sphereGlsl); Shader.import(tubeGlsl); Shader.import(prezGlsl); /** * Deferred renderer * @constructor * @alias clay.deferred.Renderer * @extends clay.core.Base */ var DeferredRenderer = Base.extend(function () { var fullQuadVertex = Shader.source('clay.compositor.vertex'); var lightVolumeVertex = Shader.source('clay.deferred.light_volume.vertex'); var directionalLightShader = new Shader(fullQuadVertex, Shader.source('clay.deferred.directional_light')); var lightAccumulateBlendFunc = function (gl) { gl.blendEquation(gl.FUNC_ADD); gl.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE); }; var createLightPassMat = function (shader) { return new Material({ shader: shader, blend: lightAccumulateBlendFunc, transparent: true, depthMask: false }); }; var createVolumeShader = function (name) { return new Shader(lightVolumeVertex, Shader.source('clay.deferred.' + name)); }; // Rotate and positioning to fit the spot light // Which the cusp of cone pointing to the positive z // and positioned on the origin var coneGeo = new Cone$1({ capSegments: 10 }); var mat = new Matrix4(); mat.rotateX(Math.PI / 2) .translate(new Vector3(0, -1, 0)); coneGeo.applyTransform(mat); var cylinderGeo = new Cylinder$1({ capSegments: 10 }); // Align with x axis mat.identity().rotateZ(Math.PI / 2); cylinderGeo.applyTransform(mat); return /** @lends clay.deferred.Renderer# */ { /** * Provide ShadowMapPass for shadow rendering. * @type {clay.prePass.ShadowMap} */ shadowMapPass: null, /** * If enable auto resizing from given defualt renderer size. * @type {boolean} */ autoResize: true, _createLightPassMat: createLightPassMat, _gBuffer: new GBuffer(), _lightAccumFrameBuffer: new FrameBuffer(), _lightAccumTex: new Texture2D({ // FIXME Device not support float texture type: Texture.HALF_FLOAT, minFilter: Texture.NEAREST, magFilter: Texture.NEAREST }), _fullQuadPass: new Pass({ blendWithPrevious: true }), _directionalLightMat: createLightPassMat(directionalLightShader), _ambientMat: createLightPassMat(new Shader( fullQuadVertex, Shader.source('clay.deferred.ambient_light') )), _ambientSHMat: createLightPassMat(new Shader( fullQuadVertex, Shader.source('clay.deferred.ambient_sh_light') )), _ambientCubemapMat: createLightPassMat(new Shader( fullQuadVertex, Shader.source('clay.deferred.ambient_cubemap_light') )), _spotLightShader: createVolumeShader('spot_light'), _pointLightShader: createVolumeShader('point_light'), _sphereLightShader: createVolumeShader('sphere_light'), _tubeLightShader: createVolumeShader('tube_light'), _lightSphereGeo: new Sphere$1({ widthSegments: 10, heightSegements: 10 }), _lightConeGeo: coneGeo, _lightCylinderGeo: cylinderGeo, _outputPass: new Pass({ fragment: Shader.source('clay.compositor.output') }) }; }, /** @lends clay.deferred.Renderer# */ { /** * Do render * @param {clay.Renderer} renderer * @param {clay.Scene} scene * @param {clay.Camera} camera * @param {Object} [opts] * @param {boolean} [opts.renderToTarget = false] If not ouput and render to the target texture * @param {boolean} [opts.notUpdateShadow = true] If not update the shadow. * @param {boolean} [opts.notUpdateScene = true] If not update the scene. */ render: function (renderer, scene, camera, opts) { opts = opts || {}; opts.renderToTarget = opts.renderToTarget || false; opts.notUpdateShadow = opts.notUpdateShadow || false; opts.notUpdateScene = opts.notUpdateScene || false; if (!opts.notUpdateScene) { scene.update(false, true); } scene.updateLights(); // Render list will be updated in gbuffer. camera.update(true); // PENDING For stereo rendering var dpr = renderer.getDevicePixelRatio(); if (this.autoResize && (renderer.getWidth() * dpr !== this._lightAccumTex.width || renderer.getHeight() * dpr !== this._lightAccumTex.height) ) { this.resize(renderer.getWidth() * dpr, renderer.getHeight() * dpr); } this._gBuffer.update(renderer, scene, camera); // Accumulate light buffer this._accumulateLightBuffer(renderer, scene, camera, !opts.notUpdateShadow); if (!opts.renderToTarget) { this._outputPass.setUniform('texture', this._lightAccumTex); this._outputPass.render(renderer); // this._gBuffer.renderDebug(renderer, camera, 'normal'); } }, /** * @return {clay.Texture2D} */ getTargetTexture: function () { return this._lightAccumTex; }, /** * @return {clay.FrameBuffer} */ getTargetFrameBuffer: function () { return this._lightAccumFrameBuffer; }, /** * @return {clay.deferred.GBuffer} */ getGBuffer: function () { return this._gBuffer; }, // TODO is dpr needed? setViewport: function (x, y, width, height, dpr) { this._gBuffer.setViewport(x, y, width, height, dpr); this._lightAccumFrameBuffer.viewport = this._gBuffer.getViewport(); }, // getFullQuadLightPass: function () { // return this._fullQuadPass; // }, /** * Set renderer size. * @param {number} width * @param {number} height */ resize: function (width, height) { this._lightAccumTex.width = width; this._lightAccumTex.height = height; // PENDING viewport ? this._gBuffer.resize(width, height); }, _accumulateLightBuffer: function (renderer, scene, camera, updateShadow) { var gl = renderer.gl; var lightAccumTex = this._lightAccumTex; var lightAccumFrameBuffer = this._lightAccumFrameBuffer; var eyePosition = camera.getWorldPosition().array; // Update volume meshes for (var i = 0; i < scene.lights.length; i++) { if (!scene.lights[i].invisible) { this._updateLightProxy(scene.lights[i]); } } var shadowMapPass = this.shadowMapPass; if (shadowMapPass && updateShadow) { gl.clearColor(1, 1, 1, 1); this._prepareLightShadow(renderer, scene, camera); } this.trigger('beforelightaccumulate', renderer, scene, camera, updateShadow); lightAccumFrameBuffer.attach(lightAccumTex); lightAccumFrameBuffer.bind(renderer); var clearColor = renderer.clearColor; var viewport = lightAccumFrameBuffer.viewport; if (viewport) { var dpr = viewport.devicePixelRatio; // use scissor to make sure only clear the viewport gl.enable(gl.SCISSOR_TEST); gl.scissor(viewport.x * dpr, viewport.y * dpr, viewport.width * dpr, viewport.height * dpr); } gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); gl.clear(gl.COLOR_BUFFER_BIT); gl.enable(gl.BLEND); if (viewport) { gl.disable(gl.SCISSOR_TEST); } this.trigger('startlightaccumulate', renderer, scene, camera); var viewProjectionInv = new Matrix4(); Matrix4.multiply(viewProjectionInv, camera.worldTransform, camera.invProjectionMatrix); var volumeMeshList = []; for (var i = 0; i < scene.lights.length; i++) { var light = scene.lights[i]; if (light.invisible) { continue; } var uTpl = light.uniformTemplates; var volumeMesh = light.volumeMesh || light.__volumeMesh; if (volumeMesh) { var material = volumeMesh.material; // Volume mesh will affect the scene bounding box when rendering // if castShadow is true volumeMesh.castShadow = false; var unknownLightType = false; switch (light.type) { case 'POINT_LIGHT': material.setUniform('lightColor', uTpl.pointLightColor.value(light)); material.setUniform('lightRange', uTpl.pointLightRange.value(light)); material.setUniform('lightPosition', uTpl.pointLightPosition.value(light)); break; case 'SPOT_LIGHT': material.setUniform('lightPosition', uTpl.spotLightPosition.value(light)); material.setUniform('lightColor', uTpl.spotLightColor.value(light)); material.setUniform('lightRange', uTpl.spotLightRange.value(light)); material.setUniform('lightDirection', uTpl.spotLightDirection.value(light)); material.setUniform('umbraAngleCosine', uTpl.spotLightUmbraAngleCosine.value(light)); material.setUniform('penumbraAngleCosine', uTpl.spotLightPenumbraAngleCosine.value(light)); material.setUniform('falloffFactor', uTpl.spotLightFalloffFactor.value(light)); break; case 'SPHERE_LIGHT': material.setUniform('lightColor', uTpl.sphereLightColor.value(light)); material.setUniform('lightRange', uTpl.sphereLightRange.value(light)); material.setUniform('lightRadius', uTpl.sphereLightRadius.value(light)); material.setUniform('lightPosition', uTpl.sphereLightPosition.value(light)); break; case 'TUBE_LIGHT': material.setUniform('lightColor', uTpl.tubeLightColor.value(light)); material.setUniform('lightRange', uTpl.tubeLightRange.value(light)); material.setUniform('lightExtend', uTpl.tubeLightExtend.value(light)); material.setUniform('lightPosition', uTpl.tubeLightPosition.value(light)); break; default: unknownLightType = true; } if (unknownLightType) { continue; } material.setUniform('eyePosition', eyePosition); material.setUniform('viewProjectionInv', viewProjectionInv.array); material.setUniform('gBufferTexture1', this._gBuffer.getTargetTexture1()); material.setUniform('gBufferTexture2', this._gBuffer.getTargetTexture2()); material.setUniform('gBufferTexture3', this._gBuffer.getTargetTexture3()); volumeMeshList.push(volumeMesh); } else { var pass = this._fullQuadPass; var unknownLightType = false; // Full quad light switch (light.type) { case 'AMBIENT_LIGHT': pass.material = this._ambientMat; pass.material.setUniform('lightColor', uTpl.ambientLightColor.value(light)); break; case 'AMBIENT_SH_LIGHT': pass.material = this._ambientSHMat; pass.material.setUniform('lightColor', uTpl.ambientSHLightColor.value(light)); pass.material.setUniform('lightCoefficients', uTpl.ambientSHLightCoefficients.value(light)); break; case 'AMBIENT_CUBEMAP_LIGHT': pass.material = this._ambientCubemapMat; pass.material.setUniform('lightColor', uTpl.ambientCubemapLightColor.value(light)); pass.material.setUniform('lightCubemap', uTpl.ambientCubemapLightCubemap.value(light)); pass.material.setUniform('brdfLookup', uTpl.ambientCubemapLightBRDFLookup.value(light)); break; case 'DIRECTIONAL_LIGHT': var hasShadow = shadowMapPass && light.castShadow; pass.material = this._directionalLightMat; pass.material[hasShadow ? 'define' : 'undefine']('fragment', 'SHADOWMAP_ENABLED'); if (hasShadow) { pass.material.define('fragment', 'SHADOW_CASCADE', light.shadowCascade); } pass.material.setUniform('lightColor', uTpl.directionalLightColor.value(light)); pass.material.setUniform('lightDirection', uTpl.directionalLightDirection.value(light)); break; default: // Unkonw light type unknownLightType = true; } if (unknownLightType) { continue; } var passMaterial = pass.material; passMaterial.setUniform('eyePosition', eyePosition); passMaterial.setUniform('viewProjectionInv', viewProjectionInv.array); passMaterial.setUniform('gBufferTexture1', this._gBuffer.getTargetTexture1()); passMaterial.setUniform('gBufferTexture2', this._gBuffer.getTargetTexture2()); passMaterial.setUniform('gBufferTexture3', this._gBuffer.getTargetTexture3()); // TODO if (shadowMapPass && light.castShadow) { passMaterial.setUniform('lightShadowMap', light.__shadowMap); passMaterial.setUniform('lightMatrices', light.__lightMatrices); passMaterial.setUniform('shadowCascadeClipsNear', light.__cascadeClipsNear); passMaterial.setUniform('shadowCascadeClipsFar', light.__cascadeClipsFar); passMaterial.setUniform('lightShadowMapSize', light.shadowResolution); } pass.renderQuad(renderer); } } this._renderVolumeMeshList(renderer, scene, camera, volumeMeshList); this.trigger('lightaccumulate', renderer, scene, camera); lightAccumFrameBuffer.unbind(renderer); this.trigger('afterlightaccumulate', renderer, scene, camera); }, _prepareLightShadow: (function () { var worldView = new Matrix4(); return function (renderer, scene, camera) { for (var i = 0; i < scene.lights.length; i++) { var light = scene.lights[i]; var volumeMesh = light.volumeMesh || light.__volumeMesh; if (!light.castShadow || light.invisible) { continue; } switch (light.type) { case 'POINT_LIGHT': case 'SPOT_LIGHT': // Frustum culling Matrix4.multiply(worldView, camera.viewMatrix, volumeMesh.worldTransform); if (scene.isFrustumCulled(volumeMesh, camera, worldView.array)) { continue; } this._prepareSingleLightShadow( renderer, scene, camera, light, volumeMesh.material ); break; case 'DIRECTIONAL_LIGHT': this._prepareSingleLightShadow( renderer, scene, camera, light, null ); } } }; })(), _prepareSingleLightShadow: function (renderer, scene, camera, light, material) { switch (light.type) { case 'POINT_LIGHT': var shadowMaps = []; this.shadowMapPass.renderPointLightShadow( renderer, scene, light, shadowMaps ); material.setUniform('lightShadowMap', shadowMaps[0]); material.setUniform('lightShadowMapSize', light.shadowResolution); break; case 'SPOT_LIGHT': var shadowMaps = []; var lightMatrices = []; this.shadowMapPass.renderSpotLightShadow( renderer, scene, light, lightMatrices, shadowMaps ); material.setUniform('lightShadowMap', shadowMaps[0]); material.setUniform('lightMatrix', lightMatrices[0]); material.setUniform('lightShadowMapSize', light.shadowResolution); break; case 'DIRECTIONAL_LIGHT': var shadowMaps = []; var lightMatrices = []; var cascadeClips = []; this.shadowMapPass.renderDirectionalLightShadow( renderer, scene, camera, light, cascadeClips, lightMatrices, shadowMaps ); var cascadeClipsNear = cascadeClips.slice(); var cascadeClipsFar = cascadeClips.slice(); cascadeClipsNear.pop(); cascadeClipsFar.shift(); // Iterate from far to near cascadeClipsNear.reverse(); cascadeClipsFar.reverse(); lightMatrices.reverse(); light.__cascadeClipsNear = cascadeClipsNear; light.__cascadeClipsFar = cascadeClipsFar; light.__shadowMap = shadowMaps[0]; light.__lightMatrices = lightMatrices; break; } }, // Update light volume mesh // Light volume mesh is rendered in light accumulate pass instead of full quad. // It will reduce pixels significantly when local light is relatively small. // And we can use custom volume mesh to shape the light. // // See "Deferred Shading Optimizations" in GDC2011 _updateLightProxy: function (light) { var volumeMesh; if (light.volumeMesh) { volumeMesh = light.volumeMesh; } else { switch (light.type) { // Only local light (point and spot) needs volume mesh. // Directional and ambient light renders in full quad case 'POINT_LIGHT': case 'SPHERE_LIGHT': var shader = light.type === 'SPHERE_LIGHT' ? this._sphereLightShader : this._pointLightShader; // Volume mesh created automatically if (!light.__volumeMesh) { light.__volumeMesh = new Mesh({ material: this._createLightPassMat(shader), geometry: this._lightSphereGeo, // Disable culling // if light volume mesh intersect camera near plane // We need mesh inside can still be rendered culling: false }); } volumeMesh = light.__volumeMesh; var r = light.range + (light.radius || 0); volumeMesh.scale.set(r, r, r); break; case 'SPOT_LIGHT': light.__volumeMesh = light.__volumeMesh || new Mesh({ material: this._createLightPassMat(this._spotLightShader), geometry: this._lightConeGeo, culling: false }); volumeMesh = light.__volumeMesh; var aspect = Math.tan(light.penumbraAngle * Math.PI / 180); var range = light.range; volumeMesh.scale.set(aspect * range, aspect * range, range / 2); break; case 'TUBE_LIGHT': light.__volumeMesh = light.__volumeMesh || new Mesh({ material: this._createLightPassMat(this._tubeLightShader), geometry: this._lightCylinderGeo, culling: false }); volumeMesh = light.__volumeMesh; var range = light.range; volumeMesh.scale.set(light.length / 2 + range, range, range); break; } } if (volumeMesh) { volumeMesh.update(); // Apply light transform Matrix4.multiply(volumeMesh.worldTransform, light.worldTransform, volumeMesh.worldTransform); var hasShadow = this.shadowMapPass && light.castShadow; volumeMesh.material[hasShadow ? 'define' : 'undefine']('fragment', 'SHADOWMAP_ENABLED'); } }, _renderVolumeMeshList: (function () { var worldView = new Matrix4(); var preZMaterial = new Material({ shader: new Shader(Shader.source('clay.prez.vertex'), Shader.source('clay.prez.fragment')) }); function getPreZMaterial() { return preZMaterial; } return function (renderer, scene, camera, volumeMeshList) { var gl = renderer.gl; gl.depthFunc(gl.LEQUAL); for (var i = 0; i < volumeMeshList.length; i++) { var volumeMesh = volumeMeshList[i]; // Frustum culling Matrix4.multiply(worldView, camera.viewMatrix, volumeMesh.worldTransform); if (scene.isFrustumCulled(volumeMesh, camera, worldView.array)) { continue; } // Use prez to avoid one pixel rendered twice gl.colorMask(false, false, false, false); gl.depthMask(true); // depthMask must be enabled before clear DEPTH_BUFFER gl.clear(gl.DEPTH_BUFFER_BIT); renderer.renderPass([volumeMesh], camera, { getMaterial: getPreZMaterial }); // Render light gl.colorMask(true, true, true, true); volumeMesh.material.depthMask = true; renderer.renderPass([volumeMesh], camera); } gl.depthFunc(gl.LESS); }; })(), /** * @param {clay.Renderer} renderer */ dispose: function (renderer) { this._gBuffer.dispose(renderer); this._lightAccumFrameBuffer.dispose(renderer); this._lightAccumTex.dispose(renderer); this._lightConeGeo.dispose(renderer); this._lightCylinderGeo.dispose(renderer); this._lightSphereGeo.dispose(renderer); this._fullQuadPass.dispose(renderer); this._outputPass.dispose(renderer); this._directionalLightMat.dispose(renderer); this.shadowMapPass.dispose(renderer); } }); /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 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. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ /** * @class 2x2 Matrix * @name mat2 */ var mat2 = {}; /** * Creates a new identity mat2 * * @returns {mat2} a new 2x2 matrix */ mat2.create = function() { var out = new GLMAT_ARRAY_TYPE(4); out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 1; return out; }; /** * Creates a new mat2 initialized with values from an existing matrix * * @param {mat2} a matrix to clone * @returns {mat2} a new 2x2 matrix */ mat2.clone = function(a) { var out = new GLMAT_ARRAY_TYPE(4); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; }; /** * Copy the values from one mat2 to another * * @param {mat2} out the receiving matrix * @param {mat2} a the source matrix * @returns {mat2} out */ mat2.copy = function(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; }; /** * Set a mat2 to the identity matrix * * @param {mat2} out the receiving matrix * @returns {mat2} out */ mat2.identity = function(out) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 1; return out; }; /** * Transpose the values of a mat2 * * @param {mat2} out the receiving matrix * @param {mat2} a the source matrix * @returns {mat2} out */ mat2.transpose = function(out, a) { // If we are transposing ourselves we can skip a few steps but have to cache some values if (out === a) { var a1 = a[1]; out[1] = a[2]; out[2] = a1; } else { out[0] = a[0]; out[1] = a[2]; out[2] = a[1]; out[3] = a[3]; } return out; }; /** * Inverts a mat2 * * @param {mat2} out the receiving matrix * @param {mat2} a the source matrix * @returns {mat2} out */ mat2.invert = function(out, a) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], // Calculate the determinant det = a0 * a3 - a2 * a1; if (!det) { return null; } det = 1.0 / det; out[0] = a3 * det; out[1] = -a1 * det; out[2] = -a2 * det; out[3] = a0 * det; return out; }; /** * Calculates the adjugate of a mat2 * * @param {mat2} out the receiving matrix * @param {mat2} a the source matrix * @returns {mat2} out */ mat2.adjoint = function(out, a) { // Caching this value is nessecary if out == a var a0 = a[0]; out[0] = a[3]; out[1] = -a[1]; out[2] = -a[2]; out[3] = a0; return out; }; /** * Calculates the determinant of a mat2 * * @param {mat2} a the source matrix * @returns {Number} determinant of a */ mat2.determinant = function (a) { return a[0] * a[3] - a[2] * a[1]; }; /** * Multiplies two mat2's * * @param {mat2} out the receiving matrix * @param {mat2} a the first operand * @param {mat2} b the second operand * @returns {mat2} out */ mat2.multiply = function (out, a, b) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; out[0] = a0 * b0 + a2 * b1; out[1] = a1 * b0 + a3 * b1; out[2] = a0 * b2 + a2 * b3; out[3] = a1 * b2 + a3 * b3; return out; }; /** * Alias for {@link mat2.multiply} * @function */ mat2.mul = mat2.multiply; /** * Rotates a mat2 by the given angle * * @param {mat2} out the receiving matrix * @param {mat2} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat2} out */ mat2.rotate = function (out, a, rad) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], s = Math.sin(rad), c = Math.cos(rad); out[0] = a0 * c + a2 * s; out[1] = a1 * c + a3 * s; out[2] = a0 * -s + a2 * c; out[3] = a1 * -s + a3 * c; return out; }; /** * Scales the mat2 by the dimensions in the given vec2 * * @param {mat2} out the receiving matrix * @param {mat2} a the matrix to rotate * @param {vec2} v the vec2 to scale the matrix by * @returns {mat2} out **/ mat2.scale = function(out, a, v) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], v0 = v[0], v1 = v[1]; out[0] = a0 * v0; out[1] = a1 * v0; out[2] = a2 * v1; out[3] = a3 * v1; return out; }; /** * Returns Frobenius norm of a mat2 * * @param {mat2} a the matrix to calculate Frobenius norm of * @returns {Number} Frobenius norm */ mat2.frob = function (a) { return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2))) }; /** * Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix * @param {mat2} L the lower triangular matrix * @param {mat2} D the diagonal matrix * @param {mat2} U the upper triangular matrix * @param {mat2} a the input matrix to factorize */ mat2.LDU = function (L, D, U, a) { L[2] = a[2]/a[0]; U[0] = a[0]; U[1] = a[1]; U[3] = a[3] - L[2] * U[1]; return [L, D, U]; }; /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 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. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ /** * @class 2x3 Matrix * @name mat2d * * @description * A mat2d contains six elements defined as: *
 * [a, c, tx,
 *  b, d, ty]
 * 
* This is a short form for the 3x3 matrix: *
 * [a, c, tx,
 *  b, d, ty,
 *  0, 0, 1]
 * 
* The last row is ignored so the array is shorter and operations are faster. */ var mat2d = {}; /** * Creates a new identity mat2d * * @returns {mat2d} a new 2x3 matrix */ mat2d.create = function() { var out = new GLMAT_ARRAY_TYPE(6); out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 1; out[4] = 0; out[5] = 0; return out; }; /** * Creates a new mat2d initialized with values from an existing matrix * * @param {mat2d} a matrix to clone * @returns {mat2d} a new 2x3 matrix */ mat2d.clone = function(a) { var out = new GLMAT_ARRAY_TYPE(6); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; return out; }; /** * Copy the values from one mat2d to another * * @param {mat2d} out the receiving matrix * @param {mat2d} a the source matrix * @returns {mat2d} out */ mat2d.copy = function(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; return out; }; /** * Set a mat2d to the identity matrix * * @param {mat2d} out the receiving matrix * @returns {mat2d} out */ mat2d.identity = function(out) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 1; out[4] = 0; out[5] = 0; return out; }; /** * Inverts a mat2d * * @param {mat2d} out the receiving matrix * @param {mat2d} a the source matrix * @returns {mat2d} out */ mat2d.invert = function(out, a) { var aa = a[0], ab = a[1], ac = a[2], ad = a[3], atx = a[4], aty = a[5]; var det = aa * ad - ab * ac; if(!det){ return null; } det = 1.0 / det; out[0] = ad * det; out[1] = -ab * det; out[2] = -ac * det; out[3] = aa * det; out[4] = (ac * aty - ad * atx) * det; out[5] = (ab * atx - aa * aty) * det; return out; }; /** * Calculates the determinant of a mat2d * * @param {mat2d} a the source matrix * @returns {Number} determinant of a */ mat2d.determinant = function (a) { return a[0] * a[3] - a[1] * a[2]; }; /** * Multiplies two mat2d's * * @param {mat2d} out the receiving matrix * @param {mat2d} a the first operand * @param {mat2d} b the second operand * @returns {mat2d} out */ mat2d.multiply = function (out, a, b) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5]; out[0] = a0 * b0 + a2 * b1; out[1] = a1 * b0 + a3 * b1; out[2] = a0 * b2 + a2 * b3; out[3] = a1 * b2 + a3 * b3; out[4] = a0 * b4 + a2 * b5 + a4; out[5] = a1 * b4 + a3 * b5 + a5; return out; }; /** * Alias for {@link mat2d.multiply} * @function */ mat2d.mul = mat2d.multiply; /** * Rotates a mat2d by the given angle * * @param {mat2d} out the receiving matrix * @param {mat2d} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat2d} out */ mat2d.rotate = function (out, a, rad) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], s = Math.sin(rad), c = Math.cos(rad); out[0] = a0 * c + a2 * s; out[1] = a1 * c + a3 * s; out[2] = a0 * -s + a2 * c; out[3] = a1 * -s + a3 * c; out[4] = a4; out[5] = a5; return out; }; /** * Scales the mat2d by the dimensions in the given vec2 * * @param {mat2d} out the receiving matrix * @param {mat2d} a the matrix to translate * @param {vec2} v the vec2 to scale the matrix by * @returns {mat2d} out **/ mat2d.scale = function(out, a, v) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], v0 = v[0], v1 = v[1]; out[0] = a0 * v0; out[1] = a1 * v0; out[2] = a2 * v1; out[3] = a3 * v1; out[4] = a4; out[5] = a5; return out; }; /** * Translates the mat2d by the dimensions in the given vec2 * * @param {mat2d} out the receiving matrix * @param {mat2d} a the matrix to translate * @param {vec2} v the vec2 to translate the matrix by * @returns {mat2d} out **/ mat2d.translate = function(out, a, v) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], v0 = v[0], v1 = v[1]; out[0] = a0; out[1] = a1; out[2] = a2; out[3] = a3; out[4] = a0 * v0 + a2 * v1 + a4; out[5] = a1 * v0 + a3 * v1 + a5; return out; }; /** * Returns Frobenius norm of a mat2d * * @param {mat2d} a the matrix to calculate Frobenius norm of * @returns {Number} Frobenius norm */ mat2d.frob = function (a) { return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + 1)) }; /** * @fileoverview gl-matrix - High performance matrix and vector operations * @author Brandon Jones * @author Colin MacKenzie IV * @version 2.2.2 */ /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 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. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ var glmatrix = { vec2: vec2, vec3: vec3, vec4: vec4, mat2: mat2, mat2d: mat2d, mat3: mat3, mat4: mat4, quat: quat }; // DEPRECATED /** * @constructor clay.light.Sphere * @extends {clay.Light} */ var SphereLight = Light.extend( /** @lends clay.light.Sphere# */ { /** * @type {number} */ range: 100, /** * @type {number} */ radius: 5 }, { type: 'SPHERE_LIGHT', uniformTemplates: { sphereLightPosition: { type: '3f', value: function(instance) { return instance.getWorldPosition().array; } }, sphereLightRange: { type: '1f', value: function(instance) { return instance.range; } }, sphereLightRadius: { type: '1f', value: function(instance) { return instance.radius; } }, sphereLightColor: { type: '3f', value: function(instance) { var color = instance.color; var intensity = instance.intensity; return [color[0]*intensity, color[1]*intensity, color[2]*intensity]; } } } }); /** * @constructor clay.light.Tube * @extends {clay.Light} */ var TubeLight = Light.extend( /** @lends clay.light.Tube# */ { /** * @type {number} */ range: 100, /** * @type {number} */ length: 10 }, { type: 'TUBE_LIGHT', uniformTemplates: { tubeLightPosition: { type: '3f', value: function(instance) { return instance.getWorldPosition().array; } }, tubeLightExtend: { type: '3f', value: (function() { var x = new Vector3(); return function(instance) { // Extend in x axis return x.copy(instance.worldTransform.x) .normalize().scale(instance.length / 2).array; }; })() }, tubeLightRange: { type: '1f', value: function(instance) { return instance.range; } }, tubeLightColor: { type: '3f', value: function(instance) { var color = instance.color; var intensity = instance.intensity; return [color[0]*intensity, color[1]*intensity, color[2]*intensity]; } } } }); /** * @constructor clay.loader.FX * @extends clay.core.Base */ var FXLoader = Base.extend(/** @lends clay.loader.FX# */ { /** * @type {string} */ rootPath: '', /** * @type {string} */ textureRootPath: '', /** * @type {string} */ shaderRootPath: '', /** * @type {clay.Scene} */ scene: null, /** * @type {clay.Camera} */ camera: null }, /** @lends clay.loader.FX.prototype */ { /** * @param {string} url */ load: function(url) { var self = this; if (!this.rootPath) { this.rootPath = url.slice(0, url.lastIndexOf('/')); } vendor.request.get({ url: url, onprogress: function(percent, loaded, total) { self.trigger('progress', percent, loaded, total); }, onerror: function(e) { self.trigger('error', e); }, responseType: 'text', onload: function (data) { createCompositor(JSON.parse(data), { textureRootPath: this.textureRootPath || this.rootPath, camera: this.camera, scene: this.scene }); } }); } }); /** * @constructor * @alias clay.Matrix2 */ var Matrix2 = function() { /** * Storage of Matrix2 * @name array * @type {Float32Array} * @memberOf clay.Matrix2# */ this.array = mat2.create(); /** * @name _dirty * @type {boolean} * @memberOf clay.Matrix2# */ this._dirty = true; }; Matrix2.prototype = { constructor: Matrix2, /** * Set components from array * @param {Float32Array|number[]} arr */ setArray: function (arr) { for (var i = 0; i < this.array.length; i++) { this.array[i] = arr[i]; } this._dirty = true; return this; }, /** * Clone a new Matrix2 * @return {clay.Matrix2} */ clone: function() { return (new Matrix2()).copy(this); }, /** * Copy from b * @param {clay.Matrix2} b * @return {clay.Matrix2} */ copy: function(b) { mat2.copy(this.array, b.array); this._dirty = true; return this; }, /** * Calculate the adjugate of self, in-place * @return {clay.Matrix2} */ adjoint: function() { mat2.adjoint(this.array, this.array); this._dirty = true; return this; }, /** * Calculate matrix determinant * @return {number} */ determinant: function() { return mat2.determinant(this.array); }, /** * Set to a identity matrix * @return {clay.Matrix2} */ identity: function() { mat2.identity(this.array); this._dirty = true; return this; }, /** * Invert self * @return {clay.Matrix2} */ invert: function() { mat2.invert(this.array, this.array); this._dirty = true; return this; }, /** * Alias for mutiply * @param {clay.Matrix2} b * @return {clay.Matrix2} */ mul: function(b) { mat2.mul(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Alias for multiplyLeft * @param {clay.Matrix2} a * @return {clay.Matrix2} */ mulLeft: function(a) { mat2.mul(this.array, a.array, this.array); this._dirty = true; return this; }, /** * Multiply self and b * @param {clay.Matrix2} b * @return {clay.Matrix2} */ multiply: function(b) { mat2.multiply(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Multiply a and self, a is on the left * @param {clay.Matrix2} a * @return {clay.Matrix2} */ multiplyLeft: function(a) { mat2.multiply(this.array, a.array, this.array); this._dirty = true; return this; }, /** * Rotate self by a given radian * @param {number} rad * @return {clay.Matrix2} */ rotate: function(rad) { mat2.rotate(this.array, this.array, rad); this._dirty = true; return this; }, /** * Scale self by s * @param {clay.Vector2} s * @return {clay.Matrix2} */ scale: function(v) { mat2.scale(this.array, this.array, v.array); this._dirty = true; return this; }, /** * Transpose self, in-place. * @return {clay.Matrix2} */ transpose: function() { mat2.transpose(this.array, this.array); this._dirty = true; return this; }, toString: function() { return '[' + Array.prototype.join.call(this.array, ',') + ']'; }, toArray: function () { return Array.prototype.slice.call(this.array); } }; /** * @param {Matrix2} out * @param {Matrix2} a * @return {Matrix2} */ Matrix2.adjoint = function(out, a) { mat2.adjoint(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix2} out * @param {clay.Matrix2} a * @return {clay.Matrix2} */ Matrix2.copy = function(out, a) { mat2.copy(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix2} a * @return {number} */ Matrix2.determinant = function(a) { return mat2.determinant(a.array); }; /** * @param {clay.Matrix2} out * @return {clay.Matrix2} */ Matrix2.identity = function(out) { mat2.identity(out.array); out._dirty = true; return out; }; /** * @param {clay.Matrix2} out * @param {clay.Matrix2} a * @return {clay.Matrix2} */ Matrix2.invert = function(out, a) { mat2.invert(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix2} out * @param {clay.Matrix2} a * @param {clay.Matrix2} b * @return {clay.Matrix2} */ Matrix2.mul = function(out, a, b) { mat2.mul(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Matrix2} out * @param {clay.Matrix2} a * @param {clay.Matrix2} b * @return {clay.Matrix2} */ Matrix2.multiply = Matrix2.mul; /** * @param {clay.Matrix2} out * @param {clay.Matrix2} a * @param {number} rad * @return {clay.Matrix2} */ Matrix2.rotate = function(out, a, rad) { mat2.rotate(out.array, a.array, rad); out._dirty = true; return out; }; /** * @param {clay.Matrix2} out * @param {clay.Matrix2} a * @param {clay.Vector2} v * @return {clay.Matrix2} */ Matrix2.scale = function(out, a, v) { mat2.scale(out.array, a.array, v.array); out._dirty = true; return out; }; /** * @param {Matrix2} out * @param {Matrix2} a * @return {Matrix2} */ Matrix2.transpose = function(out, a) { mat2.transpose(out.array, a.array); out._dirty = true; return out; }; /** * @constructor * @alias clay.Matrix2d */ var Matrix2d = function() { /** * Storage of Matrix2d * @name array * @type {Float32Array} * @memberOf clay.Matrix2d# */ this.array = mat2d.create(); /** * @name _dirty * @type {boolean} * @memberOf clay.Matrix2d# */ this._dirty = true; }; Matrix2d.prototype = { constructor: Matrix2d, /** * Set components from array * @param {Float32Array|number[]} arr */ setArray: function (arr) { for (var i = 0; i < this.array.length; i++) { this.array[i] = arr[i]; } this._dirty = true; return this; }, /** * Clone a new Matrix2d * @return {clay.Matrix2d} */ clone: function() { return (new Matrix2d()).copy(this); }, /** * Copy from b * @param {clay.Matrix2d} b * @return {clay.Matrix2d} */ copy: function(b) { mat2d.copy(this.array, b.array); this._dirty = true; return this; }, /** * Calculate matrix determinant * @return {number} */ determinant: function() { return mat2d.determinant(this.array); }, /** * Set to a identity matrix * @return {clay.Matrix2d} */ identity: function() { mat2d.identity(this.array); this._dirty = true; return this; }, /** * Invert self * @return {clay.Matrix2d} */ invert: function() { mat2d.invert(this.array, this.array); this._dirty = true; return this; }, /** * Alias for mutiply * @param {clay.Matrix2d} b * @return {clay.Matrix2d} */ mul: function(b) { mat2d.mul(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Alias for multiplyLeft * @param {clay.Matrix2d} a * @return {clay.Matrix2d} */ mulLeft: function(b) { mat2d.mul(this.array, b.array, this.array); this._dirty = true; return this; }, /** * Multiply self and b * @param {clay.Matrix2d} b * @return {clay.Matrix2d} */ multiply: function(b) { mat2d.multiply(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Multiply a and self, a is on the left * @param {clay.Matrix2d} a * @return {clay.Matrix2d} */ multiplyLeft: function(b) { mat2d.multiply(this.array, b.array, this.array); this._dirty = true; return this; }, /** * Rotate self by a given radian * @param {number} rad * @return {clay.Matrix2d} */ rotate: function(rad) { mat2d.rotate(this.array, this.array, rad); this._dirty = true; return this; }, /** * Scale self by s * @param {clay.Vector2} s * @return {clay.Matrix2d} */ scale: function(s) { mat2d.scale(this.array, this.array, s.array); this._dirty = true; return this; }, /** * Translate self by v * @param {clay.Vector2} v * @return {clay.Matrix2d} */ translate: function(v) { mat2d.translate(this.array, this.array, v.array); this._dirty = true; return this; }, toString: function() { return '[' + Array.prototype.join.call(this.array, ',') + ']'; }, toArray: function () { return Array.prototype.slice.call(this.array); } }; /** * @param {clay.Matrix2d} out * @param {clay.Matrix2d} a * @return {clay.Matrix2d} */ Matrix2d.copy = function(out, a) { mat2d.copy(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix2d} a * @return {number} */ Matrix2d.determinant = function(a) { return mat2d.determinant(a.array); }; /** * @param {clay.Matrix2d} out * @return {clay.Matrix2d} */ Matrix2d.identity = function(out) { mat2d.identity(out.array); out._dirty = true; return out; }; /** * @param {clay.Matrix2d} out * @param {clay.Matrix2d} a * @return {clay.Matrix2d} */ Matrix2d.invert = function(out, a) { mat2d.invert(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix2d} out * @param {clay.Matrix2d} a * @param {clay.Matrix2d} b * @return {clay.Matrix2d} */ Matrix2d.mul = function(out, a, b) { mat2d.mul(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Matrix2d} out * @param {clay.Matrix2d} a * @param {clay.Matrix2d} b * @return {clay.Matrix2d} */ Matrix2d.multiply = Matrix2d.mul; /** * @param {clay.Matrix2d} out * @param {clay.Matrix2d} a * @param {number} rad * @return {clay.Matrix2d} */ Matrix2d.rotate = function(out, a, rad) { mat2d.rotate(out.array, a.array, rad); out._dirty = true; return out; }; /** * @param {clay.Matrix2d} out * @param {clay.Matrix2d} a * @param {clay.Vector2} v * @return {clay.Matrix2d} */ Matrix2d.scale = function(out, a, v) { mat2d.scale(out.array, a.array, v.array); out._dirty = true; return out; }; /** * @param {clay.Matrix2d} out * @param {clay.Matrix2d} a * @param {clay.Vector2} v * @return {clay.Matrix2d} */ Matrix2d.translate = function(out, a, v) { mat2d.translate(out.array, a.array, v.array); out._dirty = true; return out; }; /** * @constructor * @alias clay.Matrix3 */ var Matrix3 = function () { /** * Storage of Matrix3 * @name array * @type {Float32Array} * @memberOf clay.Matrix3# */ this.array = mat3.create(); /** * @name _dirty * @type {boolean} * @memberOf clay.Matrix3# */ this._dirty = true; }; Matrix3.prototype = { constructor: Matrix3, /** * Set components from array * @param {Float32Array|number[]} arr */ setArray: function (arr) { for (var i = 0; i < this.array.length; i++) { this.array[i] = arr[i]; } this._dirty = true; return this; }, /** * Calculate the adjugate of self, in-place * @return {clay.Matrix3} */ adjoint: function () { mat3.adjoint(this.array, this.array); this._dirty = true; return this; }, /** * Clone a new Matrix3 * @return {clay.Matrix3} */ clone: function () { return (new Matrix3()).copy(this); }, /** * Copy from b * @param {clay.Matrix3} b * @return {clay.Matrix3} */ copy: function (b) { mat3.copy(this.array, b.array); this._dirty = true; return this; }, /** * Calculate matrix determinant * @return {number} */ determinant: function () { return mat3.determinant(this.array); }, /** * Copy the values from Matrix2d a * @param {clay.Matrix2d} a * @return {clay.Matrix3} */ fromMat2d: function (a) { mat3.fromMat2d(this.array, a.array); this._dirty = true; return this; }, /** * Copies the upper-left 3x3 values of Matrix4 * @param {clay.Matrix4} a * @return {clay.Matrix3} */ fromMat4: function (a) { mat3.fromMat4(this.array, a.array); this._dirty = true; return this; }, /** * Calculates a rotation matrix from the given quaternion * @param {clay.Quaternion} q * @return {clay.Matrix3} */ fromQuat: function (q) { mat3.fromQuat(this.array, q.array); this._dirty = true; return this; }, /** * Set to a identity matrix * @return {clay.Matrix3} */ identity: function () { mat3.identity(this.array); this._dirty = true; return this; }, /** * Invert self * @return {clay.Matrix3} */ invert: function () { mat3.invert(this.array, this.array); this._dirty = true; return this; }, /** * Alias for mutiply * @param {clay.Matrix3} b * @return {clay.Matrix3} */ mul: function (b) { mat3.mul(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Alias for multiplyLeft * @param {clay.Matrix3} a * @return {clay.Matrix3} */ mulLeft: function (a) { mat3.mul(this.array, a.array, this.array); this._dirty = true; return this; }, /** * Multiply self and b * @param {clay.Matrix3} b * @return {clay.Matrix3} */ multiply: function (b) { mat3.multiply(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Multiply a and self, a is on the left * @param {clay.Matrix3} a * @return {clay.Matrix3} */ multiplyLeft: function (a) { mat3.multiply(this.array, a.array, this.array); this._dirty = true; return this; }, /** * Rotate self by a given radian * @param {number} rad * @return {clay.Matrix3} */ rotate: function (rad) { mat3.rotate(this.array, this.array, rad); this._dirty = true; return this; }, /** * Scale self by s * @param {clay.Vector2} s * @return {clay.Matrix3} */ scale: function (v) { mat3.scale(this.array, this.array, v.array); this._dirty = true; return this; }, /** * Translate self by v * @param {clay.Vector2} v * @return {clay.Matrix3} */ translate: function (v) { mat3.translate(this.array, this.array, v.array); this._dirty = true; return this; }, /** * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix * @param {clay.Matrix4} a */ normalFromMat4: function (a) { mat3.normalFromMat4(this.array, a.array); this._dirty = true; return this; }, /** * Transpose self, in-place. * @return {clay.Matrix2} */ transpose: function () { mat3.transpose(this.array, this.array); this._dirty = true; return this; }, toString: function () { return '[' + Array.prototype.join.call(this.array, ',') + ']'; }, toArray: function () { return Array.prototype.slice.call(this.array); } }; /** * @param {clay.Matrix3} out * @param {clay.Matrix3} a * @return {clay.Matrix3} */ Matrix3.adjoint = function (out, a) { mat3.adjoint(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix3} out * @param {clay.Matrix3} a * @return {clay.Matrix3} */ Matrix3.copy = function (out, a) { mat3.copy(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix3} a * @return {number} */ Matrix3.determinant = function (a) { return mat3.determinant(a.array); }; /** * @param {clay.Matrix3} out * @return {clay.Matrix3} */ Matrix3.identity = function (out) { mat3.identity(out.array); out._dirty = true; return out; }; /** * @param {clay.Matrix3} out * @param {clay.Matrix3} a * @return {clay.Matrix3} */ Matrix3.invert = function (out, a) { mat3.invert(out.array, a.array); return out; }; /** * @param {clay.Matrix3} out * @param {clay.Matrix3} a * @param {clay.Matrix3} b * @return {clay.Matrix3} */ Matrix3.mul = function (out, a, b) { mat3.mul(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Matrix3} out * @param {clay.Matrix3} a * @param {clay.Matrix3} b * @return {clay.Matrix3} */ Matrix3.multiply = Matrix3.mul; /** * @param {clay.Matrix3} out * @param {clay.Matrix2d} a * @return {clay.Matrix3} */ Matrix3.fromMat2d = function (out, a) { mat3.fromMat2d(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix3} out * @param {clay.Matrix4} a * @return {clay.Matrix3} */ Matrix3.fromMat4 = function (out, a) { mat3.fromMat4(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix3} out * @param {clay.Quaternion} a * @return {clay.Matrix3} */ Matrix3.fromQuat = function (out, q) { mat3.fromQuat(out.array, q.array); out._dirty = true; return out; }; /** * @param {clay.Matrix3} out * @param {clay.Matrix4} a * @return {clay.Matrix3} */ Matrix3.normalFromMat4 = function (out, a) { mat3.normalFromMat4(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix3} out * @param {clay.Matrix3} a * @param {number} rad * @return {clay.Matrix3} */ Matrix3.rotate = function (out, a, rad) { mat3.rotate(out.array, a.array, rad); out._dirty = true; return out; }; /** * @param {clay.Matrix3} out * @param {clay.Matrix3} a * @param {clay.Vector2} v * @return {clay.Matrix3} */ Matrix3.scale = function (out, a, v) { mat3.scale(out.array, a.array, v.array); out._dirty = true; return out; }; /** * @param {clay.Matrix3} out * @param {clay.Matrix3} a * @return {clay.Matrix3} */ Matrix3.transpose = function (out, a) { mat3.transpose(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Matrix3} out * @param {clay.Matrix3} a * @param {clay.Vector2} v * @return {clay.Matrix3} */ Matrix3.translate = function (out, a, v) { mat3.translate(out.array, a.array, v.array); out._dirty = true; return out; }; /** * Random or constant 1d, 2d, 3d vector generator * @constructor * @alias clay.Value */ var Value = function() {}; /** * @function * @param {number|clay.Vector2|clay.Vector3} [out] * @return {number|clay.Vector2|clay.Vector3} */ Value.prototype.get = function(out) {}; // Constant var ConstantValue = function(val) { this.get = function() { return val; }; }; ConstantValue.prototype = new Value(); ConstantValue.prototype.constructor = ConstantValue; // Vector var VectorValue = function(val) { var Constructor = val.constructor; this.get = function(out) { if (!out) { out = new Constructor(); } out.copy(val); return out; }; }; VectorValue.prototype = new Value(); VectorValue.prototype.constructor = VectorValue; //Random 1D var Random1D = function(min, max) { var range = max - min; this.get = function() { return Math.random() * range + min; }; }; Random1D.prototype = new Value(); Random1D.prototype.constructor = Random1D; // Random2D var Random2D = function(min, max) { var rangeX = max.x - min.x; var rangeY = max.y - min.y; this.get = function(out) { if (!out) { out = new Vector2(); } Vector2.set( out, rangeX * Math.random() + min.array[0], rangeY * Math.random() + min.array[1] ); return out; }; }; Random2D.prototype = new Value(); Random2D.prototype.constructor = Random2D; var Random3D = function(min, max) { var rangeX = max.x - min.x; var rangeY = max.y - min.y; var rangeZ = max.z - min.z; this.get = function(out) { if (!out) { out = new Vector3(); } Vector3.set( out, rangeX * Math.random() + min.array[0], rangeY * Math.random() + min.array[1], rangeZ * Math.random() + min.array[2] ); return out; }; }; Random3D.prototype = new Value(); Random3D.prototype.constructor = Random3D; // Factory methods /** * Create a constant 1d value generator * @param {number} constant * @return {clay.Value} */ Value.constant = function(constant) { return new ConstantValue(constant); }; /** * Create a constant vector value(2d or 3d) generator * @param {clay.Vector2|clay.Vector3} vector * @return {clay.Value} */ Value.vector = function(vector) { return new VectorValue(vector); }; /** * Create a random 1d value generator * @param {number} min * @param {number} max * @return {clay.Value} */ Value.random1D = function(min, max) { return new Random1D(min, max); }; /** * Create a random 2d value generator * @param {clay.Vector2} min * @param {clay.Vector2} max * @return {clay.Value} */ Value.random2D = function(min, max) { return new Random2D(min, max); }; /** * Create a random 3d value generator * @param {clay.Vector3} min * @param {clay.Vector3} max * @return {clay.Value} */ Value.random3D = function(min, max) { return new Random3D(min, max); }; /** * @constructor * @alias clay.Vector4 * @param {number} x * @param {number} y * @param {number} z * @param {number} w */ var Vector4 = function(x, y, z, w) { x = x || 0; y = y || 0; z = z || 0; w = w || 0; /** * Storage of Vector4, read and write of x, y, z, w will change the values in array * All methods also operate on the array instead of x, y, z, w components * @name array * @type {Float32Array} * @memberOf clay.Vector4# */ this.array = vec4.fromValues(x, y, z, w); /** * Dirty flag is used by the Node to determine * if the matrix is updated to latest * @name _dirty * @type {boolean} * @memberOf clay.Vector4# */ this._dirty = true; }; Vector4.prototype = { constructor: Vector4, /** * Add b to self * @param {clay.Vector4} b * @return {clay.Vector4} */ add: function(b) { vec4.add(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Set x, y and z components * @param {number} x * @param {number} y * @param {number} z * @param {number} w * @return {clay.Vector4} */ set: function(x, y, z, w) { this.array[0] = x; this.array[1] = y; this.array[2] = z; this.array[3] = w; this._dirty = true; return this; }, /** * Set x, y, z and w components from array * @param {Float32Array|number[]} arr * @return {clay.Vector4} */ setArray: function(arr) { this.array[0] = arr[0]; this.array[1] = arr[1]; this.array[2] = arr[2]; this.array[3] = arr[3]; this._dirty = true; return this; }, /** * Clone a new Vector4 * @return {clay.Vector4} */ clone: function() { return new Vector4(this.x, this.y, this.z, this.w); }, /** * Copy from b * @param {clay.Vector4} b * @return {clay.Vector4} */ copy: function(b) { vec4.copy(this.array, b.array); this._dirty = true; return this; }, /** * Alias for distance * @param {clay.Vector4} b * @return {number} */ dist: function(b) { return vec4.dist(this.array, b.array); }, /** * Distance between self and b * @param {clay.Vector4} b * @return {number} */ distance: function(b) { return vec4.distance(this.array, b.array); }, /** * Alias for divide * @param {clay.Vector4} b * @return {clay.Vector4} */ div: function(b) { vec4.div(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Divide self by b * @param {clay.Vector4} b * @return {clay.Vector4} */ divide: function(b) { vec4.divide(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Dot product of self and b * @param {clay.Vector4} b * @return {number} */ dot: function(b) { return vec4.dot(this.array, b.array); }, /** * Alias of length * @return {number} */ len: function() { return vec4.len(this.array); }, /** * Calculate the length * @return {number} */ length: function() { return vec4.length(this.array); }, /** * Linear interpolation between a and b * @param {clay.Vector4} a * @param {clay.Vector4} b * @param {number} t * @return {clay.Vector4} */ lerp: function(a, b, t) { vec4.lerp(this.array, a.array, b.array, t); this._dirty = true; return this; }, /** * Minimum of self and b * @param {clay.Vector4} b * @return {clay.Vector4} */ min: function(b) { vec4.min(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Maximum of self and b * @param {clay.Vector4} b * @return {clay.Vector4} */ max: function(b) { vec4.max(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Alias for multiply * @param {clay.Vector4} b * @return {clay.Vector4} */ mul: function(b) { vec4.mul(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Mutiply self and b * @param {clay.Vector4} b * @return {clay.Vector4} */ multiply: function(b) { vec4.multiply(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Negate self * @return {clay.Vector4} */ negate: function() { vec4.negate(this.array, this.array); this._dirty = true; return this; }, /** * Normalize self * @return {clay.Vector4} */ normalize: function() { vec4.normalize(this.array, this.array); this._dirty = true; return this; }, /** * Generate random x, y, z, w components with a given scale * @param {number} scale * @return {clay.Vector4} */ random: function(scale) { vec4.random(this.array, scale); this._dirty = true; return this; }, /** * Scale self * @param {number} scale * @return {clay.Vector4} */ scale: function(s) { vec4.scale(this.array, this.array, s); this._dirty = true; return this; }, /** * Scale b and add to self * @param {clay.Vector4} b * @param {number} scale * @return {clay.Vector4} */ scaleAndAdd: function(b, s) { vec4.scaleAndAdd(this.array, this.array, b.array, s); this._dirty = true; return this; }, /** * Alias for squaredDistance * @param {clay.Vector4} b * @return {number} */ sqrDist: function(b) { return vec4.sqrDist(this.array, b.array); }, /** * Squared distance between self and b * @param {clay.Vector4} b * @return {number} */ squaredDistance: function(b) { return vec4.squaredDistance(this.array, b.array); }, /** * Alias for squaredLength * @return {number} */ sqrLen: function() { return vec4.sqrLen(this.array); }, /** * Squared length of self * @return {number} */ squaredLength: function() { return vec4.squaredLength(this.array); }, /** * Alias for subtract * @param {clay.Vector4} b * @return {clay.Vector4} */ sub: function(b) { vec4.sub(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Subtract b from self * @param {clay.Vector4} b * @return {clay.Vector4} */ subtract: function(b) { vec4.subtract(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Transform self with a Matrix4 m * @param {clay.Matrix4} m * @return {clay.Vector4} */ transformMat4: function(m) { vec4.transformMat4(this.array, this.array, m.array); this._dirty = true; return this; }, /** * Transform self with a Quaternion q * @param {clay.Quaternion} q * @return {clay.Vector4} */ transformQuat: function(q) { vec4.transformQuat(this.array, this.array, q.array); this._dirty = true; return this; }, toString: function() { return '[' + Array.prototype.join.call(this.array, ',') + ']'; }, toArray: function () { return Array.prototype.slice.call(this.array); } }; var defineProperty$3 = Object.defineProperty; // Getter and Setter if (defineProperty$3) { var proto$4 = Vector4.prototype; /** * @name x * @type {number} * @memberOf clay.Vector4 * @instance */ defineProperty$3(proto$4, 'x', { get: function () { return this.array[0]; }, set: function (value) { this.array[0] = value; this._dirty = true; } }); /** * @name y * @type {number} * @memberOf clay.Vector4 * @instance */ defineProperty$3(proto$4, 'y', { get: function () { return this.array[1]; }, set: function (value) { this.array[1] = value; this._dirty = true; } }); /** * @name z * @type {number} * @memberOf clay.Vector4 * @instance */ defineProperty$3(proto$4, 'z', { get: function () { return this.array[2]; }, set: function (value) { this.array[2] = value; this._dirty = true; } }); /** * @name w * @type {number} * @memberOf clay.Vector4 * @instance */ defineProperty$3(proto$4, 'w', { get: function () { return this.array[3]; }, set: function (value) { this.array[3] = value; this._dirty = true; } }); } // Supply methods that are not in place /** * @param {clay.Vector4} out * @param {clay.Vector4} a * @param {clay.Vector4} b * @return {clay.Vector4} */ Vector4.add = function(out, a, b) { vec4.add(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector4} out * @param {number} x * @param {number} y * @param {number} z * @return {clay.Vector4} */ Vector4.set = function(out, x, y, z, w) { vec4.set(out.array, x, y, z, w); out._dirty = true; }; /** * @param {clay.Vector4} out * @param {clay.Vector4} b * @return {clay.Vector4} */ Vector4.copy = function(out, b) { vec4.copy(out.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector4} a * @param {clay.Vector4} b * @return {number} */ Vector4.dist = function(a, b) { return vec4.distance(a.array, b.array); }; /** * @function * @param {clay.Vector4} a * @param {clay.Vector4} b * @return {number} */ Vector4.distance = Vector4.dist; /** * @param {clay.Vector4} out * @param {clay.Vector4} a * @param {clay.Vector4} b * @return {clay.Vector4} */ Vector4.div = function(out, a, b) { vec4.divide(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Vector4} out * @param {clay.Vector4} a * @param {clay.Vector4} b * @return {clay.Vector4} */ Vector4.divide = Vector4.div; /** * @param {clay.Vector4} a * @param {clay.Vector4} b * @return {number} */ Vector4.dot = function(a, b) { return vec4.dot(a.array, b.array); }; /** * @param {clay.Vector4} a * @return {number} */ Vector4.len = function(b) { return vec4.length(b.array); }; // Vector4.length = Vector4.len; /** * @param {clay.Vector4} out * @param {clay.Vector4} a * @param {clay.Vector4} b * @param {number} t * @return {clay.Vector4} */ Vector4.lerp = function(out, a, b, t) { vec4.lerp(out.array, a.array, b.array, t); out._dirty = true; return out; }; /** * @param {clay.Vector4} out * @param {clay.Vector4} a * @param {clay.Vector4} b * @return {clay.Vector4} */ Vector4.min = function(out, a, b) { vec4.min(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector4} out * @param {clay.Vector4} a * @param {clay.Vector4} b * @return {clay.Vector4} */ Vector4.max = function(out, a, b) { vec4.max(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector4} out * @param {clay.Vector4} a * @param {clay.Vector4} b * @return {clay.Vector4} */ Vector4.mul = function(out, a, b) { vec4.multiply(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Vector4} out * @param {clay.Vector4} a * @param {clay.Vector4} b * @return {clay.Vector4} */ Vector4.multiply = Vector4.mul; /** * @param {clay.Vector4} out * @param {clay.Vector4} a * @return {clay.Vector4} */ Vector4.negate = function(out, a) { vec4.negate(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Vector4} out * @param {clay.Vector4} a * @return {clay.Vector4} */ Vector4.normalize = function(out, a) { vec4.normalize(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Vector4} out * @param {number} scale * @return {clay.Vector4} */ Vector4.random = function(out, scale) { vec4.random(out.array, scale); out._dirty = true; return out; }; /** * @param {clay.Vector4} out * @param {clay.Vector4} a * @param {number} scale * @return {clay.Vector4} */ Vector4.scale = function(out, a, scale) { vec4.scale(out.array, a.array, scale); out._dirty = true; return out; }; /** * @param {clay.Vector4} out * @param {clay.Vector4} a * @param {clay.Vector4} b * @param {number} scale * @return {clay.Vector4} */ Vector4.scaleAndAdd = function(out, a, b, scale) { vec4.scaleAndAdd(out.array, a.array, b.array, scale); out._dirty = true; return out; }; /** * @param {clay.Vector4} a * @param {clay.Vector4} b * @return {number} */ Vector4.sqrDist = function(a, b) { return vec4.sqrDist(a.array, b.array); }; /** * @function * @param {clay.Vector4} a * @param {clay.Vector4} b * @return {number} */ Vector4.squaredDistance = Vector4.sqrDist; /** * @param {clay.Vector4} a * @return {number} */ Vector4.sqrLen = function(a) { return vec4.sqrLen(a.array); }; /** * @function * @param {clay.Vector4} a * @return {number} */ Vector4.squaredLength = Vector4.sqrLen; /** * @param {clay.Vector4} out * @param {clay.Vector4} a * @param {clay.Vector4} b * @return {clay.Vector4} */ Vector4.sub = function(out, a, b) { vec4.subtract(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Vector4} out * @param {clay.Vector4} a * @param {clay.Vector4} b * @return {clay.Vector4} */ Vector4.subtract = Vector4.sub; /** * @param {clay.Vector4} out * @param {clay.Vector4} a * @param {clay.Matrix4} m * @return {clay.Vector4} */ Vector4.transformMat4 = function(out, a, m) { vec4.transformMat4(out.array, a.array, m.array); out._dirty = true; return out; }; /** * @param {clay.Vector4} out * @param {clay.Vector4} a * @param {clay.Quaternion} q * @return {clay.Vector4} */ Vector4.transformQuat = function(out, a, q) { vec4.transformQuat(out.array, a.array, q.array); out._dirty = true; return out; }; /** * @constructor * @alias clay.particle.Particle */ var Particle = function() { /** * @type {clay.Vector3} */ this.position = new Vector3(); /** * Use euler angle to represent particle rotation * @type {clay.Vector3} */ this.rotation = new Vector3(); /** * @type {?clay.Vector3} */ this.velocity = null; /** * @type {?clay.Vector3} */ this.angularVelocity = null; /** * @type {number} */ this.life = 1; /** * @type {number} */ this.age = 0; /** * @type {number} */ this.spriteSize = 1; /** * @type {number} */ this.weight = 1; /** * @type {clay.particle.Emitter} */ this.emitter = null; }; /** * Update particle position * @param {number} deltaTime */ Particle.prototype.update = function(deltaTime) { if (this.velocity) { vec3.scaleAndAdd(this.position.array, this.position.array, this.velocity.array, deltaTime); } if (this.angularVelocity) { vec3.scaleAndAdd(this.rotation.array, this.rotation.array, this.angularVelocity.array, deltaTime); } }; /** * @constructor clay.particle.Emitter * @extends clay.core.Base */ var Emitter = Base.extend( /** @lends clay.particle.Emitter# */ { /** * Maximum number of particles created by this emitter * @type {number} */ max: 1000, /** * Number of particles created by this emitter each shot * @type {number} */ amount: 20, // Init status for each particle /** * Particle life generator * @type {?clay.Value.} */ life: null, /** * Particle position generator * @type {?clay.Value.} */ position: null, /** * Particle rotation generator * @type {?clay.Value.} */ rotation: null, /** * Particle velocity generator * @type {?clay.Value.} */ velocity: null, /** * Particle angular velocity generator * @type {?clay.Value.} */ angularVelocity: null, /** * Particle sprite size generator * @type {?clay.Value.} */ spriteSize: null, /** * Particle weight generator * @type {?clay.Value.} */ weight: null, _particlePool: null }, function() { this._particlePool = []; // TODO Reduce heap memory for (var i = 0; i < this.max; i++) { var particle = new Particle(); particle.emitter = this; this._particlePool.push(particle); if (this.velocity) { particle.velocity = new Vector3(); } if (this.angularVelocity) { particle.angularVelocity = new Vector3(); } } }, /** @lends clay.particle.Emitter.prototype */ { /** * Emitter number of particles and push them to a given particle list. Emmit number is defined by amount property * @param {Array.} out */ emit: function(out) { var amount = Math.min(this._particlePool.length, this.amount); var particle; for (var i = 0; i < amount; i++) { particle = this._particlePool.pop(); // Initialize particle status if (this.position) { this.position.get(particle.position); } if (this.rotation) { this.rotation.get(particle.rotation); } if (this.velocity) { this.velocity.get(particle.velocity); } if (this.angularVelocity) { this.angularVelocity.get(particle.angularVelocity); } if (this.life) { particle.life = this.life.get(); } if (this.spriteSize) { particle.spriteSize = this.spriteSize.get(); } if (this.weight) { particle.weight = this.weight.get(); } particle.age = 0; out.push(particle); } }, /** * Kill a dead particle and put it back in the pool * @param {clay.particle.Particle} particle */ kill: function(particle) { this._particlePool.push(particle); } }); /** * Create a constant 1d value generator. Alias for {@link clay.Value.constant} * @function clay.particle.Emitter.constant */ Emitter.constant = Value.constant; /** * Create a constant vector value(2d or 3d) generator. Alias for {@link clay.Value.vector} * @function clay.particle.Emitter.vector */ Emitter.vector = Value.vector; /** * Create a random 1d value generator. Alias for {@link clay.Value.random1D} * @function clay.particle.Emitter.random1D */ Emitter.random1D = Value.random1D; /** * Create a random 2d value generator. Alias for {@link clay.Value.random2D} * @function clay.particle.Emitter.random2D */ Emitter.random2D = Value.random2D; /** * Create a random 3d value generator. Alias for {@link clay.Value.random3D} * @function clay.particle.Emitter.random3D */ Emitter.random3D = Value.random3D; /** * @constructor clay.particle.Field * @extends clay.core.Base */ var Field = Base.extend({}, { /** * Apply a field to the particle and update the particle velocity * @param {clay.Vector3} velocity * @param {clay.Vector3} position * @param {number} weight * @param {number} deltaTime * @memberOf clay.particle.Field.prototype */ applyTo: function(velocity, position, weight, deltaTime) {} }); /** * @constructor clay.particle.ForceField * @extends clay.particle.Field */ var ForceField = Field.extend(function() { return { force: new Vector3() }; }, { applyTo: function(velocity, position, weight, deltaTime) { if (weight > 0) { vec3.scaleAndAdd(velocity.array, velocity.array, this.force.array, deltaTime / weight); } } }); var particleEssl = "@export clay.particle.vertex\nuniform mat4 worldView : WORLDVIEW;\nuniform mat4 projection : PROJECTION;\nattribute vec3 position : POSITION;\nattribute vec3 normal : NORMAL;\n#ifdef UV_ANIMATION\nattribute vec2 texcoord0 : TEXCOORD_0;\nattribute vec2 texcoord1 : TEXCOORD_1;\nvarying vec2 v_Uv0;\nvarying vec2 v_Uv1;\n#endif\nvarying float v_Age;\nvoid main() {\n v_Age = normal.x;\n float rotation = normal.y;\n vec4 worldViewPosition = worldView * vec4(position, 1.0);\n gl_Position = projection * worldViewPosition;\n float w = gl_Position.w;\n gl_PointSize = normal.z * projection[0].x / w;\n #ifdef UV_ANIMATION\n v_Uv0 = texcoord0;\n v_Uv1 = texcoord1;\n #endif\n}\n@end\n@export clay.particle.fragment\nuniform sampler2D sprite;\nuniform sampler2D gradient;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform float alpha : 1.0;\nvarying float v_Age;\n#ifdef UV_ANIMATION\nvarying vec2 v_Uv0;\nvarying vec2 v_Uv1;\n#endif\nvoid main() {\n vec4 color = vec4(color, alpha);\n #ifdef SPRITE_ENABLED\n #ifdef UV_ANIMATION\n color *= texture2D(sprite, mix(v_Uv0, v_Uv1, gl_PointCoord));\n #else\n color *= texture2D(sprite, gl_PointCoord);\n #endif\n #endif\n #ifdef GRADIENT_ENABLED\n color *= texture2D(gradient, vec2(v_Age, 0.5));\n #endif\n gl_FragColor = color;\n}\n@end"; Shader['import'](particleEssl); var particleShader = new Shader(Shader.source('clay.particle.vertex'), Shader.source('clay.particle.fragment')); /** * @constructor clay.particle.ParticleRenderable * @extends clay.Renderable * * @example * var particleRenderable = new clay.particle.ParticleRenderable({ * spriteAnimationTileX: 4, * spriteAnimationTileY: 4, * spriteAnimationRepeat: 1 * }); * scene.add(particleRenderable); * // Enable uv animation in the shader * particleRenderable.material.define('both', 'UV_ANIMATION'); * var Emitter = clay.particle.Emitter; * var Vector3 = clay.Vector3; * var emitter = new Emitter({ * max: 2000, * amount: 100, * life: Emitter.random1D(10, 20), * position: Emitter.vector(new Vector3()), * velocity: Emitter.random3D(new Vector3(-10, 0, -10), new Vector3(10, 0, 10)); * }); * particleRenderable.addEmitter(emitter); * var gravityField = new clay.particle.ForceField(); * gravityField.force.y = -10; * particleRenderable.addField(gravityField); * ... * animation.on('frame', function(frameTime) { * particleRenderable.updateParticles(frameTime); * renderer.render(scene, camera); * }); */ var ParticleRenderable = Renderable.extend(/** @lends clay.particle.ParticleRenderable# */ { /** * @type {boolean} */ loop: true, /** * @type {boolean} */ oneshot: false, /** * Duration of particle system in milliseconds * @type {number} */ duration: 1, // UV Animation /** * @type {number} */ spriteAnimationTileX: 1, /** * @type {number} */ spriteAnimationTileY: 1, /** * @type {number} */ spriteAnimationRepeat: 0, mode: Renderable.POINTS, ignorePicking: true, _elapsedTime: 0, _emitting: true }, function(){ this.geometry = new Geometry({ dynamic: true }); if (!this.material) { this.material = new Material({ shader: particleShader, transparent: true, depthMask: false }); this.material.enableTexture('sprite'); } this._particles = []; this._fields = []; this._emitters = []; }, /** @lends clay.particle.ParticleRenderable.prototype */ { culling: false, frustumCulling: false, castShadow: false, receiveShadow: false, /** * Add emitter * @param {clay.particle.Emitter} emitter */ addEmitter: function(emitter) { this._emitters.push(emitter); }, /** * Remove emitter * @param {clay.particle.Emitter} emitter */ removeEmitter: function(emitter) { this._emitters.splice(this._emitters.indexOf(emitter), 1); }, /** * Add field * @param {clay.particle.Field} field */ addField: function(field) { this._fields.push(field); }, /** * Remove field * @param {clay.particle.Field} field */ removeField: function(field) { this._fields.splice(this._fields.indexOf(field), 1); }, /** * Reset the particle system. */ reset: function() { // Put all the particles back for (var i = 0; i < this._particles.length; i++) { var p = this._particles[i]; p.emitter.kill(p); } this._particles.length = 0; this._elapsedTime = 0; this._emitting = true; }, /** * @param {number} deltaTime */ updateParticles: function(deltaTime) { // MS => Seconds deltaTime /= 1000; this._elapsedTime += deltaTime; var particles = this._particles; if (this._emitting) { for (var i = 0; i < this._emitters.length; i++) { this._emitters[i].emit(particles); } if (this.oneshot) { this._emitting = false; } } // Aging var len = particles.length; for (var i = 0; i < len;) { var p = particles[i]; p.age += deltaTime; if (p.age >= p.life) { p.emitter.kill(p); particles[i] = particles[len-1]; particles.pop(); len--; } else { i++; } } for (var i = 0; i < len; i++) { // Update var p = particles[i]; if (this._fields.length > 0) { for (var j = 0; j < this._fields.length; j++) { this._fields[j].applyTo(p.velocity, p.position, p.weight, deltaTime); } } p.update(deltaTime); } this._updateVertices(); }, _updateVertices: function() { var geometry = this.geometry; // If has uv animation var animTileX = this.spriteAnimationTileX; var animTileY = this.spriteAnimationTileY; var animRepeat = this.spriteAnimationRepeat; var nUvAnimFrame = animTileY * animTileX * animRepeat; var hasUvAnimation = nUvAnimFrame > 1; var positions = geometry.attributes.position.value; // Put particle status in normal var normals = geometry.attributes.normal.value; var uvs = geometry.attributes.texcoord0.value; var uvs2 = geometry.attributes.texcoord1.value; var len = this._particles.length; if (!positions || positions.length !== len * 3) { // TODO Optimize positions = geometry.attributes.position.value = new Float32Array(len * 3); normals = geometry.attributes.normal.value = new Float32Array(len * 3); if (hasUvAnimation) { uvs = geometry.attributes.texcoord0.value = new Float32Array(len * 2); uvs2 = geometry.attributes.texcoord1.value = new Float32Array(len * 2); } } var invAnimTileX = 1 / animTileX; for (var i = 0; i < len; i++) { var particle = this._particles[i]; var offset = i * 3; for (var j = 0; j < 3; j++) { positions[offset + j] = particle.position.array[j]; normals[offset] = particle.age / particle.life; // normals[offset + 1] = particle.rotation; normals[offset + 1] = 0; normals[offset + 2] = particle.spriteSize; } var offset2 = i * 2; if (hasUvAnimation) { // TODO var p = particle.age / particle.life; var stage = Math.round(p * (nUvAnimFrame - 1)) * animRepeat; var v = Math.floor(stage * invAnimTileX); var u = stage - v * animTileX; uvs[offset2] = u / animTileX; uvs[offset2 + 1] = 1 - v / animTileY; uvs2[offset2] = (u + 1) / animTileX; uvs2[offset2 + 1] = 1 - (v + 1) / animTileY; } } geometry.dirty(); }, /** * @return {boolean} */ isFinished: function() { return this._elapsedTime > this.duration && !this.loop; }, /** * @param {clay.Renderer} renderer */ dispose: function(renderer) { // Put all the particles back for (var i = 0; i < this._particles.length; i++) { var p = this._particles[i]; p.emitter.kill(p); } this.geometry.dispose(renderer); // TODO Dispose texture ? }, /** * @return {clay.particle.ParticleRenderable} */ clone: function() { var particleRenderable = new ParticleRenderable({ material: this.material }); particleRenderable.loop = this.loop; particleRenderable.duration = this.duration; particleRenderable.oneshot = this.oneshot; particleRenderable.spriteAnimationRepeat = this.spriteAnimationRepeat; particleRenderable.spriteAnimationTileY = this.spriteAnimationTileY; particleRenderable.spriteAnimationTileX = this.spriteAnimationTileX; particleRenderable.position.copy(this.position); particleRenderable.rotation.copy(this.rotation); particleRenderable.scale.copy(this.scale); for (var i = 0; i < this._children.length; i++) { particleRenderable.add(this._children[i].clone()); } return particleRenderable; } }); var colorEssl = "@export clay.picking.color.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\n@import clay.chunk.skinning_header\nvoid main(){\n vec3 skinnedPosition = position;\n #ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n #endif\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0);\n}\n@end\n@end\n@export clay.picking.color.fragment\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\nvoid main() {\n gl_FragColor = color;\n}\n@end"; Shader.import(colorEssl); /** * Pixel picking is gpu based picking, which is fast and accurate. * But not like ray picking, it can't get the intersection point and triangle. * @constructor clay.picking.PixelPicking * @extends clay.core.Base */ var PixelPicking = Base.extend(function() { return /** @lends clay.picking.PixelPicking# */ { /** * Target renderer * @type {clay.Renderer} */ renderer: null, /** * Downsample ratio of hidden frame buffer * @type {number} */ downSampleRatio: 1, width: 100, height: 100, lookupOffset: 1, _frameBuffer: null, _texture: null, _shader: null, _idMaterials: [], _lookupTable: [], _meshMaterials: [], _idOffset: 0 }; }, function() { if (this.renderer) { this.width = this.renderer.getWidth(); this.height = this.renderer.getHeight(); } this._init(); }, /** @lends clay.picking.PixelPicking.prototype */ { _init: function() { this._texture = new Texture2D({ width: this.width * this.downSampleRatio, height: this.height * this.downSampleRatio }); this._frameBuffer = new FrameBuffer(); this._shader = new Shader(Shader.source('clay.picking.color.vertex'), Shader.source('clay.picking.color.fragment')); }, /** * Set picking presision * @param {number} ratio */ setPrecision: function(ratio) { this._texture.width = this.width * ratio; this._texture.height = this.height * ratio; this.downSampleRatio = ratio; }, resize: function(width, height) { this._texture.width = width * this.downSampleRatio; this._texture.height = height * this.downSampleRatio; this.width = width; this.height = height; this._texture.dirty(); }, /** * Update the picking framebuffer * @param {number} ratio */ update: function(scene, camera) { var renderer = this.renderer; if (renderer.getWidth() !== this.width || renderer.getHeight() !== this.height) { this.resize(renderer.width, renderer.height); } this._frameBuffer.attach(this._texture); this._frameBuffer.bind(renderer); this._idOffset = this.lookupOffset; this._setMaterial(scene); renderer.render(scene, camera); this._restoreMaterial(); this._frameBuffer.unbind(renderer); }, _setMaterial: function(root) { for (var i =0; i < root._children.length; i++) { var child = root._children[i]; if (child.geometry && child.material && child.material.shader) { var id = this._idOffset++; var idx = id - this.lookupOffset; var material = this._idMaterials[idx]; if (!material) { material = new Material({ shader: this._shader }); var color = packID(id); color[0] /= 255; color[1] /= 255; color[2] /= 255; color[3] = 1.0; material.set('color', color); this._idMaterials[idx] = material; } this._meshMaterials[idx] = child.material; this._lookupTable[idx] = child; child.material = material; } if (child._children.length) { this._setMaterial(child); } } }, /** * Pick the object * @param {number} x Mouse position x * @param {number} y Mouse position y * @return {clay.Node} */ pick: function(x, y) { var renderer = this.renderer; var ratio = this.downSampleRatio; x = Math.ceil(ratio * x); y = Math.ceil(ratio * (this.height - y)); this._frameBuffer.bind(renderer); var pixel = new Uint8Array(4); var _gl = renderer.gl; // TODO out of bounds ? // preserveDrawingBuffer ? _gl.readPixels(x, y, 1, 1, _gl.RGBA, _gl.UNSIGNED_BYTE, pixel); this._frameBuffer.unbind(renderer); // Skip interpolated pixel because of anti alias if (pixel[3] === 255) { var id = unpackID(pixel[0], pixel[1], pixel[2]); if (id) { var el = this._lookupTable[id - this.lookupOffset]; return el; } } }, _restoreMaterial: function() { for (var i = 0; i < this._lookupTable.length; i++) { this._lookupTable[i].material = this._meshMaterials[i]; } }, dispose: function(renderer) { this._frameBuffer.dispose(renderer); } }); function packID(id){ var r = id >> 16; var g = (id - (r << 8)) >> 8; var b = id - (r << 16) - (g<<8); return [r, g, b]; } function unpackID(r, g, b){ return (r << 16) + (g<<8) + b; } var doc = typeof document === 'undefined' ? {} : document; /** * @constructor clay.plugin.FreeControl * @example * var control = new clay.plugin.FreeControl({ * target: camera, * domElement: renderer.canvas * }); * ... * timeline.on('frame', function(frameTime) { * control.update(frameTime); * renderer.render(scene, camera); * }); */ var FreeControl = Base.extend(function() { return /** @lends clay.plugin.FreeControl# */ { /** * Scene node to control, mostly it is a camera * @type {clay.Node} */ target: null, /** * Target dom to bind with mouse events * @type {HTMLElement} */ domElement: null, /** * Mouse move sensitivity * @type {number} */ sensitivity: 1, /** * Target move speed * @type {number} */ speed: 0.4, /** * Up axis * @type {clay.Vector3} */ up: new Vector3(0, 1, 0), /** * If lock vertical movement * @type {boolean} */ verticalMoveLock: false, /** * @type {clay.Timeline} */ timeline: null, _moveForward: false, _moveBackward: false, _moveLeft: false, _moveRight: false, _offsetPitch: 0, _offsetRoll: 0 }; }, function() { this._lockChange = this._lockChange.bind(this); this._keyDown = this._keyDown.bind(this); this._keyUp = this._keyUp.bind(this); this._mouseMove = this._mouseMove.bind(this); if (this.domElement) { this.init(); } }, /** @lends clay.plugin.FreeControl.prototype */ { /** * init control */ init: function() { // Use pointer lock // http://www.html5rocks.com/en/tutorials/pointerlock/intro/ var el = this.domElement; //Must request pointer lock after click event, can't not do it directly //Why ? ? vendor.addEventListener(el, 'click', this._requestPointerLock); vendor.addEventListener(doc, 'pointerlockchange', this._lockChange); vendor.addEventListener(doc, 'mozpointerlockchange', this._lockChange); vendor.addEventListener(doc, 'webkitpointerlockchange', this._lockChange); vendor.addEventListener(doc, 'keydown', this._keyDown); vendor.addEventListener(doc, 'keyup', this._keyUp); if (this.timeline) { this.timeline.on('frame', this._detectMovementChange, this); } }, /** * Dispose control */ dispose: function() { var el = this.domElement; el.exitPointerLock = el.exitPointerLock || el.mozExitPointerLock || el.webkitExitPointerLock; if (el.exitPointerLock) { el.exitPointerLock(); } vendor.removeEventListener(el, 'click', this._requestPointerLock); vendor.removeEventListener(doc, 'pointerlockchange', this._lockChange); vendor.removeEventListener(doc, 'mozpointerlockchange', this._lockChange); vendor.removeEventListener(doc, 'webkitpointerlockchange', this._lockChange); vendor.removeEventListener(doc, 'keydown', this._keyDown); vendor.removeEventListener(doc, 'keyup', this._keyUp); if (this.timeline) { this.timeline.off('frame', this._detectMovementChange); } }, _requestPointerLock: function() { var el = this; el.requestPointerLock = el.requestPointerLock || el.mozRequestPointerLock || el.webkitRequestPointerLock; el.requestPointerLock(); }, /** * Control update. Should be invoked every frame * @param {number} frameTime Frame time */ update: function (frameTime) { var target = this.target; var position = this.target.position; var xAxis = target.localTransform.x.normalize(); var zAxis = target.localTransform.z.normalize(); if (this.verticalMoveLock) { zAxis.y = 0; zAxis.normalize(); } var speed = this.speed * frameTime / 20; if (this._moveForward) { // Opposite direction of z position.scaleAndAdd(zAxis, -speed); } if (this._moveBackward) { position.scaleAndAdd(zAxis, speed); } if (this._moveLeft) { position.scaleAndAdd(xAxis, -speed / 2); } if (this._moveRight) { position.scaleAndAdd(xAxis, speed / 2); } target.rotateAround(target.position, this.up, -this._offsetPitch * frameTime * Math.PI / 360); var xAxis = target.localTransform.x; target.rotateAround(target.position, xAxis, -this._offsetRoll * frameTime * Math.PI / 360); this._offsetRoll = this._offsetPitch = 0; }, _lockChange: function() { if ( doc.pointerLockElement === this.domElement || doc.mozPointerLockElement === this.domElement || doc.webkitPointerLockElement === this.domElement ) { vendor.addEventListener(doc, 'mousemove', this._mouseMove, false); } else { vendor.removeEventListener(doc, 'mousemove', this._mouseMove); } }, _mouseMove: function(e) { var dx = e.movementX || e.mozMovementX || e.webkitMovementX || 0; var dy = e.movementY || e.mozMovementY || e.webkitMovementY || 0; this._offsetPitch += dx * this.sensitivity / 200; this._offsetRoll += dy * this.sensitivity / 200; // Trigger change event to remind renderer do render this.trigger('change'); }, _detectMovementChange: function () { if (this._moveForward || this._moveBackward || this._moveLeft || this._moveRight) { this.trigger('change'); } }, _keyDown: function(e) { switch(e.keyCode) { case 87: //w case 37: //up arrow this._moveForward = true; break; case 83: //s case 40: //down arrow this._moveBackward = true; break; case 65: //a case 37: //left arrow this._moveLeft = true; break; case 68: //d case 39: //right arrow this._moveRight = true; break; } // Trigger change event to remind renderer do render this.trigger('change'); }, _keyUp: function(e) { switch(e.keyCode) { case 87: //w case 37: //up arrow this._moveForward = false; break; case 83: //s case 40: //down arrow this._moveBackward = false; break; case 65: //a case 37: //left arrow this._moveLeft = false; break; case 68: //d case 39: //right arrow this._moveRight = false; break; } } }); /** * Gamepad Control plugin. * * @constructor clay.plugin.GamepadControl * * @example * init: function(app) { * this._gamepadControl = new clay.plugin.GamepadControl({ * target: camera, * onStandardGamepadReady: customCallback * }); * }, * * loop: function(app) { * this._gamepadControl.update(app.frameTime); * } */ var GamepadControl = Base.extend(function() { return /** @lends clay.plugin.GamepadControl# */ { /** * Scene node to control, mostly it is a camera. * * @type {clay.Node} */ target: null, /** * Move speed. * * @type {number} */ moveSpeed: 0.1, /** * Look around speed. * * @type {number} */ lookAroundSpeed: 0.1, /** * Up axis. * * @type {clay.Vector3} */ up: new Vector3(0, 1, 0), /** * Timeline. * * @type {clay.Timeline} */ timeline: null, /** * Function to be called when a standard gamepad is ready to use. * * @type {function} */ onStandardGamepadReady: function(gamepad){}, /** * Function to be called when a gamepad is disconnected. * * @type {function} */ onGamepadDisconnected: function(gamepad){}, // Private properties: _moveForward: false, _moveBackward: false, _moveLeft: false, _moveRight: false, _offsetPitch: 0, _offsetRoll: 0, _connectedGamepadIndex: 0, _standardGamepadAvailable: false, _gamepadAxisThreshold: 0.3 }; }, function() { this._checkGamepadCompatibility = this._checkGamepadCompatibility.bind(this); this._disconnectGamepad = this._disconnectGamepad.bind(this); this._getStandardGamepad = this._getStandardGamepad.bind(this); this._scanPressedGamepadButtons = this._scanPressedGamepadButtons.bind(this); this._scanInclinedGamepadAxes = this._scanInclinedGamepadAxes.bind(this); this.update = this.update.bind(this); // If browser supports Gamepad API: if (typeof navigator.getGamepads === 'function') { this.init(); } }, /** @lends clay.plugin.GamepadControl.prototype */ { /** * Init. control. */ init: function() { /** * When user begins to interact with connected gamepad: * * @see https://w3c.github.io/gamepad/#dom-gamepadevent */ vendor.addEventListener(window, 'gamepadconnected', this._checkGamepadCompatibility); if (this.timeline) { this.timeline.on('frame', this.update); } vendor.addEventListener(window, 'gamepaddisconnected', this._disconnectGamepad); }, /** * Dispose control. */ dispose: function() { vendor.removeEventListener(window, 'gamepadconnected', this._checkGamepadCompatibility); if (this.timeline) { this.timeline.off('frame', this.update); } vendor.removeEventListener(window, 'gamepaddisconnected', this._disconnectGamepad); }, /** * Control's update. Should be invoked every frame. * * @param {number} frameTime Frame time. */ update: function (frameTime) { if (!this._standardGamepadAvailable) { return; } this._scanPressedGamepadButtons(); this._scanInclinedGamepadAxes(); // Update target depending on user input. var target = this.target; var position = this.target.position; var xAxis = target.localTransform.x.normalize(); var zAxis = target.localTransform.z.normalize(); var moveSpeed = this.moveSpeed * frameTime / 20; if (this._moveForward) { // Opposite direction of z. position.scaleAndAdd(zAxis, -moveSpeed); } if (this._moveBackward) { position.scaleAndAdd(zAxis, moveSpeed); } if (this._moveLeft) { position.scaleAndAdd(xAxis, -moveSpeed); } if (this._moveRight) { position.scaleAndAdd(xAxis, moveSpeed); } target.rotateAround(target.position, this.up, -this._offsetPitch * frameTime * Math.PI / 360); var xAxis = target.localTransform.x; target.rotateAround(target.position, xAxis, -this._offsetRoll * frameTime * Math.PI / 360); /* * If necessary: trigger `update` event. * XXX This can economize rendering OPs. */ if (this._moveForward === true || this._moveBackward === true || this._moveLeft === true || this._moveRight === true || this._offsetPitch !== 0 || this._offsetRoll !== 0) { this.trigger('update'); } // Reset values to avoid lost of control. this._moveForward = this._moveBackward = this._moveLeft = this._moveRight = false; this._offsetPitch = this._offsetRoll = 0; }, // Private methods: _checkGamepadCompatibility: function(event) { /** * If connected gamepad has a **standard** layout: * * @see https://w3c.github.io/gamepad/#remapping about standard. */ if (event.gamepad.mapping === 'standard') { this._standardGamepadIndex = event.gamepad.index; this._standardGamepadAvailable = true; this.onStandardGamepadReady(event.gamepad); } }, _disconnectGamepad: function(event) { this._standardGamepadAvailable = false; this.onGamepadDisconnected(event.gamepad); }, _getStandardGamepad: function() { return navigator.getGamepads()[this._standardGamepadIndex]; }, _scanPressedGamepadButtons: function() { var gamepadButtons = this._getStandardGamepad().buttons; // For each gamepad button: for (var gamepadButtonId = 0; gamepadButtonId < gamepadButtons.length; gamepadButtonId++) { // Get user input. var gamepadButton = gamepadButtons[gamepadButtonId]; if (gamepadButton.pressed) { switch (gamepadButtonId) { // D-pad Up case 12: this._moveForward = true; break; // D-pad Down case 13: this._moveBackward = true; break; // D-pad Left case 14: this._moveLeft = true; break; // D-pad Right case 15: this._moveRight = true; break; } } } }, _scanInclinedGamepadAxes: function() { var gamepadAxes = this._getStandardGamepad().axes; // For each gamepad axis: for (var gamepadAxisId = 0; gamepadAxisId < gamepadAxes.length; gamepadAxisId++) { // Get user input. var gamepadAxis = gamepadAxes[gamepadAxisId]; // XXX We use a threshold because axes are never neutral. if (Math.abs(gamepadAxis) > this._gamepadAxisThreshold) { switch (gamepadAxisId) { // Left stick X± case 0: this._moveLeft = gamepadAxis < 0; this._moveRight = gamepadAxis > 0; break; // Left stick Y± case 1: this._moveForward = gamepadAxis < 0; this._moveBackward = gamepadAxis > 0; break; // Right stick X± case 2: this._offsetPitch += gamepadAxis * this.lookAroundSpeed; break; // Right stick Y± case 3: this._offsetRoll += gamepadAxis * this.lookAroundSpeed; break; } } } } }); var GestureMgr = function () { this._track = []; }; GestureMgr.prototype = { constructor: GestureMgr, recognize: function (event, target, root) { this._doTrack(event, target, root); return this._recognize(event); }, clear: function () { this._track.length = 0; return this; }, _doTrack: function (event, target, root) { var touches = event.targetTouches; if (!touches) { return; } var trackItem = { points: [], touches: [], target: target, event: event }; for (var i = 0, len = touches.length; i < len; i++) { var touch = touches[i]; trackItem.points.push([touch.clientX, touch.clientY]); trackItem.touches.push(touch); } this._track.push(trackItem); }, _recognize: function (event) { for (var eventName in recognizers) { if (recognizers.hasOwnProperty(eventName)) { var gestureInfo = recognizers[eventName](this._track, event); if (gestureInfo) { return gestureInfo; } } } } }; function dist(pointPair) { var dx = pointPair[1][0] - pointPair[0][0]; var dy = pointPair[1][1] - pointPair[0][1]; return Math.sqrt(dx * dx + dy * dy); } function center(pointPair) { return [ (pointPair[0][0] + pointPair[1][0]) / 2, (pointPair[0][1] + pointPair[1][1]) / 2 ]; } var recognizers = { pinch: function (track, event) { var trackLen = track.length; if (!trackLen) { return; } var pinchEnd = (track[trackLen - 1] || {}).points; var pinchPre = (track[trackLen - 2] || {}).points || pinchEnd; if (pinchPre && pinchPre.length > 1 && pinchEnd && pinchEnd.length > 1 ) { var pinchScale = dist(pinchEnd) / dist(pinchPre); !isFinite(pinchScale) && (pinchScale = 1); event.pinchScale = pinchScale; var pinchCenter = center(pinchEnd); event.pinchX = pinchCenter[0]; event.pinchY = pinchCenter[1]; return { type: 'pinch', target: track[0].target, event: event }; } } }; var uvs = [[0, 0], [0, 1], [1, 1], [1, 0]]; var tris = [0, 1, 2, 2, 3, 0]; var InfinitePlane = Mesh.extend({ camera: null, plane: null, maxGrid: 0, // TODO frustumCulling: false }, function () { var geometry = this.geometry = new Geometry({ dynamic: true }); geometry.attributes.position.init(6); geometry.attributes.normal.init(6); geometry.attributes.texcoord0.init(6); geometry.indices = new Uint16Array(6); this.plane = new Plane$1(); }, { updateGeometry: function () { var coords = this._unProjectGrid(); if (!coords) { return; } var positionAttr = this.geometry.attributes.position; var normalAttr = this.geometry.attributes.normal; var texcoords = this.geometry.attributes.texcoord0; var indices = this.geometry.indices; for (var i = 0; i < 6; i++) { var idx = tris[i]; positionAttr.set(i, coords[idx].array); normalAttr.set(i, this.plane.normal.array); texcoords.set(i, uvs[idx]); indices[i] = i; } this.geometry.dirty(); }, // http://fileadmin.cs.lth.se/graphics/theses/projects/projgrid/ _unProjectGrid: (function () { var planeViewSpace = new Plane$1(); var lines = [ 0, 1, 0, 2, 1, 3, 2, 3, 4, 5, 4, 6, 5, 7, 6, 7, 0, 4, 1, 5, 2, 6, 3, 7 ]; var start = new Vector3(); var end = new Vector3(); var points = []; // 1----2 // | | // 0----3 var coords = []; for (var i = 0; i < 4; i++) { coords[i] = new Vector3(0, 0); } var ray = new Ray(); return function () { planeViewSpace.copy(this.plane); planeViewSpace.applyTransform(this.camera.viewMatrix); var frustumVertices = this.camera.frustum.vertices; var nPoints = 0; // Intersect with lines of frustum for (var i = 0; i < 12; i++) { start.array = frustumVertices[lines[i * 2]]; end.array = frustumVertices[lines[i * 2 + 1]]; var point = planeViewSpace.intersectLine(start, end, points[nPoints]); if (point) { if (!points[nPoints]) { points[nPoints] = point; } nPoints++; } } if (nPoints === 0) { return; } for (var i = 0; i < nPoints; i++) { points[i].applyProjection(this.camera.projectionMatrix); } var minX = points[0].array[0]; var minY = points[0].array[1]; var maxX = points[0].array[0]; var maxY = points[0].array[1]; for (var i = 1; i < nPoints; i++) { maxX = Math.max(maxX, points[i].array[0]); maxY = Math.max(maxY, points[i].array[1]); minX = Math.min(minX, points[i].array[0]); minY = Math.min(minY, points[i].array[1]); } if (minX == maxX || minY == maxY) { return; } coords[0].array[0] = minX; coords[0].array[1] = minY; coords[1].array[0] = minX; coords[1].array[1] = maxY; coords[2].array[0] = maxX; coords[2].array[1] = maxY; coords[3].array[0] = maxX; coords[3].array[1] = minY; for (var i = 0; i < 4; i++) { this.camera.castRay(coords[i], ray); ray.intersectPlane(this.plane, coords[i]); } return coords; }; })() }); function convertToArray(val) { if (!Array.isArray(val)) { val = [val, val]; } return val; } /** * @constructor * @alias clay.plugin.OrbitControl * @extends clay.core.Base */ var OrbitControl = Base.extend(function () { return /** @lends clay.plugin.OrbitControl# */ { timeline: null, /** * @type {HTMLElement} */ domElement: null, /** * @type {clay.Node} */ target: null, /** * @type {clay.Vector3} */ _center: new Vector3(), /** * Minimum distance to the center * @type {number} * @default 0.5 */ minDistance: 0.1, /** * Maximum distance to the center * @type {number} * @default 2 */ maxDistance: 1000, /** * Minimum alpha rotation */ minAlpha: -90, /** * Maximum alpha rotation */ maxAlpha: 90, /** * Minimum beta rotation */ minBeta: -Infinity, /** * Maximum beta rotation */ maxBeta: Infinity, /** * Start auto rotating after still for the given time */ autoRotateAfterStill: 0, /** * Direction of autoRotate. cw or ccw when looking top down. */ autoRotateDirection: 'cw', /** * Degree per second */ autoRotateSpeed: 60, /** * Pan or rotate * @type {String} */ _mode: 'rotate', /** * @param {number} */ damping: 0.8, /** * @param {number} */ rotateSensitivity: 1, /** * @param {number} */ zoomSensitivity: 1, /** * @param {number} */ panSensitivity: 1, _needsUpdate: false, _rotating: false, // Rotation around yAxis _phi: 0, // Rotation around xAxis _theta: 0, _mouseX: 0, _mouseY: 0, _rotateVelocity: new Vector2(), _panVelocity: new Vector2(), _distance: 20, _zoomSpeed: 0, _stillTimeout: 0, _animators: [], _gestureMgr: new GestureMgr() }; }, function () { // Each OrbitControl has it's own handler this._mouseDownHandler = this._mouseDownHandler.bind(this); this._mouseWheelHandler = this._mouseWheelHandler.bind(this); this._mouseMoveHandler = this._mouseMoveHandler.bind(this); this._mouseUpHandler = this._mouseUpHandler.bind(this); this._pinchHandler = this._pinchHandler.bind(this); this.init(); }, /** @lends clay.plugin.OrbitControl# */ { /** * Initialize. * Mouse event binding */ init: function () { var dom = this.domElement; vendor.addEventListener(dom, 'touchstart', this._mouseDownHandler); vendor.addEventListener(dom, 'mousedown', this._mouseDownHandler); vendor.addEventListener(dom, 'wheel', this._mouseWheelHandler); if (this.timeline) { this.timeline.on('frame', this.update, this); } }, /** * Dispose. * Mouse event unbinding */ dispose: function () { var dom = this.domElement; vendor.removeEventListener(dom, 'touchstart', this._mouseDownHandler); vendor.removeEventListener(dom, 'touchmove', this._mouseMoveHandler); vendor.removeEventListener(dom, 'touchend', this._mouseUpHandler); vendor.removeEventListener(dom, 'mousedown', this._mouseDownHandler); vendor.removeEventListener(dom, 'mousemove', this._mouseMoveHandler); vendor.removeEventListener(dom, 'mouseup', this._mouseUpHandler); vendor.removeEventListener(dom, 'wheel', this._mouseWheelHandler); vendor.removeEventListener(dom, 'mouseout', this._mouseUpHandler); if (this.timeline) { this.timeline.off('frame', this.update); } this.stopAllAnimation(); }, /** * Get distance * @return {number} */ getDistance: function () { return this._distance; }, /** * Set distance * @param {number} distance */ setDistance: function (distance) { this._distance = distance; this._needsUpdate = true; }, /** * Get alpha rotation * Alpha angle for top-down rotation. Positive to rotate to top. * * Which means camera rotation around x axis. */ getAlpha: function () { return this._theta / Math.PI * 180; }, /** * Get beta rotation * Beta angle for left-right rotation. Positive to rotate to right. * * Which means camera rotation around y axis. */ getBeta: function () { return -this._phi / Math.PI * 180; }, /** * Get control center * @return {Array.} */ getCenter: function () { return this._center.toArray(); }, /** * Set alpha rotation angle * @param {number} alpha */ setAlpha: function (alpha) { alpha = Math.max(Math.min(this.maxAlpha, alpha), this.minAlpha); this._theta = alpha / 180 * Math.PI; this._needsUpdate = true; }, /** * Set beta rotation angle * @param {number} beta */ setBeta: function (beta) { beta = Math.max(Math.min(this.maxBeta, beta), this.minBeta); this._phi = -beta / 180 * Math.PI; this._needsUpdate = true; }, /** * Set control center * @param {Array.} center */ setCenter: function (centerArr) { this._center.setArray(centerArr); }, setOption: function (opts) { opts = opts || {}; ['autoRotate', 'autoRotateAfterStill', 'autoRotateDirection', 'autoRotateSpeed', 'damping', 'minDistance', 'maxDistance', 'minAlpha', 'maxAlpha', 'minBeta', 'maxBeta', 'rotateSensitivity', 'zoomSensitivity', 'panSensitivity' ].forEach(function (key) { if (opts[key] != null) { this[key] = opts[key]; } }, this); if (opts.distance != null) { this.setDistance(opts.distance); } if (opts.alpha != null) { this.setAlpha(opts.alpha); } if (opts.beta != null) { this.setBeta(opts.beta); } if (opts.center) { this.setCenter(opts.center); } }, /** * @param {Object} opts * @param {number} opts.distance * @param {number} opts.alpha * @param {number} opts.beta * @param {Array.} opts.center * @param {number} [opts.duration=1000] * @param {number} [opts.easing='linear'] * @param {number} [opts.done] */ animateTo: function (opts) { var self = this; var obj = {}; var target = {}; var timeline = this.timeline; if (!timeline) { return; } if (opts.distance != null) { obj.distance = this.getDistance(); target.distance = opts.distance; } if (opts.alpha != null) { obj.alpha = this.getAlpha(); target.alpha = opts.alpha; } if (opts.beta != null) { obj.beta = this.getBeta(); target.beta = opts.beta; } if (opts.center != null) { obj.center = this.getCenter(); target.center = opts.center; } return this._addAnimator( timeline.animate(obj) .when(opts.duration || 1000, target) .during(function () { if (obj.alpha != null) { self.setAlpha(obj.alpha); } if (obj.beta != null) { self.setBeta(obj.beta); } if (obj.distance != null) { self.setDistance(obj.distance); } if (obj.center != null) { self.setCenter(obj.center); } self._needsUpdate = true; }) .done(opts.done) ).start(opts.easing || 'linear'); }, /** * Stop all animations */ stopAllAnimation: function () { for (var i = 0; i < this._animators.length; i++) { this._animators[i].stop(); } this._animators.length = 0; }, _isAnimating: function () { return this._animators.length > 0; }, /** * Call update each frame * @param {number} deltaTime Frame time */ update: function (deltaTime) { deltaTime = deltaTime || 16; if (this._rotating) { var radian = (this.autoRotateDirection === 'cw' ? 1 : -1) * this.autoRotateSpeed / 180 * Math.PI; this._phi -= radian * deltaTime / 1000; this._needsUpdate = true; } else if (this._rotateVelocity.len() > 0) { this._needsUpdate = true; } if (Math.abs(this._zoomSpeed) > 0.01 || this._panVelocity.len() > 0) { this._needsUpdate = true; } if (!this._needsUpdate) { return; } // Fixed deltaTime this._updateDistance(Math.min(deltaTime, 50)); this._updatePan(Math.min(deltaTime, 50)); this._updateRotate(Math.min(deltaTime, 50)); this._updateTransform(); this.target.update(); this.trigger('update'); this._needsUpdate = false; }, _updateRotate: function (deltaTime) { var velocity = this._rotateVelocity; this._phi = velocity.y * deltaTime / 20 + this._phi; this._theta = velocity.x * deltaTime / 20 + this._theta; this.setAlpha(this.getAlpha()); this.setBeta(this.getBeta()); this._vectorDamping(velocity, this.damping); }, _updateDistance: function (deltaTime) { this._setDistance(this._distance + this._zoomSpeed * deltaTime / 20); this._zoomSpeed *= this.damping; }, _setDistance: function (distance) { this._distance = Math.max(Math.min(distance, this.maxDistance), this.minDistance); }, _updatePan: function (deltaTime) { var velocity = this._panVelocity; var len = this._distance; var target = this.target; var yAxis = target.worldTransform.y; var xAxis = target.worldTransform.x; // PENDING this._center .scaleAndAdd(xAxis, -velocity.x * len / 200) .scaleAndAdd(yAxis, -velocity.y * len / 200); this._vectorDamping(velocity, 0); velocity.x = velocity.y = 0; }, _updateTransform: function () { var camera = this.target; var dir = new Vector3(); var theta = this._theta + Math.PI / 2; var phi = this._phi + Math.PI / 2; var r = Math.sin(theta); dir.x = r * Math.cos(phi); dir.y = -Math.cos(theta); dir.z = r * Math.sin(phi); camera.position.copy(this._center).scaleAndAdd(dir, this._distance); camera.rotation.identity() // First around y, then around x .rotateY(-this._phi) .rotateX(-this._theta); }, _startCountingStill: function () { clearTimeout(this._stillTimeout); var time = this.autoRotateAfterStill; var self = this; if (!isNaN(time) && time > 0) { this._stillTimeout = setTimeout(function () { self._rotating = true; }, time * 1000); } }, _vectorDamping: function (v, damping) { var speed = v.len(); speed = speed * damping; if (speed < 1e-4) { speed = 0; } v.normalize().scale(speed); }, decomposeTransform: function () { if (!this.target) { return; } // FIXME euler order...... // FIXME alpha is not certain when beta is 90 or -90 // var euler = new Vector3(); // euler.eulerFromMat3( // new Matrix3().fromQuat(this.target.rotation), 'ZYX' // ); // euler.eulerFromQuat( // this.target.rotation.normalize(), 'ZYX' // ); this.target.updateWorldTransform(); var forward = this.target.worldTransform.z; var alpha = Math.asin(forward.y); var beta = Math.atan2(forward.x, forward.z); this._theta = alpha; this._phi = -beta; this.setBeta(this.getBeta()); this.setAlpha(this.getAlpha()); this._setDistance(this.target.position.dist(this._center)); }, _mouseDownHandler: function (e) { if (this._isAnimating()) { return; } var x = e.clientX; var y = e.clientY; // Touch if (e.targetTouches) { var touch = e.targetTouches[0]; x = touch.clientX; y = touch.clientY; this._mode = 'rotate'; this._processGesture(e, 'start'); } else { // Left button. if (e.button === 0) { this._mode = 'rotate'; } // Middle button. else if (e.button === 1) { this._mode = 'pan'; /** * Vendors like Mozilla provide a mouse-driven panning feature * that is activated when the middle mouse button is pressed. * * @see https://w3c.github.io/uievents/#event-type-mousedown */ e.preventDefault(); } else { this._mode = null; } } var dom = this.domElement; vendor.addEventListener(dom, 'touchmove', this._mouseMoveHandler); vendor.addEventListener(dom, 'touchend', this._mouseUpHandler); vendor.addEventListener(dom, 'mousemove', this._mouseMoveHandler); vendor.addEventListener(dom, 'mouseup', this._mouseUpHandler); vendor.addEventListener(dom, 'mouseout', this._mouseUpHandler); // Reset rotate velocity this._rotateVelocity.set(0, 0); this._rotating = false; if (this.autoRotate) { this._startCountingStill(); } this._mouseX = x; this._mouseY = y; }, _mouseMoveHandler: function (e) { if (this._isAnimating()) { return; } var x = e.clientX; var y = e.clientY; var haveGesture; // Touch if (e.targetTouches) { var touch = e.targetTouches[0]; x = touch.clientX; y = touch.clientY; haveGesture = this._processGesture(e, 'change'); } var panSensitivity = convertToArray(this.panSensitivity); var rotateSensitivity = convertToArray(this.rotateSensitivity); if (!haveGesture) { if (this._mode === 'rotate') { this._rotateVelocity.y += (x - this._mouseX) / this.domElement.clientWidth * 2 * rotateSensitivity[0]; this._rotateVelocity.x += (y - this._mouseY) / this.domElement.clientHeight * 2 * rotateSensitivity[1]; } else if (this._mode === 'pan') { this._panVelocity.x += (x - this._mouseX) / this.domElement.clientWidth * panSensitivity[0] * 400; this._panVelocity.y += (-y + this._mouseY) / this.domElement.clientHeight * panSensitivity[1] * 400; } } this._mouseX = x; this._mouseY = y; e.preventDefault && e.preventDefault(); }, _mouseWheelHandler: function (e) { if (this._isAnimating()) { return; } var delta = e.deltaY; if (delta === 0) { return; } this._zoomHandler(e, delta > 0 ? 1 : -1); }, _pinchHandler: function (e) { if (this._isAnimating()) { return; } this._zoomHandler(e, e.pinchScale > 1 ? -0.4 : 0.4); }, _zoomHandler: function (e, delta) { var distance = Math.max(Math.min( this._distance - this.minDistance, this.maxDistance - this._distance )); this._zoomSpeed = delta * Math.max(distance / 40 * this.zoomSensitivity, 0.2); this._rotating = false; if (this.autoRotate && this._mode === 'rotate') { this._startCountingStill(); } e.preventDefault && e.preventDefault(); }, _mouseUpHandler: function (event) { var dom = this.domElement; vendor.removeEventListener(dom, 'touchmove', this._mouseMoveHandler); vendor.removeEventListener(dom, 'touchend', this._mouseUpHandler); vendor.removeEventListener(dom, 'mousemove', this._mouseMoveHandler); vendor.removeEventListener(dom, 'mouseup', this._mouseUpHandler); vendor.removeEventListener(dom, 'mouseout', this._mouseUpHandler); this._processGesture(event, 'end'); }, _addAnimator: function (animator) { var animators = this._animators; animators.push(animator); animator.done(function () { var idx = animators.indexOf(animator); if (idx >= 0) { animators.splice(idx, 1); } }); return animator; }, _processGesture: function (event, stage) { var gestureMgr = this._gestureMgr; stage === 'start' && gestureMgr.clear(); var gestureInfo = gestureMgr.recognize( event, null, this.domElement ); stage === 'end' && gestureMgr.clear(); // Do not do any preventDefault here. Upper application do that if necessary. if (gestureInfo) { var type = gestureInfo.type; event.gestureEvent = type; this._pinchHandler(gestureInfo.event); } return gestureInfo; } }); /** * If auto rotate the target * @type {boolean} * @default false */ Object.defineProperty(OrbitControl.prototype, 'autoRotate', { get: function () { return this._autoRotate; }, set: function (val) { this._autoRotate = val; this._rotating = val; } }); Object.defineProperty(OrbitControl.prototype, 'target', { get: function () { return this._target; }, set: function (val) { if (val && val.target) { this.setCenter(val.target.toArray()); } this._target = val; this.decomposeTransform(); } }); /** * StaticGeometry can not be changed once they've been setup */ /** * @constructor clay.StaticGeometry * @extends clay.Geometry */ var StaticGeometry = Geometry.extend({ dynamic: false }); // TODO test /** * @namespace clay.util.mesh */ var meshUtil = { /** * Merge multiple meshes to one. * Note that these meshes must have the same material * * @param {Array.} meshes * @param {boolean} applyWorldTransform * @return {clay.Mesh} * @memberOf clay.util.mesh */ merge: function (meshes, applyWorldTransform) { if (! meshes.length) { return; } var templateMesh = meshes[0]; var templateGeo = templateMesh.geometry; var material = templateMesh.material; var geometry = new Geometry({ dynamic: false }); geometry.boundingBox = new BoundingBox(); var attributeNames = templateGeo.getEnabledAttributes(); for (var i = 0; i < attributeNames.length; i++) { var name = attributeNames[i]; var attr = templateGeo.attributes[name]; // Extend custom attributes if (!geometry.attributes[name]) { geometry.attributes[name] = attr.clone(false); } } var inverseTransposeMatrix = mat4.create(); // Initialize the array data and merge bounding box var nVertex = 0; var nFace = 0; for (var k = 0; k < meshes.length; k++) { var currentGeo = meshes[k].geometry; if (currentGeo.boundingBox) { currentGeo.boundingBox.applyTransform(applyWorldTransform ? meshes[k].worldTransform : meshes[k].localTransform); geometry.boundingBox.union(currentGeo.boundingBox); } nVertex += currentGeo.vertexCount; nFace += currentGeo.triangleCount; } for (var n = 0; n < attributeNames.length; n++) { var name = attributeNames[n]; var attrib = geometry.attributes[name]; attrib.init(nVertex); } if (nVertex >= 0xffff) { geometry.indices = new Uint32Array(nFace * 3); } else { geometry.indices = new Uint16Array(nFace * 3); } var vertexOffset = 0; var indicesOffset = 0; var useIndices = templateGeo.isUseIndices(); for (var mm = 0; mm < meshes.length; mm++) { var mesh = meshes[mm]; var currentGeo = mesh.geometry; var nVertex = currentGeo.vertexCount; var matrix = applyWorldTransform ? mesh.worldTransform.array : mesh.localTransform.array; mat4.invert(inverseTransposeMatrix, matrix); mat4.transpose(inverseTransposeMatrix, inverseTransposeMatrix); for (var nn = 0; nn < attributeNames.length; nn++) { var name = attributeNames[nn]; var currentAttr = currentGeo.attributes[name]; var targetAttr = geometry.attributes[name]; // Skip the unused attributes; if (!currentAttr.value.length) { continue; } var len = currentAttr.value.length; var size = currentAttr.size; var offset = vertexOffset * size; var count = len / size; for (var i = 0; i < len; i++) { targetAttr.value[offset + i] = currentAttr.value[i]; } // Transform position, normal and tangent if (name === 'position') { vec3.forEach(targetAttr.value, size, offset, count, vec3.transformMat4, matrix); } else if (name === 'normal' || name === 'tangent') { vec3.forEach(targetAttr.value, size, offset, count, vec3.transformMat4, inverseTransposeMatrix); } } if (useIndices) { var len = currentGeo.indices.length; for (var i = 0; i < len; i++) { geometry.indices[i + indicesOffset] = currentGeo.indices[i] + vertexOffset; } indicesOffset += len; } vertexOffset += nVertex; } return new Mesh({ material: material, geometry: geometry }); }, /** * Split mesh into sub meshes, each mesh will have maxJointNumber joints. * @param {clay.Mesh} mesh * @param {number} maxJointNumber * @param {boolean} inPlace * @return {clay.Node} * * @memberOf clay.util.mesh */ // FIXME, Have issues on some models splitByJoints: function (mesh, maxJointNumber, inPlace) { var geometry = mesh.geometry; var skeleton = mesh.skeleton; var material = mesh.material; var joints = mesh.joints; if (!geometry || !skeleton || !joints.length) { return; } if (joints.length < maxJointNumber) { return mesh; } var indices = geometry.indices; var faceLen = geometry.triangleCount; var rest = faceLen; var isFaceAdded = []; var jointValues = geometry.attributes.joint.value; for (var i = 0; i < faceLen; i++) { isFaceAdded[i] = false; } var addedJointIdxPerFace = []; var buckets = []; var getJointByIndex = function (idx) { return joints[idx]; }; while (rest > 0) { var bucketTriangles = []; var bucketJointReverseMap = []; var bucketJoints = []; var subJointNumber = 0; for (var i = 0; i < joints.length; i++) { bucketJointReverseMap[i] = -1; } for (var f = 0; f < faceLen; f++) { if (isFaceAdded[f]) { continue; } var canAddToBucket = true; var addedNumber = 0; for (var i = 0; i < 3; i++) { var idx = indices[f * 3 + i]; for (var j = 0; j < 4; j++) { var jointIdx = jointValues[idx * 4 + j]; if (jointIdx >= 0) { if (bucketJointReverseMap[jointIdx] === -1) { if (subJointNumber < maxJointNumber) { bucketJointReverseMap[jointIdx] = subJointNumber; bucketJoints[subJointNumber++] = jointIdx; addedJointIdxPerFace[addedNumber++] = jointIdx; } else { canAddToBucket = false; } } } } } if (!canAddToBucket) { // Reverse operation for (var i = 0; i < addedNumber; i++) { bucketJointReverseMap[addedJointIdxPerFace[i]] = -1; bucketJoints.pop(); subJointNumber--; } } else { bucketTriangles.push(indices.subarray(f * 3, (f + 1) * 3)); isFaceAdded[f] = true; rest--; } } buckets.push({ triangles: bucketTriangles, joints: bucketJoints.map(getJointByIndex), jointReverseMap: bucketJointReverseMap }); } var root = new Node({ name: mesh.name }); var attribNames = geometry.getEnabledAttributes(); attribNames.splice(attribNames.indexOf('joint'), 1); // Map from old vertex index to new vertex index var newIndices = []; for (var b = 0; b < buckets.length; b++) { var bucket = buckets[b]; var jointReverseMap = bucket.jointReverseMap; var subJointNumber = bucket.joints.length; var subGeo = new Geometry(); var subMesh = new Mesh({ name: [mesh.name, i].join('-'), // DON'T clone material. material: material, geometry: subGeo, skeleton: skeleton, joints: bucket.joints.slice() }); var nVertex = 0; var nVertex2 = geometry.vertexCount; for (var i = 0; i < nVertex2; i++) { newIndices[i] = -1; } // Count sub geo number for (var f = 0; f < bucket.triangles.length; f++) { var face = bucket.triangles[f]; for (var i = 0; i < 3; i++) { var idx = face[i]; if (newIndices[idx] === -1) { newIndices[idx] = nVertex; nVertex++; } } } for (var a = 0; a < attribNames.length; a++) { var attribName = attribNames[a]; var subAttrib = subGeo.attributes[attribName]; subAttrib.init(nVertex); } subGeo.attributes.joint.value = new Float32Array(nVertex * 4); if (nVertex > 0xffff) { subGeo.indices = new Uint32Array(bucket.triangles.length * 3); } else { subGeo.indices = new Uint16Array(bucket.triangles.length * 3); } var indicesOffset = 0; nVertex = 0; for (var i = 0; i < nVertex2; i++) { newIndices[i] = -1; } for (var f = 0; f < bucket.triangles.length; f++) { var triangle = bucket.triangles[f]; for (var i = 0; i < 3; i++) { var idx = triangle[i]; if (newIndices[idx] === -1) { newIndices[idx] = nVertex; for (var a = 0; a < attribNames.length; a++) { var attribName = attribNames[a]; var attrib = geometry.attributes[attribName]; var subAttrib = subGeo.attributes[attribName]; var size = attrib.size; for (var j = 0; j < size; j++) { subAttrib.value[nVertex * size + j] = attrib.value[idx * size + j]; } } for (var j = 0; j < 4; j++) { var jointIdx = geometry.attributes.joint.value[idx * 4 + j]; var offset = nVertex * 4 + j; if (jointIdx >= 0) { subGeo.attributes.joint.value[offset] = jointReverseMap[jointIdx]; } else { subGeo.attributes.joint.value[offset] = -1; } } nVertex++; } subGeo.indices[indicesOffset++] = newIndices[idx]; } } subGeo.updateBoundingBox(); root.add(subMesh); } var children = mesh.children(); for (var i = 0; i < children.length; i++) { root.add(children[i]); } root.position.copy(mesh.position); root.rotation.copy(mesh.rotation); root.scale.copy(mesh.scale); if (inPlace) { if (mesh.getParent()) { var parent = mesh.getParent(); parent.remove(mesh); parent.add(root); } } return root; } }; var META = { version: 1.0, type: 'Geometry', generator: 'util.transferable.toObject' }; /** * @alias clay.util.transferable */ var transferableUtil = { /** * Convert geometry to a object containing transferable data * @param {Geometry} geometry geometry * @param {Boolean} shallow whether shallow copy * @returns {Object} { data : data, buffers : buffers }, buffers is the transferable list */ toObject : function (geometry, shallow) { if (!geometry) { return null; } var data = { metadata : util$1.extend({}, META) }; //transferable buffers var buffers = []; //dynamic data.dynamic = geometry.dynamic; //bounding box if (geometry.boundingBox) { data.boundingBox = { min : geometry.boundingBox.min.toArray(), max : geometry.boundingBox.max.toArray() }; } //indices if (geometry.indices && geometry.indices.length > 0) { data.indices = copyIfNecessary(geometry.indices, shallow); buffers.push(data.indices.buffer); } //attributes data.attributes = {}; for (var p in geometry.attributes) { if (geometry.attributes.hasOwnProperty(p)) { var attr = geometry.attributes[p]; //ignore empty attributes if (attr && attr.value && attr.value.length > 0) { attr = data.attributes[p] = copyAttribute(attr, shallow); buffers.push(attr.value.buffer); } } } return { data : data, buffers : buffers }; }, /** * Reproduce a geometry from object generated by toObject * @param {Object} object object generated by toObject * @returns {Geometry} geometry */ toGeometry : function (object) { if (!object) { return null; } if (object.data && object.buffers) { return transferableUtil.toGeometry(object.data); } if (!object.metadata || object.metadata.generator !== META.generator) { throw new Error('[util.transferable.toGeometry] the object is not generated by util.transferable.'); } //basic options var options = { dynamic : object.dynamic, indices : object.indices }; if (object.boundingBox) { var min = new Vector3().setArray(object.boundingBox.min); var max = new Vector3().setArray(object.boundingBox.max); options.boundingBox = new BoundingBox(min, max); } var geometry = new Geometry(options); //attributes for (var p in object.attributes) { if (object.attributes.hasOwnProperty(p)) { var attr = object.attributes[p]; geometry.attributes[p] = new Geometry.Attribute(attr.name, attr.type, attr.size, attr.semantic); geometry.attributes[p].value = attr.value; } } return geometry; } }; function copyAttribute(attr, shallow) { return { name : attr.name, type : attr.type, size : attr.size, semantic : attr.semantic, value : copyIfNecessary(attr.value, shallow) }; } function copyIfNecessary(arr, shallow) { if (!shallow) { return new arr.constructor(arr); } else { return arr; } } /** * @name clay.version */ var version = '1.2.1'; var outputEssl$1 = "@export clay.vr.disorter.output.vertex\nattribute vec2 texcoord: TEXCOORD_0;\nattribute vec3 position: POSITION;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n v_Texcoord = texcoord;\n gl_Position = vec4(position.xy, 0.5, 1.0);\n}\n@end\n@export clay.vr.disorter.output.fragment\nuniform sampler2D texture;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n gl_FragColor = texture2D(texture, v_Texcoord);\n}\n@end"; // https://github.com/googlevr/webvr-polyfill/blob/master/src/cardboard-distorter.js // Use webvr may have scale problem. // https://github.com/googlevr/webvr-polyfill/issues/140 // https://github.com/googlevr/webvr-polyfill/search?q=SCALE&type=Issues&utf8=%E2%9C%93 // https://github.com/googlevr/webvr-polyfill/issues/147 Shader.import(outputEssl$1); function lerp (a, b, t) { return a * (1 - t) + b * t; } var CardboardDistorter = Base.extend(function () { return { clearColor: [0, 0, 0, 1], _mesh: new Mesh({ geometry: new Geometry({ dynamic: true }), culling: false, material: new Material({ // FIXME Why disable depthMask will be wrong // depthMask: false, depthTest: false, shader: new Shader({ vertex: Shader.source('clay.vr.disorter.output.vertex'), fragment: Shader.source('clay.vr.disorter.output.fragment') }) }) }), _fakeCamera: new Perspective$1() }; }, { render: function (renderer, sourceTexture) { var clearColor = this.clearColor; var gl = renderer.gl; gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); gl.clear(gl.COLOR_BUFFER_BIT); gl.disable(gl.BLEND); this._mesh.material.set('texture', sourceTexture); // Full size? renderer.saveViewport(); renderer.setViewport(0, 0, renderer.getWidth(), renderer.getHeight()); renderer.renderPass([this._mesh], this._fakeCamera); renderer.restoreViewport(); // this._mesh.material.shader.bind(renderer); // this._mesh.material.bind(renderer); // this._mesh.render(renderer.gl); }, updateFromVRDisplay: function (vrDisplay) { // FIXME if (vrDisplay.deviceInfo_) { // Hardcoded mesh size this._updateMesh(20, 20, vrDisplay.deviceInfo_); } else { console.warn('Cant get vrDisplay.deviceInfo_, seems code changed'); } }, _updateMesh: function (width, height, deviceInfo) { var positionAttr = this._mesh.geometry.attributes.position; var texcoordAttr = this._mesh.geometry.attributes.texcoord0; positionAttr.init(2 * width * height); texcoordAttr.init(2 * width * height); var lensFrustum = deviceInfo.getLeftEyeVisibleTanAngles(); var noLensFrustum = deviceInfo.getLeftEyeNoLensTanAngles(); var viewport = deviceInfo.getLeftEyeVisibleScreenRect(noLensFrustum); var vidx = 0; var pos = []; var uv = []; // Vertices for (var e = 0; e < 2; e++) { for (var j = 0; j < height; j++) { for (var i = 0; i < width; i++, vidx++) { var u = i / (width - 1); var v = j / (height - 1); // Grid points regularly spaced in StreoScreen, and barrel distorted in // the mesh. var s = u; var t = v; var x = lerp(lensFrustum[0], lensFrustum[2], u); var y = lerp(lensFrustum[3], lensFrustum[1], v); var d = Math.sqrt(x * x + y * y); var r = deviceInfo.distortion.distortInverse(d); var p = x * r / d; var q = y * r / d; u = (p - noLensFrustum[0]) / (noLensFrustum[2] - noLensFrustum[0]); v = (q - noLensFrustum[3]) / (noLensFrustum[1] - noLensFrustum[3]); // Convert u,v to mesh screen coordinates. u = (viewport.x + u * viewport.width - 0.5) * 2.0; //* aspect; v = (viewport.y + v * viewport.height - 0.5) * 2.0; pos[0] = u; pos[1] = v; pos[2] = 0; uv[0] = s * 0.5 + e * 0.5; uv[1] = t; positionAttr.set(vidx, pos); texcoordAttr.set(vidx, uv); } } var w = lensFrustum[2] - lensFrustum[0]; lensFrustum[0] = -(w + lensFrustum[0]); lensFrustum[2] = w - lensFrustum[2]; w = noLensFrustum[2] - noLensFrustum[0]; noLensFrustum[0] = -(w + noLensFrustum[0]); noLensFrustum[2] = w - noLensFrustum[2]; viewport.x = 1 - (viewport.x + viewport.width); } // Indices var indices = new Uint16Array(2 * (width - 1) * (height - 1) * 6); var halfwidth = width / 2; var halfheight = height / 2; var vidx = 0; var iidx = 0; for (var e = 0; e < 2; e++) { for (var j = 0; j < height; j++) { for (var i = 0; i < width; i++, vidx++) { if (i === 0 || j === 0) { continue; } // Build a quad. Lower right and upper left quadrants have quads with // the triangle diagonal flipped to get the vignette to interpolate // correctly. if ((i <= halfwidth) == (j <= halfheight)) { // Quad diagonal lower left to upper right. indices[iidx++] = vidx; indices[iidx++] = vidx - width - 1; indices[iidx++] = vidx - width; indices[iidx++] = vidx - width - 1; indices[iidx++] = vidx; indices[iidx++] = vidx - 1; } else { // Quad diagonal upper left to lower right. indices[iidx++] = vidx - 1; indices[iidx++] = vidx - width; indices[iidx++] = vidx; indices[iidx++] = vidx - width; indices[iidx++] = vidx - 1; indices[iidx++] = vidx - width - 1; } } } } this._mesh.geometry.indices = indices; this._mesh.geometry.dirty(); } }); var tmpProjectionMatrix = new Matrix4(); var StereoCamera = Node.extend(function () { return { aspect: 0.5, _leftCamera: new Perspective$1(), _rightCamera: new Perspective$1(), _eyeLeft: new Matrix4(), _eyeRight: new Matrix4(), _frameData: null }; }, { updateFromCamera: function (camera, focus, zoom, eyeSep) { if (camera.transformNeedsUpdate()) { console.warn('Node transform is not updated'); } focus = focus == null ? 10 : focus; zoom = zoom == null ? 1 : zoom; eyeSep = eyeSep == null ? 0.064 : eyeSep; var fov = camera.fov; var aspect = camera.aspect * this.aspect; var near = camera.near; // Off-axis stereoscopic effect based on // http://paulbourke.net/stereographics/stereorender/ tmpProjectionMatrix.copy(camera.projectionMatrix); var eyeSep = eyeSep / 2; var eyeSepOnProjection = eyeSep * near / focus; var ymax = (near * Math.tan(Math.PI / 180 * fov * 0.5 ) ) / zoom; var xmin, xmax; // translate xOffset this._eyeLeft.array[12] = - eyeSep; this._eyeRight.array[12] = eyeSep; // for left eye xmin = - ymax * aspect + eyeSepOnProjection; xmax = ymax * aspect + eyeSepOnProjection; tmpProjectionMatrix.array[0] = 2 * near / (xmax - xmin); tmpProjectionMatrix.array[8] = (xmax + xmin ) / (xmax - xmin); this._leftCamera.projectionMatrix.copy(tmpProjectionMatrix); // for right eye xmin = - ymax * aspect - eyeSepOnProjection; xmax = ymax * aspect - eyeSepOnProjection; tmpProjectionMatrix.array[0] = 2 * near / (xmax - xmin); tmpProjectionMatrix.array[8] = (xmax + xmin ) / (xmax - xmin); this._rightCamera.projectionMatrix.copy(tmpProjectionMatrix); this._leftCamera.worldTransform .copy(camera.worldTransform) .multiply(this._eyeLeft); this._rightCamera.worldTransform .copy(camera.worldTransform) .multiply(this._eyeRight); this._leftCamera.decomposeWorldTransform(); this._leftCamera.decomposeProjectionMatrix(); this._rightCamera.decomposeWorldTransform(); this._rightCamera.decomposeProjectionMatrix(); }, updateFromVRDisplay: function (vrDisplay, parentNode) { if (typeof VRFrameData === 'undefined') { return; } var frameData = this._frameData || (this._frameData = new VRFrameData()); vrDisplay.getFrameData(frameData); var leftCamera = this._leftCamera; var rightCamera = this._rightCamera; leftCamera.projectionMatrix.setArray(frameData.leftProjectionMatrix); leftCamera.decomposeProjectionMatrix(); leftCamera.viewMatrix.setArray(frameData.leftViewMatrix); leftCamera.setViewMatrix(leftCamera.viewMatrix); rightCamera.projectionMatrix.setArray(frameData.rightProjectionMatrix); rightCamera.decomposeProjectionMatrix(); rightCamera.viewMatrix.setArray(frameData.rightViewMatrix); rightCamera.setViewMatrix(rightCamera.viewMatrix); if (parentNode && parentNode.worldTransform) { if (parentNode.transformNeedsUpdate()) { console.warn('Node transform is not updated'); } leftCamera.worldTransform.multiplyLeft(parentNode.worldTransform); leftCamera.decomposeWorldTransform(); rightCamera.worldTransform.multiplyLeft(parentNode.worldTransform); rightCamera.decomposeWorldTransform(); } }, getLeftCamera: function () { return this._leftCamera; }, getRightCamera: function () { return this._rightCamera; } }); /** @namespace clay */ /** @namespace clay.math */ /** @namespace clay.animation */ /** @namespace clay.async */ /** @namespace clay.camera */ /** @namespace clay.compositor */ /** @namespace clay.core */ /** @namespace clay.geometry */ /** @namespace clay.helper */ /** @namespace clay.light */ /** @namespace clay.loader */ /** @namespace clay.particle */ /** @namespace clay.plugin */ /** @namespace clay.prePass */ /** @namespace clay.shader */ /** @namespace clay.texture */ /** @namespace clay.util */ var animation = { Animator : Animator, Blend1DClip : Blend1DClip, Blend2DClip : Blend2DClip, Clip : Clip, easing : easing, SamplerTrack : SamplerTrack, Timeline : Timeline, TrackClip : TrackClip }; var async = { Task : Task, TaskGroup : TaskGroup }; var camera = { Orthographic : Orthographic$1, Perspective : Perspective$1 }; var compositor = { Compositor : Compositor, CompositorNode : CompositorNode, createCompositor : createCompositor, FilterNode : FilterNode$1, Graph : Graph, Pass : Pass, SceneNode : SceneNode$1, TextureNode : TextureNode$1, TexturePool : TexturePool }; var core = { Base : Base, Cache : Cache, color : colorUtil, glenum : glenum, GLInfo : GLInfo, LinkedList : LinkedList, LRU : LRU$1, mixin : { extend : extendMixin, notifier : notifier }, request : request, util : util$1, vendor : vendor }; var deferred = { GBuffer : GBuffer, Renderer : DeferredRenderer }; var dep = { glmatrix : glmatrix }; var geometry = { Cone : Cone$1, Cube : Cube$1, Cylinder : Cylinder$1, ParametricSurface : ParametricSurface$1, Plane : Plane$3, Sphere : Sphere$1 }; var light = { Ambient : AmbientLight, AmbientCubemap : AmbientCubemapLight, AmbientSH : AmbientSHLight, Directional : DirectionalLight, Point : PointLight, Sphere : SphereLight, Spot : SpotLight, Tube : TubeLight }; var loader = { FX : FXLoader, GLTF : GLTFLoader }; var math = { BoundingBox : BoundingBox, Frustum : Frustum, Matrix2 : Matrix2, Matrix2d : Matrix2d, Matrix3 : Matrix3, Matrix4 : Matrix4, Plane : Plane$1, Quaternion : Quaternion, Ray : Ray, util : mathUtil, Value : Value, Vector2 : Vector2, Vector3 : Vector3, Vector4 : Vector4 }; var particle = { Emitter : Emitter, Field : Field, ForceField : ForceField, Particle : Particle, ParticleRenderable : ParticleRenderable }; var picking = { PixelPicking : PixelPicking, RayPicking : RayPicking }; var plugin = { FreeControl : FreeControl, GamepadControl : GamepadControl, GestureMgr : GestureMgr, InfinitePlane : InfinitePlane, OrbitControl : OrbitControl, Skybox : Skybox$1, Skydome : Skybox$1 }; var prePass = { EnvironmentMap : EnvironmentMapPass, ShadowMap : ShadowMapPass }; var shader = { library : library, registerBuiltinCompositor : register, source : { header : { light : lightEssl } } }; var util = { cubemap : cubemapUtil, dds : ret, delaunay : delaunay, hdr : ret$1, mesh : meshUtil, sh : sh, texture : textureUtil, transferable : transferableUtil }; var vr = { CardboardDistorter : CardboardDistorter, StereoCamera : StereoCamera }; exports.animation = animation; exports.application = application; exports.async = async; exports.Camera = Camera; exports.camera = camera; exports.compositor = compositor; exports.core = core; exports.createCompositor = createCompositor; exports.deferred = deferred; exports.dep = dep; exports.FrameBuffer = FrameBuffer; exports.Geometry = Geometry; exports.geometry = geometry; exports.GeometryBase = GeometryBase; exports.Joint = Joint; exports.Light = Light; exports.light = light; exports.loader = loader; exports.Material = Material; exports.math = math; exports.BoundingBox = BoundingBox; exports.Frustum = Frustum; exports.Matrix2 = Matrix2; exports.Matrix2d = Matrix2d; exports.Matrix3 = Matrix3; exports.Matrix4 = Matrix4; exports.Plane = Plane$1; exports.Quaternion = Quaternion; exports.Ray = Ray; exports.Value = Value; exports.Vector2 = Vector2; exports.Vector3 = Vector3; exports.Vector4 = Vector4; exports.Mesh = Mesh; exports.Node = Node; exports.particle = particle; exports.picking = picking; exports.plugin = plugin; exports.prePass = prePass; exports.Renderable = Renderable; exports.Renderer = Renderer; exports.Scene = Scene; exports.Shader = Shader; exports.shader = shader; exports.Skeleton = Skeleton; exports.StandardMaterial = StandardMaterial; exports.StaticGeometry = StaticGeometry; exports.Texture = Texture; exports.Texture2D = Texture2D; exports.TextureCube = TextureCube; exports.Timeline = Timeline; exports.util = util; exports.version = version; exports.vr = vr; Object.defineProperty(exports, '__esModule', { value: true }); }))); ================================================ FILE: test/lib/dat.gui.js ================================================ /** * dat-gui JavaScript Controller Library * http://code.google.com/p/dat-gui * * Copyright 2011 Data Arts Team, Google Creative Lab * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 */ var dat=dat||{};dat.gui=dat.gui||{};dat.utils=dat.utils||{};dat.controllers=dat.controllers||{};dat.dom=dat.dom||{};dat.color=dat.color||{};dat.utils.css=function(){return{load:function(e,a){var a=a||document,c=a.createElement("link");c.type="text/css";c.rel="stylesheet";c.href=e;a.getElementsByTagName("head")[0].appendChild(c)},inject:function(e,a){var a=a||document,c=document.createElement("style");c.type="text/css";c.innerHTML=e;a.getElementsByTagName("head")[0].appendChild(c)}}}(); dat.utils.common=function(){var e=Array.prototype.forEach,a=Array.prototype.slice;return{BREAK:{},extend:function(c){this.each(a.call(arguments,1),function(a){for(var f in a)this.isUndefined(a[f])||(c[f]=a[f])},this);return c},defaults:function(c){this.each(a.call(arguments,1),function(a){for(var f in a)this.isUndefined(c[f])&&(c[f]=a[f])},this);return c},compose:function(){var c=a.call(arguments);return function(){for(var d=a.call(arguments),f=c.length-1;f>=0;f--)d=[c[f].apply(this,d)];return d[0]}}, each:function(a,d,f){if(e&&a.forEach===e)a.forEach(d,f);else if(a.length===a.length+0)for(var b=0,n=a.length;b-1?d.length-d.indexOf(".")-1:0};c.superclass=e;a.extend(c.prototype,e.prototype,{setValue:function(a){if(this.__min!==void 0&&athis.__max)a=this.__max;this.__step!==void 0&&a%this.__step!=0&&(a=Math.round(a/this.__step)*this.__step);return c.superclass.prototype.setValue.call(this,a)},min:function(a){this.__min=a;return this},max:function(a){this.__max=a;return this},step:function(a){this.__step=a;return this}});return c}(dat.controllers.Controller,dat.utils.common); dat.controllers.NumberControllerBox=function(e,a,c){var d=function(f,b,e){function h(){var a=parseFloat(l.__input.value);c.isNaN(a)||l.setValue(a)}function j(a){var b=o-a.clientY;l.setValue(l.getValue()+b*l.__impliedStep);o=a.clientY}function m(){a.unbind(window,"mousemove",j);a.unbind(window,"mouseup",m)}this.__truncationSuspended=false;d.superclass.call(this,f,b,e);var l=this,o;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"change",h); a.bind(this.__input,"blur",function(){h();l.__onFinishChange&&l.__onFinishChange.call(l,l.getValue())});a.bind(this.__input,"mousedown",function(b){a.bind(window,"mousemove",j);a.bind(window,"mouseup",m);o=b.clientY});a.bind(this.__input,"keydown",function(a){if(a.keyCode===13)l.__truncationSuspended=true,this.blur(),l.__truncationSuspended=false});this.updateDisplay();this.domElement.appendChild(this.__input)};d.superclass=e;c.extend(d.prototype,e.prototype,{updateDisplay:function(){var a=this.__input, b;if(this.__truncationSuspended)b=this.getValue();else{b=this.getValue();var c=Math.pow(10,this.__precision);b=Math.round(b*c)/c}a.value=b;return d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.NumberController,dat.dom.dom,dat.utils.common); dat.controllers.NumberControllerSlider=function(e,a,c,d,f){var b=function(d,c,f,e,l){function o(b){b.preventDefault();var d=a.getOffset(g.__background),c=a.getWidth(g.__background);g.setValue(g.__min+(g.__max-g.__min)*((b.clientX-d.left)/(d.left+c-d.left)));return false}function y(){a.unbind(window,"mousemove",o);a.unbind(window,"mouseup",y);g.__onFinishChange&&g.__onFinishChange.call(g,g.getValue())}b.superclass.call(this,d,c,{min:f,max:e,step:l});var g=this;this.__background=document.createElement("div"); this.__foreground=document.createElement("div");a.bind(this.__background,"mousedown",function(b){a.bind(window,"mousemove",o);a.bind(window,"mouseup",y);o(b)});a.addClass(this.__background,"slider");a.addClass(this.__foreground,"slider-fg");this.updateDisplay();this.__background.appendChild(this.__foreground);this.domElement.appendChild(this.__background)};b.superclass=e;b.useDefaultStyles=function(){c.inject(f)};d.extend(b.prototype,e.prototype,{updateDisplay:function(){this.__foreground.style.width= (this.getValue()-this.__min)/(this.__max-this.__min)*100+"%";return b.superclass.prototype.updateDisplay.call(this)}});return b}(dat.controllers.NumberController,dat.dom.dom,dat.utils.css,dat.utils.common,".slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}"); dat.controllers.FunctionController=function(e,a,c){var d=function(c,b,e){d.superclass.call(this,c,b);var h=this;this.__button=document.createElement("div");this.__button.innerHTML=e===void 0?"Fire":e;a.bind(this.__button,"click",function(a){a.preventDefault();h.fire();return false});a.addClass(this.__button,"button");this.domElement.appendChild(this.__button)};d.superclass=e;c.extend(d.prototype,e.prototype,{fire:function(){this.__onChange&&this.__onChange.call(this);this.__onFinishChange&&this.__onFinishChange.call(this, this.getValue());this.getValue().call(this.object)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common); dat.controllers.BooleanController=function(e,a,c){var d=function(c,b){d.superclass.call(this,c,b);var e=this;this.__prev=this.getValue();this.__checkbox=document.createElement("input");this.__checkbox.setAttribute("type","checkbox");a.bind(this.__checkbox,"change",function(){e.setValue(!e.__prev)},false);this.domElement.appendChild(this.__checkbox);this.updateDisplay()};d.superclass=e;c.extend(d.prototype,e.prototype,{setValue:function(a){a=d.superclass.prototype.setValue.call(this,a);this.__onFinishChange&& this.__onFinishChange.call(this,this.getValue());this.__prev=this.getValue();return a},updateDisplay:function(){this.getValue()===true?(this.__checkbox.setAttribute("checked","checked"),this.__checkbox.checked=true):this.__checkbox.checked=false;return d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common); dat.color.toString=function(e){return function(a){if(a.a==1||e.isUndefined(a.a)){for(a=a.hex.toString(16);a.length<6;)a="0"+a;return"#"+a}else return"rgba("+Math.round(a.r)+","+Math.round(a.g)+","+Math.round(a.b)+","+a.a+")"}}(dat.utils.common); dat.color.interpret=function(e,a){var c,d,f=[{litmus:a.isString,conversions:{THREE_CHAR_HEX:{read:function(a){a=a.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);return a===null?false:{space:"HEX",hex:parseInt("0x"+a[1].toString()+a[1].toString()+a[2].toString()+a[2].toString()+a[3].toString()+a[3].toString())}},write:e},SIX_CHAR_HEX:{read:function(a){a=a.match(/^#([A-F0-9]{6})$/i);return a===null?false:{space:"HEX",hex:parseInt("0x"+a[1].toString())}},write:e},CSS_RGB:{read:function(a){a=a.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/); return a===null?false:{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3])}},write:e},CSS_RGBA:{read:function(a){a=a.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/);return a===null?false:{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3]),a:parseFloat(a[4])}},write:e}}},{litmus:a.isNumber,conversions:{HEX:{read:function(a){return{space:"HEX",hex:a,conversionName:"HEX"}},write:function(a){return a.hex}}}},{litmus:a.isArray,conversions:{RGB_ARRAY:{read:function(a){return a.length!= 3?false:{space:"RGB",r:a[0],g:a[1],b:a[2]}},write:function(a){return[a.r,a.g,a.b]}},RGBA_ARRAY:{read:function(a){return a.length!=4?false:{space:"RGB",r:a[0],g:a[1],b:a[2],a:a[3]}},write:function(a){return[a.r,a.g,a.b,a.a]}}}},{litmus:a.isObject,conversions:{RGBA_OBJ:{read:function(b){return a.isNumber(b.r)&&a.isNumber(b.g)&&a.isNumber(b.b)&&a.isNumber(b.a)?{space:"RGB",r:b.r,g:b.g,b:b.b,a:b.a}:false},write:function(a){return{r:a.r,g:a.g,b:a.b,a:a.a}}},RGB_OBJ:{read:function(b){return a.isNumber(b.r)&& a.isNumber(b.g)&&a.isNumber(b.b)?{space:"RGB",r:b.r,g:b.g,b:b.b}:false},write:function(a){return{r:a.r,g:a.g,b:a.b}}},HSVA_OBJ:{read:function(b){return a.isNumber(b.h)&&a.isNumber(b.s)&&a.isNumber(b.v)&&a.isNumber(b.a)?{space:"HSV",h:b.h,s:b.s,v:b.v,a:b.a}:false},write:function(a){return{h:a.h,s:a.s,v:a.v,a:a.a}}},HSV_OBJ:{read:function(b){return a.isNumber(b.h)&&a.isNumber(b.s)&&a.isNumber(b.v)?{space:"HSV",h:b.h,s:b.s,v:b.v}:false},write:function(a){return{h:a.h,s:a.s,v:a.v}}}}}];return function(){d= false;var b=arguments.length>1?a.toArray(arguments):arguments[0];a.each(f,function(e){if(e.litmus(b))return a.each(e.conversions,function(e,f){c=e.read(b);if(d===false&&c!==false)return d=c,c.conversionName=f,c.conversion=e,a.BREAK}),a.BREAK});return d}}(dat.color.toString,dat.utils.common); dat.GUI=dat.gui.GUI=function(e,a,c,d,f,b,n,h,j,m,l,o,y,g,i){function q(a,b,r,c){if(b[r]===void 0)throw Error("Object "+b+' has no property "'+r+'"');c.color?b=new l(b,r):(b=[b,r].concat(c.factoryArgs),b=d.apply(a,b));if(c.before instanceof f)c.before=c.before.__li;t(a,b);g.addClass(b.domElement,"c");r=document.createElement("span");g.addClass(r,"property-name");r.innerHTML=b.property;var e=document.createElement("div");e.appendChild(r);e.appendChild(b.domElement);c=s(a,e,c.before);g.addClass(c,k.CLASS_CONTROLLER_ROW); g.addClass(c,typeof b.getValue());p(a,c,b);a.__controllers.push(b);return b}function s(a,b,d){var c=document.createElement("li");b&&c.appendChild(b);d?a.__ul.insertBefore(c,params.before):a.__ul.appendChild(c);a.onResize();return c}function p(a,d,c){c.__li=d;c.__gui=a;i.extend(c,{options:function(b){if(arguments.length>1)return c.remove(),q(a,c.object,c.property,{before:c.__li.nextElementSibling,factoryArgs:[i.toArray(arguments)]});if(i.isArray(b)||i.isObject(b))return c.remove(),q(a,c.object,c.property, {before:c.__li.nextElementSibling,factoryArgs:[b]})},name:function(a){c.__li.firstElementChild.firstElementChild.innerHTML=a;return c},listen:function(){c.__gui.listen(c);return c},remove:function(){c.__gui.remove(c);return c}});if(c instanceof j){var e=new h(c.object,c.property,{min:c.__min,max:c.__max,step:c.__step});i.each(["updateDisplay","onChange","onFinishChange"],function(a){var b=c[a],H=e[a];c[a]=e[a]=function(){var a=Array.prototype.slice.call(arguments);b.apply(c,a);return H.apply(e,a)}}); g.addClass(d,"has-slider");c.domElement.insertBefore(e.domElement,c.domElement.firstElementChild)}else if(c instanceof h){var f=function(b){return i.isNumber(c.__min)&&i.isNumber(c.__max)?(c.remove(),q(a,c.object,c.property,{before:c.__li.nextElementSibling,factoryArgs:[c.__min,c.__max,c.__step]})):b};c.min=i.compose(f,c.min);c.max=i.compose(f,c.max)}else if(c instanceof b)g.bind(d,"click",function(){g.fakeEvent(c.__checkbox,"click")}),g.bind(c.__checkbox,"click",function(a){a.stopPropagation()}); else if(c instanceof n)g.bind(d,"click",function(){g.fakeEvent(c.__button,"click")}),g.bind(d,"mouseover",function(){g.addClass(c.__button,"hover")}),g.bind(d,"mouseout",function(){g.removeClass(c.__button,"hover")});else if(c instanceof l)g.addClass(d,"color"),c.updateDisplay=i.compose(function(a){d.style.borderLeftColor=c.__color.toString();return a},c.updateDisplay),c.updateDisplay();c.setValue=i.compose(function(b){a.getRoot().__preset_select&&c.isModified()&&B(a.getRoot(),true);return b},c.setValue)} function t(a,b){var c=a.getRoot(),d=c.__rememberedObjects.indexOf(b.object);if(d!=-1){var e=c.__rememberedObjectIndecesToControllers[d];e===void 0&&(e={},c.__rememberedObjectIndecesToControllers[d]=e);e[b.property]=b;if(c.load&&c.load.remembered){c=c.load.remembered;if(c[a.preset])c=c[a.preset];else if(c[w])c=c[w];else return;if(c[d]&&c[d][b.property]!==void 0)d=c[d][b.property],b.initialValue=d,b.setValue(d)}}}function I(a){var b=a.__save_row=document.createElement("li");g.addClass(a.domElement, "has-save");a.__ul.insertBefore(b,a.__ul.firstChild);g.addClass(b,"save-row");var c=document.createElement("span");c.innerHTML=" ";g.addClass(c,"button gears");var d=document.createElement("span");d.innerHTML="Save";g.addClass(d,"button");g.addClass(d,"save");var e=document.createElement("span");e.innerHTML="New";g.addClass(e,"button");g.addClass(e,"save-as");var f=document.createElement("span");f.innerHTML="Revert";g.addClass(f,"button");g.addClass(f,"revert");var m=a.__preset_select=document.createElement("select"); a.load&&a.load.remembered?i.each(a.load.remembered,function(b,c){C(a,c,c==a.preset)}):C(a,w,false);g.bind(m,"change",function(){for(var b=0;b0){a.preset=this.preset;if(!a.remembered)a.remembered={};a.remembered[this.preset]=z(this)}a.folders={};i.each(this.__folders,function(b, c){a.folders[c]=b.getSaveObject()});return a},save:function(){if(!this.load.remembered)this.load.remembered={};this.load.remembered[this.preset]=z(this);B(this,false)},saveAs:function(a){if(!this.load.remembered)this.load.remembered={},this.load.remembered[w]=z(this,true);this.load.remembered[a]=z(this);this.preset=a;C(this,a,true)},revert:function(a){i.each(this.__controllers,function(b){this.getRoot().load.remembered?t(a||this.getRoot(),b):b.setValue(b.initialValue)},this);i.each(this.__folders, function(a){a.revert(a)});a||B(this.getRoot(),false)},listen:function(a){var b=this.__listening.length==0;this.__listening.push(a);b&&E(this.__listening)}});return k}(dat.utils.css,'
\n\n Here\'s the new load parameter for your GUI\'s constructor:\n\n \n\n
\n\n Automatically save\n values to localStorage on exit.\n\n
The values saved to localStorage will\n override those passed to dat.GUI\'s constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n
\n \n
\n\n
', ".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear;border:0;position:absolute;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-x:hidden}.dg.a.has-save ul{margin-top:27px}.dg.a.has-save ul.closed{margin-top:0}.dg.a .save-row{position:fixed;top:0;z-index:1002}.dg li{-webkit-transition:height 0.1s ease-out;-o-transition:height 0.1s ease-out;-moz-transition:height 0.1s ease-out;transition:height 0.1s ease-out}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;overflow:hidden;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li > *{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:9px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2fa1d6}.dg .cr.number input[type=text]{color:#2fa1d6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2fa1d6}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n", dat.controllers.factory=function(e,a,c,d,f,b,n){return function(h,j,m,l){var o=h[j];if(n.isArray(m)||n.isObject(m))return new e(h,j,m);if(n.isNumber(o))return n.isNumber(m)&&n.isNumber(l)?new c(h,j,m,l):new a(h,j,{min:m,max:l});if(n.isString(o))return new d(h,j);if(n.isFunction(o))return new f(h,j,"");if(n.isBoolean(o))return new b(h,j)}}(dat.controllers.OptionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.StringController=function(e,a,c){var d= function(c,b){function e(){h.setValue(h.__input.value)}d.superclass.call(this,c,b);var h=this;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"keyup",e);a.bind(this.__input,"change",e);a.bind(this.__input,"blur",function(){h.__onFinishChange&&h.__onFinishChange.call(h,h.getValue())});a.bind(this.__input,"keydown",function(a){a.keyCode===13&&this.blur()});this.updateDisplay();this.domElement.appendChild(this.__input)};d.superclass=e;c.extend(d.prototype, e.prototype,{updateDisplay:function(){if(!a.isActive(this.__input))this.__input.value=this.getValue();return d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common),dat.controllers.FunctionController,dat.controllers.BooleanController,dat.utils.common),dat.controllers.Controller,dat.controllers.BooleanController,dat.controllers.FunctionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.OptionController, dat.controllers.ColorController=function(e,a,c,d,f){function b(a,b,c,d){a.style.background="";f.each(j,function(e){a.style.cssText+="background: "+e+"linear-gradient("+b+", "+c+" 0%, "+d+" 100%); "})}function n(a){a.style.background="";a.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);";a.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"; a.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";a.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";a.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}var h=function(e,l){function o(b){q(b);a.bind(window,"mousemove",q);a.bind(window, "mouseup",j)}function j(){a.unbind(window,"mousemove",q);a.unbind(window,"mouseup",j)}function g(){var a=d(this.value);a!==false?(p.__color.__state=a,p.setValue(p.__color.toOriginal())):this.value=p.__color.toString()}function i(){a.unbind(window,"mousemove",s);a.unbind(window,"mouseup",i)}function q(b){b.preventDefault();var c=a.getWidth(p.__saturation_field),d=a.getOffset(p.__saturation_field),e=(b.clientX-d.left+document.body.scrollLeft)/c,b=1-(b.clientY-d.top+document.body.scrollTop)/c;b>1?b= 1:b<0&&(b=0);e>1?e=1:e<0&&(e=0);p.__color.v=b;p.__color.s=e;p.setValue(p.__color.toOriginal());return false}function s(b){b.preventDefault();var c=a.getHeight(p.__hue_field),d=a.getOffset(p.__hue_field),b=1-(b.clientY-d.top+document.body.scrollTop)/c;b>1?b=1:b<0&&(b=0);p.__color.h=b*360;p.setValue(p.__color.toOriginal());return false}h.superclass.call(this,e,l);this.__color=new c(this.getValue());this.__temp=new c(0);var p=this;this.domElement=document.createElement("div");a.makeSelectable(this.domElement, false);this.__selector=document.createElement("div");this.__selector.className="selector";this.__saturation_field=document.createElement("div");this.__saturation_field.className="saturation-field";this.__field_knob=document.createElement("div");this.__field_knob.className="field-knob";this.__field_knob_border="2px solid ";this.__hue_knob=document.createElement("div");this.__hue_knob.className="hue-knob";this.__hue_field=document.createElement("div");this.__hue_field.className="hue-field";this.__input= document.createElement("input");this.__input.type="text";this.__input_textShadow="0 1px 1px ";a.bind(this.__input,"keydown",function(a){a.keyCode===13&&g.call(this)});a.bind(this.__input,"blur",g);a.bind(this.__selector,"mousedown",function(){a.addClass(this,"drag").bind(window,"mouseup",function(){a.removeClass(p.__selector,"drag")})});var t=document.createElement("div");f.extend(this.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"}); f.extend(this.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:this.__field_knob_border+(this.__color.v<0.5?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1});f.extend(this.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1});f.extend(this.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"});f.extend(t.style, {width:"100%",height:"100%",background:"none"});b(t,"top","rgba(0,0,0,0)","#000");f.extend(this.__hue_field.style,{width:"15px",height:"100px",display:"inline-block",border:"1px solid #555",cursor:"ns-resize"});n(this.__hue_field);f.extend(this.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:this.__input_textShadow+"rgba(0,0,0,0.7)"});a.bind(this.__saturation_field,"mousedown",o);a.bind(this.__field_knob,"mousedown",o);a.bind(this.__hue_field,"mousedown", function(b){s(b);a.bind(window,"mousemove",s);a.bind(window,"mouseup",i)});this.__saturation_field.appendChild(t);this.__selector.appendChild(this.__field_knob);this.__selector.appendChild(this.__saturation_field);this.__selector.appendChild(this.__hue_field);this.__hue_field.appendChild(this.__hue_knob);this.domElement.appendChild(this.__input);this.domElement.appendChild(this.__selector);this.updateDisplay()};h.superclass=e;f.extend(h.prototype,e.prototype,{updateDisplay:function(){var a=d(this.getValue()); if(a!==false){var e=false;f.each(c.COMPONENTS,function(b){if(!f.isUndefined(a[b])&&!f.isUndefined(this.__color.__state[b])&&a[b]!==this.__color.__state[b])return e=true,{}},this);e&&f.extend(this.__color.__state,a)}f.extend(this.__temp.__state,this.__color.__state);this.__temp.a=1;var h=this.__color.v<0.5||this.__color.s>0.5?255:0,j=255-h;f.extend(this.__field_knob.style,{marginLeft:100*this.__color.s-7+"px",marginTop:100*(1-this.__color.v)-7+"px",backgroundColor:this.__temp.toString(),border:this.__field_knob_border+ "rgb("+h+","+h+","+h+")"});this.__hue_knob.style.marginTop=(1-this.__color.h/360)*100+"px";this.__temp.s=1;this.__temp.v=1;b(this.__saturation_field,"left","#fff",this.__temp.toString());f.extend(this.__input.style,{backgroundColor:this.__input.value=this.__color.toString(),color:"rgb("+h+","+h+","+h+")",textShadow:this.__input_textShadow+"rgba("+j+","+j+","+j+",.7)"})}});var j=["-moz-","-o-","-webkit-","-ms-",""];return h}(dat.controllers.Controller,dat.dom.dom,dat.color.Color=function(e,a,c,d){function f(a, b,c){Object.defineProperty(a,b,{get:function(){if(this.__state.space==="RGB")return this.__state[b];n(this,b,c);return this.__state[b]},set:function(a){if(this.__state.space!=="RGB")n(this,b,c),this.__state.space="RGB";this.__state[b]=a}})}function b(a,b){Object.defineProperty(a,b,{get:function(){if(this.__state.space==="HSV")return this.__state[b];h(this);return this.__state[b]},set:function(a){if(this.__state.space!=="HSV")h(this),this.__state.space="HSV";this.__state[b]=a}})}function n(b,c,e){if(b.__state.space=== "HEX")b.__state[c]=a.component_from_hex(b.__state.hex,e);else if(b.__state.space==="HSV")d.extend(b.__state,a.hsv_to_rgb(b.__state.h,b.__state.s,b.__state.v));else throw"Corrupted color state";}function h(b){var c=a.rgb_to_hsv(b.r,b.g,b.b);d.extend(b.__state,{s:c.s,v:c.v});if(d.isNaN(c.h)){if(d.isUndefined(b.__state.h))b.__state.h=0}else b.__state.h=c.h}var j=function(){this.__state=e.apply(this,arguments);if(this.__state===false)throw"Failed to interpret color arguments";this.__state.a=this.__state.a|| 1};j.COMPONENTS="r,g,b,h,s,v,hex,a".split(",");d.extend(j.prototype,{toString:function(){return c(this)},toOriginal:function(){return this.__state.conversion.write(this)}});f(j.prototype,"r",2);f(j.prototype,"g",1);f(j.prototype,"b",0);b(j.prototype,"h");b(j.prototype,"s");b(j.prototype,"v");Object.defineProperty(j.prototype,"a",{get:function(){return this.__state.a},set:function(a){this.__state.a=a}});Object.defineProperty(j.prototype,"hex",{get:function(){if(!this.__state.space!=="HEX")this.__state.hex= a.rgb_to_hex(this.r,this.g,this.b);return this.__state.hex},set:function(a){this.__state.space="HEX";this.__state.hex=a}});return j}(dat.color.interpret,dat.color.math=function(){var e;return{hsv_to_rgb:function(a,c,d){var e=a/60-Math.floor(a/60),b=d*(1-c),n=d*(1-e*c),c=d*(1-(1-e)*c),a=[[d,c,b],[n,d,b],[b,d,c],[b,n,d],[c,b,d],[d,b,n]][Math.floor(a/60)%6];return{r:a[0]*255,g:a[1]*255,b:a[2]*255}},rgb_to_hsv:function(a,c,d){var e=Math.min(a,c,d),b=Math.max(a,c,d),e=b-e;if(b==0)return{h:NaN,s:0,v:0}; a=a==b?(c-d)/e:c==b?2+(d-a)/e:4+(a-c)/e;a/=6;a<0&&(a+=1);return{h:a*360,s:e/b,v:b/255}},rgb_to_hex:function(a,c,d){a=this.hex_with_component(0,2,a);a=this.hex_with_component(a,1,c);return a=this.hex_with_component(a,0,d)},component_from_hex:function(a,c){return a>>c*8&255},hex_with_component:function(a,c,d){return d<<(e=c*8)|a&~(255< Polygon Offset Test ================================================ FILE: test/polyline-offset.html ================================================ Polyline Offset Test ================================================ FILE: test/slerp.html ================================================ Slerp Test ================================================ FILE: test/street.html ================================================ Street Polylines Example