├── .babelrc ├── .gitignore ├── .vscode └── settings.json ├── README.md ├── config └── webpack.config.js ├── data_streets.json ├── dist └── main.js ├── icon.png ├── index.html ├── index.js ├── lib ├── Pure3 │ ├── Circle.purs │ ├── Interpolate.purs │ ├── Line.purs │ ├── Point.purs │ ├── Scene.purs │ ├── Square.purs │ ├── Tesselate.purs │ ├── Transform.purs │ └── Utils.purs ├── ffi-utils │ ├── index.js │ └── package.json ├── pure3 │ └── Types.purs └── three-ffi │ ├── Camera │ ├── Camera.js │ └── Camera.purs │ ├── Core │ ├── Geometry │ │ ├── Geometry.js │ │ └── Geometry.purs │ └── Object3D │ │ ├── Object3D.js │ │ └── Object3D.purs │ ├── Extras │ └── Core │ │ └── Shape │ │ ├── Shape.js │ │ └── Shape.purs │ ├── Geometry │ ├── BoxGeometry │ │ ├── BoxGeometry.js │ │ └── BoxGeometry.purs │ ├── ExtrudeGeometry │ │ ├── ExtrudeGeometry.js │ │ └── ExtrudeGeometry.purs │ └── PlaneGeometry │ │ ├── PlaneGeometry.js │ │ └── PlaneGeometry.purs │ ├── Material │ ├── LineBasicMaterial │ │ ├── LineBasicMaterial.js │ │ └── LineBasicMaterial.purs │ ├── MeshBasicMaterial │ │ ├── MeshBasicMaterial.js │ │ └── MeshBasicMaterial.purs │ ├── MeshNormalMaterial │ │ ├── MeshNormalMaterial.js │ │ └── MeshNormalMaterial.purs │ ├── MeshPhongMaterial │ │ ├── MeshPhongMaterial.js │ │ └── MeshPhongMaterial.purs │ └── PointsMaterial │ │ ├── PointsMaterial.js │ │ └── PointsMaterial.purs │ ├── Math │ ├── Math.js │ └── Math.purs │ ├── Object3D │ ├── Light │ │ ├── AmbientLight │ │ │ ├── AmbientLight.js │ │ │ └── AmbientLight.purs │ │ ├── DirectionalLight │ │ │ ├── DirectionalLight.js │ │ │ └── DirectionalLight.purs │ │ └── HemisphereLight │ │ │ ├── HemisphereLight.js │ │ │ └── HemisphereLight.purs │ ├── Line │ │ ├── Line.js │ │ └── Line.purs │ ├── Mesh │ │ ├── Mesh.js │ │ └── Mesh.purs │ └── Points │ │ ├── Points.js │ │ └── Points.purs │ ├── OrbitControls │ ├── OrbitControls.js │ └── OrbitControls.purs │ ├── Renderer │ ├── Renderer.js │ └── Renderer.purs │ ├── Scene │ ├── Scene.js │ └── Scene.purs │ ├── Three.js │ ├── Three.purs │ └── Types.purs ├── manifest.json ├── package-lock.json ├── package.json ├── psc-package.json ├── run-dev.sh ├── scripts ├── building_importer.js ├── buildings.json ├── buildings_se228np_1km.json ├── data.json └── se228np_1km.json ├── src ├── Editor │ └── main.js ├── Main.purs └── Projects │ ├── BaseProject │ └── BaseProject.purs │ ├── CircleStuff │ ├── CircleStuff.purs │ └── Main.purs │ ├── Foo │ ├── Foo.purs │ └── Main.purs │ ├── FrameBound │ ├── FrameBound.purs │ ├── Main.purs │ ├── MapLoader.js │ ├── MapLoader.purs │ ├── Projection.purs │ ├── Types.purs │ ├── data_buidings.json │ └── data_streets.json │ ├── Sealike │ ├── Main.purs │ ├── Materials │ │ ├── SeaMaterial.js │ │ └── SeaMaterial.purs │ └── Sealike.purs │ └── Timeline │ ├── Timeline.js │ └── Timeline.purs └── test └── Main.purs /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [["env", {"modules": false}]] 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bower_components/ 2 | /node_modules/ 3 | /.pulp-cache/ 4 | /output/ 5 | /generated-docs/ 6 | /.psc-package/ 7 | /.psc* 8 | /.purs* 9 | /.psa* 10 | dist 11 | !dist/main.js -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.enable": false, 3 | "editor.formatOnSave": false, 4 | "editor.formatOnType": false, 5 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Purescript simple scene model and geometric operations. Simple ThreeJS bindings included. 2 | 3 | This is a personal exploratoty project to learn more Purescript and WebGL. 4 | 5 | See it live at [Purescript ThreeJS](https://rlucha.github.io/purescript-threejs/) 6 | 7 | # Getting started 8 | 9 | 1. Install all dependencies: 10 | ``` 11 | npm install -g purescript pulp psc-package-bin-simple 12 | npm install 13 | psc-package install 14 | ``` 15 | 2. Start the project (will start build and server background processes): 16 | ``` 17 | npm start 18 | ``` 19 | 3. Enter http://127.0.0.1:8080/ and watch it go! 20 | 21 | ## Project hierarchy 22 | - Editor 23 | - Placeholder for a project editor in browser 24 | - Projects 25 | - Graph-like scene creator & animations 26 | - Three 27 | - ThreeJS bindings and utilities 28 | - Lib 29 | - An algebra for 3D objects 30 | - Main 31 | - Entry point 32 | 33 | ## Creating a new scene 34 | - Create a new Projects folder with the project name 35 | - Duplicate Main.purs of another project, set scene, camera, etc. 36 | - Create a new Project file, import it in main 37 | - Project should export create (Effect Project) and update functions (Effect Unit) 38 | - create a new link in index.html 39 | ``` 04 ``` 40 | - create a new route in index.js 41 | 42 | ## TODO 43 | - Use import Control.Monad.Eff.Uncurried instead of custom js-ffi 44 | - Make udpdate functions in projects NOT perform side effects but get a collection of objects and properties and 45 | return a new collection of objects and properties. A consumer will use that to apply the changes 46 | under Eff making the scene as pure as possible. Under that idea, the project would use a DSL and a "runner" module 47 | would transform those into actual threejs calls. 48 | - Make Project a graph and provide a way to traverse it (Functor Project?) 49 | - Generalize the project file utils into a project object in Pure3 50 | - Connect datGUI to those params to get some interactivity 51 | - Create a set of JS utils to make IFF less painful 52 | - Get webpack to serve all files using purs-loader or similar 53 | - Will this do dead code elimination? 54 | - Orbitcontrol rotate, autoupdate fns, enable zoom, etc. 55 | - Write a bit of documentation about the type decisions on Timeline and Main mostly 56 | - Pass any input value as well as frame to behaviours... 57 | - Move camera into project? 58 | - Add proper fog to scene instead of directly from js 59 | - Transparent canvas color? 60 | - Check for a way to easy the pain on wrapping unwrapping object3D 61 | - get 2d coordinates from any element in canvas to match css elements on top 62 | - Move projects config to a record 63 | - move onResize event to purescript 64 | - throttle onResize 65 | - Replace Maintype with Effect, currently Timeline is coupled 66 | - [NEWTYPE] Wrap / Unwrap using newtype instance for Line and other Pure3 types 67 | - Flip shape matrix to the ground 68 | - Center FrameBound scene 69 | - custom height for buildings 70 | - get shadows to work 71 | - create a base material object (typeclass? to deal with common properties) 72 | - only get lines with all points inside query from osm-cutemaps 73 | - makes some sense of the lineString geom type 74 | - explore solutions like https://www.nextzen.org/ or https://wiki.openstreetmap.org/wiki/Overpass_API to get the data 75 | - Finish ThreeJS bindings module structure, set placeholders for every module in the original repo 76 | - Check lineGeometry, lineMaterial, etc. 77 | 78 | From stackoverflow: 79 | ``` 80 | function hexToRgb(hex) { 81 | var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); 82 | return result ? { 83 | r: parseInt(result[1], 16) / 255, 84 | g: parseInt(result[2], 16) / 255, 85 | b: parseInt(result[3], 16) / 255 86 | } : null; 87 | } 88 | ``` 89 | -------------------------------------------------------------------------------- /config/webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require("webpack"); 2 | const path = require("path"); 3 | 4 | module.exports = { 5 | entry: './index.js', 6 | output: { 7 | filename: 'main.js', 8 | path: path.resolve(__dirname, '..', 'dist') 9 | }, 10 | module: { 11 | rules: [ 12 | {test: /\.(js|jsx|json)$/, use: "babel-loader"}, 13 | ] 14 | }, 15 | resolve: { 16 | modules: ["node_modules", "output"], 17 | extensions: [".js", ".json", ".re", ".ml"] 18 | }, 19 | watchOptions: { 20 | aggregateTimeout: 300, 21 | poll: 1000, 22 | ignored: /node_modules/ 23 | }, 24 | plugins: [ 25 | new webpack.HotModuleReplacementPlugin() 26 | ], 27 | mode: "development" 28 | } 29 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlucha/purescript-threejs-archived/ef26a65b468463ba1b00fb222ad90b8ee56e6328/icon.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Document 11 | 12 | 122 | 123 | 124 | 125 |
126 |

Roberto Lucha

127 |

Purescript Playgrounds

128 |
129 | github 130 | twitter 131 |
132 | 04 133 | 03 134 | 02 135 | 01 136 |
137 | 138 | 141 | 142 | 143 | 144 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const rlite = require("rlite-router"); 2 | 3 | const circleStuff = require("./output/Projects.CircleStuff.Main"); 4 | const seaLike = require("./output/Projects.Sealike.Main"); 5 | const frameBound = require("./output/Projects.FrameBound.Main"); 6 | const foo = require("./output/Projects.Foo.Main"); 7 | 8 | const editorFactory = require("./src/Editor/main"); 9 | 10 | const route = rlite(notFound, { 11 | "": function() { 12 | circleStuff.main(); 13 | }, 14 | "01": function() { 15 | document.body.className = "theme02"; 16 | seaLike.main(); 17 | }, 18 | "02": function({ editor }) { 19 | document.body.className = "theme01"; 20 | circleStuff.main(); 21 | if (editor === "true") { 22 | editorFactory.editor(); 23 | } 24 | }, 25 | "03": function() { 26 | document.body.className = "theme01"; 27 | frameBound.main(); 28 | }, 29 | "04": function() { 30 | document.body.className = "theme04"; 31 | foo.main(); 32 | } 33 | }); 34 | 35 | function notFound() { 36 | document.body.className = "theme01"; 37 | frameBound.main(); 38 | } 39 | 40 | // Hash-based routing 41 | function processHash() { 42 | const hash = location.hash || "#"; 43 | route(hash.slice(2)); 44 | } 45 | 46 | function toggleFullScreen() { 47 | var doc = window.document; 48 | var docEl = doc.documentElement; 49 | 50 | var requestFullScreen = 51 | docEl.requestFullscreen || 52 | docEl.mozRequestFullScreen || 53 | docEl.webkitRequestFullScreen || 54 | docEl.msRequestFullscreen; 55 | var cancelFullScreen = 56 | doc.exitFullscreen || 57 | doc.mozCancelFullScreen || 58 | doc.webkitExitFullscreen || 59 | doc.msExitFullscreen; 60 | 61 | if ( 62 | !doc.fullscreenElement && 63 | !doc.mozFullScreenElement && 64 | !doc.webkitFullscreenElement && 65 | !doc.msFullscreenElement 66 | ) { 67 | requestFullScreen.call(docEl); 68 | } else { 69 | cancelFullScreen.call(doc); 70 | } 71 | } 72 | 73 | window.go = () => { 74 | setTimeout(() => window.location.reload(true), 200); 75 | }; 76 | 77 | document.addEventListener("dblclick", toggleFullScreen); 78 | window.addEventListener("hashchange", processHash); 79 | processHash(); 80 | -------------------------------------------------------------------------------- /lib/Pure3/Circle.purs: -------------------------------------------------------------------------------- 1 | module Pure3.Circle where 2 | 3 | import Prelude (class Show) 4 | import Data.Generic.Rep (class Generic) 5 | import Data.Generic.Rep.Show (genericShow) 6 | 7 | import Pure3.Point (Point) 8 | 9 | type Radius = Number 10 | 11 | -- Move to newtype, make a function to show if needed 12 | -- get unwrap for free 13 | data Circle = Circle { center :: Point, radius :: Radius } 14 | derive instance genCircle :: Generic Circle _ 15 | instance showCircle :: Show Circle where 16 | show = genericShow 17 | 18 | create :: Point -> Radius -> Circle 19 | create c r = Circle { center: c, radius: r } 20 | 21 | -- [NEWTYPE] 22 | unwrap :: Circle -> { center :: Point, radius :: Radius } 23 | unwrap (Circle {center, radius}) = {center, radius} 24 | -------------------------------------------------------------------------------- /lib/Pure3/Interpolate.purs: -------------------------------------------------------------------------------- 1 | module Pure3.Interpolate where 2 | 3 | import Prelude 4 | import Math as Math 5 | 6 | import Data.List ((..)) 7 | import Data.List as StrictList 8 | import Data.List.Lazy as LazyList 9 | import Data.Int (toNumber) 10 | import Data.List.ZipList (ZipList(..)) 11 | 12 | import Control.Apply (lift2) 13 | 14 | import Pure3.Types (Circle, Line(..), Point(..), Square) 15 | import Pure3.Point as Point 16 | import Pure3.Line as Line 17 | import Pure3.Circle as Circle 18 | import Pure3.Square as Square 19 | 20 | type Steps = Int 21 | 22 | interpolateRange :: Number -> Number -> Int -> StrictList.List Number 23 | interpolateRange from to s = 24 | let inc = (to - from) / toNumber s 25 | in map (\x -> from + inc * toNumber x) (StrictList.range 0 s) 26 | -- \[x_n = x_i + \frac{x_f - x_i}{s} n\] 27 | 28 | degToRad :: Number -> Number 29 | degToRad n = n * (180.0 / Math.pi) 30 | 31 | class Interpolatable a where 32 | interpolate :: Steps -> a -> StrictList.List Point 33 | 34 | instance interpolateCircle :: Interpolatable Circle where 35 | interpolate s c = 36 | let {center, radius} = Circle.unwrap c 37 | inc = 360.0 / degToRad (toNumber s) 38 | degs = ((*) inc) <$> toNumber <$> 0..s 39 | cosR = (*) radius <<< Math.cos 40 | sinR = (*) radius <<< Math.sin 41 | -- Is there a way to chain this fmaps more beautifully? 42 | points = (+) center <$> (\r -> Point.create (cosR r) (sinR r) 0.0) <$> degs 43 | -- uncurry is gonna take a binary function and make it a unary function over Tuples 44 | -- cartesianProductOfPoints :: (*) <$> lab <*> lac 45 | in points 46 | 47 | instance interpolateSquare :: Interpolatable Square where 48 | interpolate s sq = 49 | let points = Square.getPoints sq 50 | lab = interpolate s (Line.create points.a points.b) 51 | lac = interpolate s (Line.create points.a points.c) 52 | -- uncurry is gonna take a binary function and make it a unary function over Tuples 53 | -- cartesianProductOfPoints :: (*) <$> lab <*> lac 54 | in StrictList.fromFoldable $ lift2 (+) lab lac -- (*) <$> lab <*> lac 55 | 56 | -- something :: ∀ a. Interpolatable a => a -> StrictList.List Point 57 | -- something s = interpolate s 10 58 | 59 | -- Previously this was ----------- 60 | -- in ri = zip ai $ zip bi ci 61 | -- in map (\(Tuple a b c) -> Point {x:a, y:b, z:c}) $ ri 62 | -- How to avoid getting nested Tuples? 63 | -- Lazy list and strict list are different list types, we need to differentiate them 64 | -- because ZipList only works on lazy lists and List Point is from Strict 65 | -- Then we use the applicative instance of ZipLlist to apply a 3ary function to 3 lists 66 | -- effectively using zipWith with 3 elements 67 | -- Applicative on lists is a cartesian product, applicative on Ziplist is an "ordered" function application 68 | 69 | -- How does this work? 70 | -- P.create is a pure function 71 | instance il :: Interpolatable Line where 72 | interpolate s (Line {a:Point a, b:Point b}) = 73 | -- Change the destructuring of the line to a getLinePoints fn 74 | let ai = interpolateRange a.x b.x s 75 | bi = interpolateRange a.y b.y s 76 | ci = interpolateRange a.z b.z s 77 | ri = Point.create 78 | <$> ZipList (LazyList.fromFoldable ai) 79 | <*> ZipList (LazyList.fromFoldable bi) 80 | <*> ZipList (LazyList.fromFoldable ci) 81 | in StrictList.fromFoldable ri 82 | 83 | -- This should be a combination of basic interpolation and a ziggy line? 84 | -- That would need to create a square from two lines nad not only from four points 85 | 86 | -- getDistanceFromLine :: Line -> Point 87 | -- getDistanceFromLine Nil = P.create 0.0 0.0 0.0 88 | -- getDistanceFromLine (Line l) = StrictList.take 2 lab 89 | 90 | -- -- This is a failed tesselation prototype 91 | -- interpolateStarSquare :: SQ.Square -> Int -> StrictList.List Point 92 | -- interpolateStarSquare s sq = 93 | -- let points = SQ.getPoints sq 94 | -- lab = interpolate s (L.create points.a points.b) 95 | -- distancePoint = (*) (P.create 0.25 1.0 1.0) $ foldr (-) P.zeroPoint $ StrictList.take 2 lab 96 | -- -- zigPoint = 97 | -- -- case distance of 98 | -- -- Nil -> f 99 | -- -- (distance:Nil) -> distance 100 | -- -- lac = interpolate (L.create points.a points.c) s 101 | -- lac = zigPoints distancePoint (P.negatePoint distancePoint) $ interpolate (L.create points.a points.c) s 102 | -- -- uncurry is gonna take a binary function and make it a unary function over Tuples 103 | -- -- cartesianProductOfPoints :: (*) <$> lab <*> lac 104 | -- in StrictList.fromFoldable $ lift2 (+) lab lac -- (*) <$> lab <*> lac 105 | -------------------------------------------------------------------------------- /lib/Pure3/Line.purs: -------------------------------------------------------------------------------- 1 | module Pure3.Line where 2 | 3 | import Prelude (class Show) 4 | import Data.Generic.Rep (class Generic) 5 | import Data.Generic.Rep.Show (genericShow) 6 | import Data.Newtype (class Newtype) 7 | 8 | import Pure3.Point (Point) 9 | 10 | newtype Line = Line { a :: Point, b :: Point} 11 | derive instance genLine :: Generic Line _ 12 | instance showLine :: Show Line where 13 | show = genericShow 14 | derive instance newtypeLine :: Newtype Line _ 15 | 16 | create :: Point -> Point -> Line 17 | create a b = Line { a: a, b: b} 18 | 19 | -- [NEWTYPE] 20 | -------------------------------------------------------------------------------- /lib/Pure3/Point.purs: -------------------------------------------------------------------------------- 1 | module Pure3.Point where 2 | 3 | import Prelude 4 | 5 | import Data.Generic.Rep (class Generic) 6 | import Data.Generic.Rep.Show (genericShow) 7 | import Data.Newtype (class Newtype) 8 | 9 | newtype Point = Point { x :: Number, y :: Number, z :: Number } 10 | 11 | derive instance newPoint :: Newtype Point _ 12 | derive instance eqPoint :: Eq Point 13 | derive instance genPoint :: Generic Point _ 14 | instance showPoint :: Show Point where show = genericShow 15 | 16 | instance semiringPoint :: Semiring Point where 17 | add = sumPoint 18 | mul = mulPoint 19 | zero = zeroPoint 20 | one = Point { x:1.0, y:1.0, z:1.0} 21 | 22 | instance ringPoint :: Ring Point where 23 | sub = subPoint 24 | 25 | -- [NEWTYPE] 26 | unwrap :: Point -> { x :: Number, y :: Number, z :: Number } 27 | unwrap (Point {x, y, z}) = {x, y, z} 28 | 29 | -- a way to fetch a record value from label? 30 | getZ :: Point -> Number 31 | getZ p = (\r -> r.z) $ unwrap p 32 | 33 | zeroPoint :: Point 34 | zeroPoint = Point { x:0.0, y:0.0, z:0.0} 35 | 36 | create :: Number -> Number -> Number -> Point 37 | create x y z = Point 38 | { x: x 39 | , y: y 40 | , z: z 41 | } 42 | 43 | sumPoint :: Point -> Point -> Point 44 | sumPoint (Point a) (Point b) = Point 45 | { x: a.x + b.x 46 | , y: a.y + b.y 47 | , z: a.z + b.z 48 | } 49 | 50 | subPoint :: Point -> Point -> Point 51 | subPoint (Point a) (Point b) = Point 52 | { x: a.x - b.x 53 | , y: a.y - b.y 54 | , z: a.z - b.z 55 | } 56 | 57 | mulPoint :: Point -> Point -> Point 58 | mulPoint (Point a) (Point b) = Point 59 | { x: a.x * b.x 60 | , y: a.y * b.y 61 | , z: a.z * b.z 62 | } 63 | 64 | negatePoint :: Point -> Point 65 | negatePoint (Point a) = create (negate a.x) (negate a.y) (negate a.z) 66 | -------------------------------------------------------------------------------- /lib/Pure3/Scene.purs: -------------------------------------------------------------------------------- 1 | module Pure3.Scene where 2 | 3 | import Prelude 4 | import Data.Generic.Rep (class Generic) 5 | import Data.Generic.Rep.Show (genericShow) 6 | import Data.Array (concat) 7 | 8 | import Pure3.Point (Point) 9 | import Pure3.Line (Line) 10 | import Pure3.Line as Line 11 | import Pure3.Square (Square(..)) 12 | 13 | type Mesh = Array Point 14 | 15 | data Scene = Scene 16 | { points :: Array Point 17 | , lines :: Array Line 18 | , squares :: Array Square 19 | , meshes :: Array Mesh 20 | } 21 | 22 | derive instance genScene :: Generic Scene _ 23 | instance showScene :: Show Scene where show = genericShow 24 | 25 | -- Transforms an scene to a list of points and lines... 26 | -- Reduces squares to lines 27 | -- In the future shapes could carry representation information to 28 | -- decide which interpolation/transform function to use 29 | -- so we could represent an square as a list of lines or as a list of points 30 | -- maybe even both? 31 | 32 | -- for now we will represent an square as a list of 4 lines 33 | -- so we need to create lines from the points of an square 34 | 35 | squareToLines :: Square -> Array Line 36 | squareToLines (Square {a,b,c,d}) = 37 | let lab = Line.create a b 38 | lbd = Line.create b d 39 | ldc = Line.create d c 40 | lca = Line.create c a 41 | in [lab, lbd, ldc, lca] 42 | 43 | -- create parses the squares to lines, this should be a row type I think 44 | create :: 45 | { points :: Array Point 46 | , lines :: Array Line 47 | , squares :: Array Square 48 | , meshes :: Array Mesh } -> Scene 49 | 50 | create scene = 51 | let squares' = map squareToLines scene.squares 52 | in 53 | Scene 54 | { points: scene.points 55 | , lines: scene.lines <> concat squares' 56 | , squares: [] 57 | , meshes: scene.meshes 58 | } 59 | 60 | -- This is not needed anymore... 61 | -- unfoldScene :: Scene -> { points :: Array Point, lines :: Array Line } 62 | -- unfoldScene (Scene s) = s 63 | -------------------------------------------------------------------------------- /lib/Pure3/Square.purs: -------------------------------------------------------------------------------- 1 | module Pure3.Square where 2 | 3 | import Prelude (class Show) 4 | import Data.Generic.Rep (class Generic) 5 | import Data.Generic.Rep.Show (genericShow) 6 | 7 | import Pure3.Point (Point) 8 | import Pure3.Line (Line(..)) 9 | 10 | type Steps = Int 11 | 12 | data Square = Square { a :: Point, b :: Point, c :: Point, d :: Point } 13 | derive instance genSquare :: Generic Square _ 14 | instance showSquare :: Show Square where 15 | show = genericShow 16 | 17 | -- [NEWTYPE] 18 | create :: Point -> Point -> Point -> Point -> Square 19 | create a b c d = Square { a: a, b: b, c: c, d: d } 20 | 21 | -- MultiParamTypeClasses ? for parametric dispatch? 22 | createFromLines :: Line -> Line -> Square 23 | createFromLines (Line la) (Line lb) = Square { a: la.a, b: la.b, c: lb.a, d: lb.b} 24 | 25 | -- Is there a way to pass a record-like datatype to a record automatically? 26 | getPoints :: Square -> { a :: Point, b :: Point, c :: Point, d :: Point } 27 | getPoints (Square {a, b, c, d}) = {a, b, c, d} 28 | 29 | -- TODO 30 | -- How to write a function that accepts different number of params and types? 31 | -- create :: Point -> Point -> Point -> Point -> Square 32 | -- create :: Line -> Line -> Square 33 | -- create .... = implementation 1 || implemenetation 2 34 | -------------------------------------------------------------------------------- /lib/Pure3/Tesselate.purs: -------------------------------------------------------------------------------- 1 | -- https://hexnet.org/content/hexagonal-geometry 2 | -- 120 degs everywhere 3 | -- make each item in a tesselation group retain local 4 | -- coordinates to apply location related 5 | -- transformations 6 | 7 | module Pure3.Tesselate where 8 | -------------------------------------------------------------------------------- /lib/Pure3/Transform.purs: -------------------------------------------------------------------------------- 1 | module Pure3.Transform 2 | ( scaleSquare 3 | , translateSquare 4 | , zigPoints) 5 | where 6 | 7 | import Prelude 8 | import Data.List (List) 9 | 10 | import Pure3.Point (Point) 11 | import Pure3.Point as Point 12 | import Pure3.Utils (evens, odds) 13 | import Pure3.Square(Square(..)) 14 | 15 | -- Make a typeclass for this... 16 | -- Maybe we need lenses already 17 | -- Destructuring this and restructuring the shape 18 | -- is gonna be a pain 19 | 20 | scaleSquare :: Number -> Square -> Square 21 | scaleSquare n (Square {a, b, c, d}) = 22 | Square 23 | { a: a * Point.create n n n 24 | , b: b * Point.create n n n 25 | , c: c * Point.create n n n 26 | , d: d * Point.create n n n 27 | } 28 | 29 | -- Replace with https://qiita.com/kimagure/items/06d7eed9521b6217b771 30 | translateSquare :: Square -> Point -> Square 31 | translateSquare (Square {a, b, c, d}) g = 32 | Square 33 | { a: a + g 34 | , b: b + g 35 | , c: c + g 36 | , d: d + g 37 | } 38 | 39 | -- zigLine :: L.Line -> L.Line 40 | -- zigLine l = 41 | -- let points = L.getPoints l 42 | -- in points 43 | 44 | zigPoints :: ∀ 45 | a. Semiring a => a -> a -> List a -> List a 46 | zigPoints p p2 lp = 47 | let evenP = (+) p <$> evens lp 48 | oddsP = (+) p2 <$> odds lp 49 | in evenP <> oddsP 50 | -------------------------------------------------------------------------------- /lib/Pure3/Utils.purs: -------------------------------------------------------------------------------- 1 | module Pure3.Utils where 2 | 3 | import Data.List (List(Nil), (:)) 4 | 5 | odds :: ∀ a. List a -> List a 6 | odds Nil = Nil 7 | odds (x:Nil) = (x:Nil) 8 | odds (x:y:xs) = x : (odds xs) 9 | 10 | evens :: ∀ a. List a -> List a 11 | evens Nil = Nil 12 | evens (x:Nil) = Nil 13 | evens (x:y:xs) = y : (evens xs) 14 | -------------------------------------------------------------------------------- /lib/ffi-utils/index.js: -------------------------------------------------------------------------------- 1 | exports.curry1 = function(fn) { 2 | return function(p1) { 3 | return function() { 4 | return fn(p1) 5 | } 6 | } 7 | } 8 | 9 | exports.curry2 = function(fn) { 10 | return function(p1) { 11 | return function(p2) { 12 | return function() { 13 | return fn(p1, p2) 14 | } 15 | } 16 | } 17 | } 18 | 19 | exports.curry3 = function(fn) { 20 | return function(p1) { 21 | return function(p2) { 22 | return function(p3) { 23 | return function() { 24 | return fn(p1, p2, p3) 25 | } 26 | } 27 | } 28 | } 29 | } 30 | 31 | exports.curry4 = function(fn) { 32 | return function(p1) { 33 | return function(p2) { 34 | return function(p3) { 35 | return function(p4) { 36 | return function() { 37 | return fn(p1, p2, p3, p4) 38 | } 39 | } 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/ffi-utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ffi-utils", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /lib/pure3/Types.purs: -------------------------------------------------------------------------------- 1 | module Pure3.Types 2 | ( module Pure3.Point 3 | , module Pure3.Line 4 | , module Pure3.Square 5 | , module Pure3.Circle ) 6 | where 7 | 8 | import Pure3.Point (Point(..)) 9 | import Pure3.Line (Line(..)) 10 | import Pure3.Square (Square(..)) 11 | import Pure3.Circle (Circle(..)) 12 | -------------------------------------------------------------------------------- /lib/three-ffi/Camera/Camera.js: -------------------------------------------------------------------------------- 1 | var ffi = require("ffi-utils") 2 | var PerspectiveCamera = require("three").PerspectiveCamera 3 | 4 | exports.create = ffi.curry4( 5 | function(fov, aspect, near, far) { 6 | var camera = new PerspectiveCamera(fov, aspect, near, far) 7 | return camera 8 | } 9 | ) 10 | 11 | exports.setAspect = ffi.curry2( 12 | function(aspect, camera) { 13 | camera.aspect = aspect 14 | } 15 | ); 16 | 17 | exports.setPosition = ffi.curry4( 18 | function(x, y, z, camera) { 19 | camera.position.set(x, y, z) 20 | } 21 | ) 22 | 23 | exports.lookAt = ffi.curry4( 24 | function(x, y, z, camera) { 25 | camera.lookAt(x, y, z) 26 | } 27 | ) 28 | 29 | exports.debug = ffi.curry1( 30 | function(camera) { 31 | window.camera = camera 32 | } 33 | ) 34 | 35 | exports.updateProjectionMatrix = ffi.curry1( 36 | function(camera) { 37 | camera.updateProjectionMatrix() 38 | } 39 | ) 40 | -------------------------------------------------------------------------------- /lib/three-ffi/Camera/Camera.purs: -------------------------------------------------------------------------------- 1 | module Three.Camera where 2 | 3 | import Prelude 4 | import Effect 5 | import Three.Types (Camera) 6 | 7 | type Fov = Number 8 | type Aspect = Number 9 | type Near = Number 10 | type Far = Number 11 | 12 | type X = Number 13 | type Y = Number 14 | type Z = Number 15 | 16 | foreign import create 17 | :: Fov -> Aspect -> Near -> Far -> Effect Camera 18 | 19 | foreign import debug :: Camera -> Effect Unit 20 | 21 | -- TODO Use Object3D setPoasition instead 22 | foreign import setPosition 23 | :: X -> Y -> Z -> Camera -> Effect Unit 24 | 25 | foreign import lookAt 26 | :: X -> Y -> Z -> Camera -> Effect Unit 27 | 28 | foreign import setAspect 29 | :: Number -> Camera -> Effect Unit 30 | 31 | foreign import updateProjectionMatrix 32 | :: Camera -> Effect Unit 33 | -------------------------------------------------------------------------------- /lib/three-ffi/Core/Geometry/Geometry.js: -------------------------------------------------------------------------------- 1 | // TODO: pass configuration 2 | var ffi = require("ffi-utils") 3 | var Geometry = require("three").Geometry 4 | 5 | // this doesn't work with ffi.curry1... why? 6 | exports.create = 7 | function() { 8 | return new Geometry(); 9 | } 10 | -------------------------------------------------------------------------------- /lib/three-ffi/Core/Geometry/Geometry.purs: -------------------------------------------------------------------------------- 1 | module Three.Geometry where 2 | 3 | import Effect 4 | import Three.Types (Geometry) 5 | 6 | foreign import create :: Effect Geometry -------------------------------------------------------------------------------- /lib/three-ffi/Core/Object3D/Object3D.js: -------------------------------------------------------------------------------- 1 | var ffi = require("ffi-utils"); 2 | 3 | exports.setPosition_ = function(x) { 4 | return function(y) { 5 | return function(z) { 6 | return function(object3D) { 7 | return function() { 8 | object3D.position.set(x, y, z); 9 | }; 10 | }; 11 | }; 12 | }; 13 | }; 14 | 15 | exports.setRotation_ = function(x) { 16 | return function(y) { 17 | return function(z) { 18 | return function(object3D) { 19 | return function() { 20 | object3D.rotation.set(x, y, z); 21 | }; 22 | }; 23 | }; 24 | }; 25 | }; 26 | 27 | exports.setScale_ = function(x) { 28 | return function(y) { 29 | return function(z) { 30 | return function(object3D) { 31 | return function() { 32 | object3D.scale.set(x, y, z); 33 | }; 34 | }; 35 | }; 36 | }; 37 | }; 38 | 39 | exports.rotateOnAxis_ = function(v3) { 40 | return function(angle) { 41 | return function(object3D) { 42 | return function() { 43 | object3D.rotateOnAxis(v3, angle); 44 | }; 45 | }; 46 | }; 47 | }; 48 | 49 | // TODO change for a generic Object3D 50 | exports.forceVerticesUpdate_ = function(g) { 51 | return function() { 52 | // remove .geometry and make access direct from PS 53 | g.geometry.verticesNeedUpdate = true; 54 | }; 55 | }; 56 | 57 | exports.getPosition_ = function(object3D) { 58 | return function() { 59 | return object3D.position; 60 | }; 61 | }; 62 | 63 | exports.setReceiveShadow_ = ffi.curry2(function(bool, object3D) { 64 | object3D.receiveShadow = bool; 65 | }); 66 | 67 | exports.setCastShadow_ = ffi.curry2(function(bool, object3D) { 68 | object3D.castShadow = bool; 69 | }); 70 | -------------------------------------------------------------------------------- /lib/three-ffi/Core/Object3D/Object3D.purs: -------------------------------------------------------------------------------- 1 | module Three.Object3D where 2 | 3 | import Effect 4 | import Prelude 5 | 6 | import Three (getVector3Position) 7 | import Three.Camera (setPosition) 8 | -- TODO explain the need of Object3D and Object3D_ 9 | import Three.Types (Object3D(..), Object3D_, Vector3) 10 | 11 | -- Can we reduce some boilerplate? this functions are doing the same thing all over... 12 | 13 | foreign import setPosition_ :: Number -> Number -> Number -> Object3D_ -> Effect Unit 14 | foreign import getPosition_ :: Object3D_ -> Effect Vector3 15 | foreign import setRotation_ :: Number -> Number -> Number -> Object3D_ -> Effect Unit 16 | foreign import setScale_ :: Number -> Number -> Number -> Object3D_ -> Effect Unit 17 | foreign import rotateOnAxis_ :: Vector3 -> Number -> Object3D_ -> Effect Unit 18 | foreign import forceVerticesUpdate_ :: Object3D_ -> Effect Unit 19 | foreign import setReceiveShadow_ :: Boolean -> Object3D_ -> Effect Unit 20 | foreign import setCastShadow_ :: Boolean -> Object3D_ -> Effect Unit 21 | 22 | -- Using functor on Object3D 23 | -- setPosition :: Number -> Number -> Number -> Object3D -> Effect Unit 24 | -- setPosition x y z o = traverse_ (setPosition_ x y z) o 25 | 26 | setPosition :: Number -> Number -> Number -> Object3D -> Effect Unit 27 | setPosition x y z o = setPosition_ x y z (unwrap o) 28 | 29 | setRotation :: Number -> Number -> Number -> Object3D -> Effect Unit 30 | setRotation x y z o = setRotation_ x y z (unwrap o) 31 | 32 | setScale :: Number -> Number -> Number -> Object3D -> Effect Unit 33 | setScale x y z o = setScale_ x y z (unwrap o) 34 | 35 | rotateOnAxis :: Vector3 -> Number -> Object3D -> Effect Unit 36 | rotateOnAxis v3 angle o = rotateOnAxis_ v3 angle (unwrap o) 37 | 38 | forceVerticesUpdate :: Object3D -> Effect Unit 39 | forceVerticesUpdate o = forceVerticesUpdate_ (unwrap o) 40 | 41 | getPosition :: Object3D -> Effect { x :: Number, y :: Number, z :: Number } 42 | getPosition o = getPosition_ (unwrap o) >>= getVector3Position 43 | 44 | -- make Object3D functor so we can map on it no matter the value? 45 | setReceiveShadow :: Boolean -> Object3D -> Effect Unit 46 | setReceiveShadow b o = setReceiveShadow_ b (unwrap o) 47 | 48 | setCastShadow :: Boolean -> Object3D -> Effect Unit 49 | setCastShadow b o = setCastShadow_ b (unwrap o) 50 | 51 | -- This is completely redundant 52 | unwrap :: Object3D -> Object3D_ 53 | unwrap (Object3D o) = o.unObject3D 54 | -------------------------------------------------------------------------------- /lib/three-ffi/Extras/Core/Shape/Shape.js: -------------------------------------------------------------------------------- 1 | // TODO: pass configuration 2 | var ffi = require("ffi-utils") 3 | var Shape = require("three").Shape 4 | 5 | exports.create = ffi.curry1( 6 | function(v2s) { 7 | return new Shape(v2s); 8 | } 9 | ) 10 | -------------------------------------------------------------------------------- /lib/three-ffi/Extras/Core/Shape/Shape.purs: -------------------------------------------------------------------------------- 1 | module Three.Extras.Core.Shape where 2 | 3 | import Prelude 4 | 5 | import Effect 6 | import Three.Types (Vector2, Shape) 7 | 8 | foreign import create 9 | :: Array Vector2 -> Effect Shape 10 | -------------------------------------------------------------------------------- /lib/three-ffi/Geometry/BoxGeometry/BoxGeometry.js: -------------------------------------------------------------------------------- 1 | var ffi = require("ffi-utils") 2 | var BoxGeometry = require("three").BoxGeometry 3 | 4 | exports.create = ffi.curry3( 5 | function(width, height, depth) { 6 | return new BoxGeometry(width, height, depth); 7 | } 8 | ) 9 | -------------------------------------------------------------------------------- /lib/three-ffi/Geometry/BoxGeometry/BoxGeometry.purs: -------------------------------------------------------------------------------- 1 | module Three.Geometry.BoxGeometry where 2 | 3 | import Effect 4 | import Three.Types (Geometry) 5 | 6 | type Width = Number 7 | type Height = Number 8 | type Depth = Number 9 | 10 | -- Type these numbers to get some docs 11 | foreign import create 12 | :: Width 13 | -> Height 14 | -> Depth 15 | -> Effect Geometry 16 | -------------------------------------------------------------------------------- /lib/three-ffi/Geometry/ExtrudeGeometry/ExtrudeGeometry.js: -------------------------------------------------------------------------------- 1 | var ffi = require("ffi-utils") 2 | var ExtrudeGeometry = require("three").ExtrudeGeometry 3 | 4 | // TODO: pass extrudeSettings as 2nd param 5 | exports.create = ffi.curry2( 6 | function(depth, shape) { 7 | return new ExtrudeGeometry(shape, { 8 | steps: 1, 9 | depth: depth, 10 | bevelEnabled: false 11 | }); 12 | } 13 | ) 14 | -------------------------------------------------------------------------------- /lib/three-ffi/Geometry/ExtrudeGeometry/ExtrudeGeometry.purs: -------------------------------------------------------------------------------- 1 | module Three.Geometry.ExtrudeGeometry where 2 | 3 | import Effect 4 | import Three.Types (Geometry, Shape) 5 | 6 | type Depth = Number 7 | 8 | -- Type these numbers to get some docs 9 | foreign import create 10 | :: Depth 11 | -> Shape 12 | -> Effect Geometry 13 | -------------------------------------------------------------------------------- /lib/three-ffi/Geometry/PlaneGeometry/PlaneGeometry.js: -------------------------------------------------------------------------------- 1 | var ffi = require("ffi-utils") 2 | var PlaneGeometry = require("three").PlaneGeometry 3 | 4 | exports.create = ffi.curry4( 5 | function(width, height, width_segments, height_segments) { 6 | return new PlaneGeometry(width, height, width_segments, height_segments); 7 | } 8 | ) -------------------------------------------------------------------------------- /lib/three-ffi/Geometry/PlaneGeometry/PlaneGeometry.purs: -------------------------------------------------------------------------------- 1 | module Three.Geometry.PlaneGeometry where 2 | 3 | import Effect 4 | import Three.Types (Geometry, Shape) 5 | 6 | type Width = Number 7 | type Height = Number 8 | type WidthSegments = Int 9 | type HeightSegments = Int 10 | 11 | foreign import create 12 | :: Width 13 | -> Height 14 | -> WidthSegments 15 | -> HeightSegments 16 | -> Effect Geometry 17 | -------------------------------------------------------------------------------- /lib/three-ffi/Material/LineBasicMaterial/LineBasicMaterial.js: -------------------------------------------------------------------------------- 1 | // TODO: pass configuration 2 | var ffi = require("ffi-utils") 3 | var LineBasicMaterial = require("three").LineBasicMaterial 4 | 5 | exports.create = ffi.curry1( 6 | function(color) { 7 | return new LineBasicMaterial({color: color, linewidth: 10}); 8 | } 9 | ) 10 | -------------------------------------------------------------------------------- /lib/three-ffi/Material/LineBasicMaterial/LineBasicMaterial.purs: -------------------------------------------------------------------------------- 1 | module Three.Materials.LineBasicMaterial where 2 | 3 | import Effect 4 | import Three.Types (Material, Color) 5 | 6 | foreign import create 7 | :: Color 8 | -> Effect Material 9 | -------------------------------------------------------------------------------- /lib/three-ffi/Material/MeshBasicMaterial/MeshBasicMaterial.js: -------------------------------------------------------------------------------- 1 | // TODO: pass configuration 2 | var ffi = require("ffi-utils") 3 | var MeshBasicMaterial = require("three").MeshBasicMaterial 4 | 5 | exports.create = ffi.curry1( 6 | function(color) { 7 | return new MeshBasicMaterial({color: color}); 8 | } 9 | ) 10 | -------------------------------------------------------------------------------- /lib/three-ffi/Material/MeshBasicMaterial/MeshBasicMaterial.purs: -------------------------------------------------------------------------------- 1 | module Three.Materials.MeshBasicMaterial where 2 | 3 | import Effect 4 | import Three.Types (Material, Color) 5 | 6 | foreign import create 7 | :: Color 8 | -> Effect Material 9 | -------------------------------------------------------------------------------- /lib/three-ffi/Material/MeshNormalMaterial/MeshNormalMaterial.js: -------------------------------------------------------------------------------- 1 | // TODO: pass configuration 2 | var ffi = require("ffi-utils") 3 | var MeshNormalMaterial = require("three").MeshNormalMaterial 4 | 5 | exports.create = ffi.curry2( 6 | function(color, lights) { 7 | return new MeshNormalMaterial({color: color, lights: lights}); 8 | } 9 | ) 10 | -------------------------------------------------------------------------------- /lib/three-ffi/Material/MeshNormalMaterial/MeshNormalMaterial.purs: -------------------------------------------------------------------------------- 1 | module Three.Materials.MeshNormalMaterial where 2 | 3 | import Effect 4 | import Three.Types (Material, Color) 5 | 6 | foreign import create 7 | :: Color 8 | -> Boolean 9 | -> Effect Material 10 | -------------------------------------------------------------------------------- /lib/three-ffi/Material/MeshPhongMaterial/MeshPhongMaterial.js: -------------------------------------------------------------------------------- 1 | // TODO: pass configuration 2 | var ffi = require("ffi-utils") 3 | var MeshPhongMaterial = require("three").MeshPhongMaterial 4 | 5 | exports.create = ffi.curry2( 6 | function(color, lights) { 7 | return new MeshPhongMaterial({color: color, lights: lights}); 8 | } 9 | ) 10 | -------------------------------------------------------------------------------- /lib/three-ffi/Material/MeshPhongMaterial/MeshPhongMaterial.purs: -------------------------------------------------------------------------------- 1 | module Three.Materials.MeshPhongMaterial where 2 | 3 | import Effect 4 | import Three.Types (Material, Color) 5 | 6 | type Lights = Boolean 7 | 8 | foreign import create 9 | :: Color 10 | -> Lights 11 | -> Effect Material 12 | -------------------------------------------------------------------------------- /lib/three-ffi/Material/PointsMaterial/PointsMaterial.js: -------------------------------------------------------------------------------- 1 | // TODO: pass configuration 2 | var ffi = require("ffi-utils") 3 | var PointsMaterial = require("three").PointsMaterial 4 | 5 | exports.create = ffi.curry1( 6 | function(/*cfg*/) { 7 | return new PointsMaterial({ size: 1, sizeAttenuation: false, lights: false, fog: true } ); 8 | } 9 | ) 10 | -------------------------------------------------------------------------------- /lib/three-ffi/Material/PointsMaterial/PointsMaterial.purs: -------------------------------------------------------------------------------- 1 | module Three.Materials.PointsMaterial where 2 | 3 | import Effect 4 | import Three.Types (Material) 5 | 6 | foreign import create :: 7 | Effect Material 8 | -------------------------------------------------------------------------------- /lib/three-ffi/Math/Math.js: -------------------------------------------------------------------------------- 1 | var ffi = require("ffi-utils") 2 | var ThreeMath = require("three").Math 3 | 4 | exports.degToRad = ffi.curry1( 5 | function(deg) { 6 | return ThreeMath.degToRad(deg) 7 | } 8 | ) -------------------------------------------------------------------------------- /lib/three-ffi/Math/Math.purs: -------------------------------------------------------------------------------- 1 | module Three.Math where 2 | 3 | foreign import degToRad :: Number -> Number 4 | -------------------------------------------------------------------------------- /lib/three-ffi/Object3D/Light/AmbientLight/AmbientLight.js: -------------------------------------------------------------------------------- 1 | var ffi = require("ffi-utils") 2 | var AmbientLight = require("three").AmbientLight 3 | 4 | exports.create_ = ffi.curry2( 5 | function(color, intensity) { 6 | return new AmbientLight(color, intensity); 7 | } 8 | ) 9 | -------------------------------------------------------------------------------- /lib/three-ffi/Object3D/Light/AmbientLight/AmbientLight.purs: -------------------------------------------------------------------------------- 1 | module Three.Object3D.Light.AmbientLight where 2 | 3 | import Prelude 4 | import Effect 5 | import Three.Types (Object3D(..), Object3DTag(..), Object3D_, Color, Geometry, Material) 6 | 7 | type Intensity = Number 8 | 9 | foreign import create_ :: Color -> Intensity -> Effect Object3D_ 10 | 11 | create :: Color -> Intensity -> Effect Object3D 12 | create c i = do 13 | l <- create_ c i 14 | pure $ Object3D { unObject3D: l, tag: Light } 15 | -------------------------------------------------------------------------------- /lib/three-ffi/Object3D/Light/DirectionalLight/DirectionalLight.js: -------------------------------------------------------------------------------- 1 | var ffi = require("ffi-utils") 2 | var DirectionalLight = require("three").DirectionalLight 3 | 4 | exports.create_ = ffi.curry2( 5 | function(color, intensity) { 6 | return new DirectionalLight(color, intensity) 7 | } 8 | ) 9 | -------------------------------------------------------------------------------- /lib/three-ffi/Object3D/Light/DirectionalLight/DirectionalLight.purs: -------------------------------------------------------------------------------- 1 | module Three.Object3D.Light.DirectionalLight where 2 | 3 | import Prelude 4 | import Effect 5 | import Three.Types (Object3D(..), Object3DTag(..), Object3D_, Color, Geometry, Material) 6 | 7 | type Intensity = Number 8 | 9 | foreign import create_ :: Color -> Intensity -> Effect Object3D_ 10 | 11 | create :: Color -> Intensity -> Effect Object3D 12 | create c i = do 13 | l <- create_ c i 14 | pure $ Object3D { unObject3D: l, tag: Light } 15 | -------------------------------------------------------------------------------- /lib/three-ffi/Object3D/Light/HemisphereLight/HemisphereLight.js: -------------------------------------------------------------------------------- 1 | var ffi = require("ffi-utils") 2 | var HemisphereLight = require("three").HemisphereLight 3 | 4 | exports.create_ = ffi.curry3( 5 | function(skyColor, groundColor, intensity) { 6 | return new HemisphereLight(skyColor, groundColor, intensity); 7 | } 8 | ) 9 | -------------------------------------------------------------------------------- /lib/three-ffi/Object3D/Light/HemisphereLight/HemisphereLight.purs: -------------------------------------------------------------------------------- 1 | module Three.Object3D.Light.HemisphereLight where 2 | 3 | import Prelude 4 | import Effect 5 | import Three.Types (Object3D(..), Object3DTag(..), Object3D_, Color) 6 | 7 | type SkyColor = Color 8 | type GroundColor = Color 9 | type Intensity = Number 10 | 11 | foreign import create_ :: SkyColor -> GroundColor -> Intensity -> Effect Object3D_ 12 | 13 | create :: SkyColor -> GroundColor -> Intensity -> Effect Object3D 14 | create c1 c2 i = do 15 | l <- create_ c1 c2 i 16 | pure $ Object3D { unObject3D: l, tag: Light } 17 | -------------------------------------------------------------------------------- /lib/three-ffi/Object3D/Line/Line.js: -------------------------------------------------------------------------------- 1 | var ffi = require("ffi-utils") 2 | var Line = require("three").Line 3 | 4 | exports.create_ = ffi.curry2( 5 | function(geometry, material) { 6 | return new Line(geometry, material); 7 | } 8 | ) 9 | -------------------------------------------------------------------------------- /lib/three-ffi/Object3D/Line/Line.purs: -------------------------------------------------------------------------------- 1 | module Three.Object3D.Line where 2 | 3 | import Prelude 4 | import Effect 5 | import Three.Types (Object3D(..), Object3DTag(..), Object3D_, Geometry, Material) 6 | 7 | foreign import create_ :: Geometry -> Material -> Effect Object3D_ 8 | 9 | create :: Geometry -> Material -> Effect Object3D 10 | create g m = do 11 | m' <- create_ g m 12 | pure $ Object3D { unObject3D: m', tag: Line } -------------------------------------------------------------------------------- /lib/three-ffi/Object3D/Mesh/Mesh.js: -------------------------------------------------------------------------------- 1 | var ffi = require("ffi-utils") 2 | var Mesh = require("three").Mesh 3 | 4 | exports.create_ = ffi.curry2( 5 | function(geometry, material) { 6 | return new Mesh(geometry, material); 7 | } 8 | ) 9 | -------------------------------------------------------------------------------- /lib/three-ffi/Object3D/Mesh/Mesh.purs: -------------------------------------------------------------------------------- 1 | module Three.Object3D.Mesh where 2 | 3 | import Prelude 4 | import Effect 5 | import Three.Types (Object3D(..), Object3DTag(..), Object3D_, Geometry, Material) 6 | 7 | foreign import create_ :: Geometry -> Material -> Effect Object3D_ 8 | 9 | create :: Geometry -> Material -> Effect Object3D 10 | create g m = do 11 | m' <- create_ g m 12 | pure $ Object3D { unObject3D: m', tag: Mesh } 13 | -------------------------------------------------------------------------------- /lib/three-ffi/Object3D/Points/Points.js: -------------------------------------------------------------------------------- 1 | var ffi = require("ffi-utils") 2 | var Points = require("three").Points 3 | 4 | exports.create_ = ffi.curry2( 5 | function(geometry, material) { 6 | return new Points(geometry, material); 7 | } 8 | ) 9 | -------------------------------------------------------------------------------- /lib/three-ffi/Object3D/Points/Points.purs: -------------------------------------------------------------------------------- 1 | module Three.Object3D.Points where 2 | 3 | import Prelude 4 | import Effect 5 | import Three.Types (Object3D(..), Object3DTag(..), Object3D_, Geometry, Material) 6 | 7 | foreign import create_ :: Geometry -> Material -> Effect Object3D_ 8 | 9 | create :: Geometry -> Material -> Effect Object3D 10 | create g m = do 11 | m' <- create_ g m 12 | pure $ Object3D { unObject3D: m', tag: Points } 13 | -------------------------------------------------------------------------------- /lib/three-ffi/OrbitControls/OrbitControls.js: -------------------------------------------------------------------------------- 1 | var ffi = require("ffi-utils") 2 | var OrbitControls = require('three-orbit-controls')(require("three")) 3 | 4 | exports.create = function(camera) { 5 | return function() { 6 | return new OrbitControls(camera) 7 | } 8 | } 9 | 10 | exports.toggle = function(status) { 11 | return function(controls) { 12 | return function() { 13 | controls.enabled = status 14 | // controls.autoRotate = true //remove 15 | controls.enableZoom = true //remove 16 | } 17 | } 18 | } 19 | 20 | exports.setAutoRotate = ffi.curry2( 21 | function(status, controls) { 22 | controls.autoRotate = status 23 | } 24 | ) 25 | 26 | // Had to force this to take a number that doesn't use 27 | exports.update = function(controls) { 28 | return function() { 29 | controls.update() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/three-ffi/OrbitControls/OrbitControls.purs: -------------------------------------------------------------------------------- 1 | module Three.OrbitControls where 2 | 3 | import Prelude (Unit) 4 | import Three.Types (Camera) 5 | import Effect 6 | 7 | foreign import data OrbitControls :: Type 8 | 9 | foreign import create :: Camera -> Effect OrbitControls 10 | foreign import toggle :: Boolean -> OrbitControls -> Effect Unit 11 | foreign import setAutoRotate :: Boolean -> OrbitControls -> Effect Unit 12 | foreign import update :: OrbitControls -> Effect Unit 13 | -------------------------------------------------------------------------------- /lib/three-ffi/Renderer/Renderer.js: -------------------------------------------------------------------------------- 1 | var ffi = require("ffi-utils") 2 | 3 | var WebGLRenderer = require("three").WebGLRenderer 4 | 5 | var createWebGLRenderer = function() { 6 | return new WebGLRenderer() 7 | } 8 | 9 | // TODO: make this get a param from window 10 | var setPixelRatio = function(renderer) { 11 | return function() { 12 | renderer.setPixelRatio( window.devicePixelRatio) 13 | return renderer 14 | } 15 | } 16 | 17 | // TODO: Use something like Ramda curry fn to make this easy 18 | // window.innerWidth, window.innerHeight 19 | var setSize = function(width) { 20 | return function(height) { 21 | return function(renderer) { 22 | return function() { 23 | renderer.setSize( width, height) 24 | return renderer 25 | } 26 | } 27 | } 28 | } 29 | 30 | // Had to force this to take a number that doesn't need 31 | var render = function(scene) { 32 | return function (camera) { 33 | return function(renderer) { 34 | return function() { 35 | renderer.render(scene, camera) 36 | } 37 | } 38 | } 39 | } 40 | 41 | var mount = function(renderer) { 42 | return function() { 43 | document.body.appendChild( renderer.domElement); 44 | } 45 | } 46 | 47 | var setShadowMap = ffi.curry2( 48 | function(bool, renderer) { 49 | renderer.shadowMap.enabled = bool 50 | } 51 | ) 52 | 53 | module.exports = { 54 | createWebGLRenderer: createWebGLRenderer, 55 | setPixelRatio: setPixelRatio, 56 | setSize: setSize, 57 | mount: mount, 58 | render: render, 59 | setShadowMap: setShadowMap 60 | } 61 | -------------------------------------------------------------------------------- /lib/three-ffi/Renderer/Renderer.purs: -------------------------------------------------------------------------------- 1 | module Three.Renderer where 2 | 3 | import Effect 4 | 5 | import Prelude (Unit) 6 | import Three.Types (Renderer, Scene, Camera) 7 | 8 | foreign import createWebGLRenderer :: Effect Renderer 9 | foreign import setPixelRatio :: Renderer -> Effect Unit 10 | foreign import setSize :: Number -> Number -> Renderer -> Effect Unit 11 | foreign import mount :: Renderer -> Effect Unit 12 | foreign import render :: Scene -> Camera -> Renderer -> Effect Unit 13 | foreign import setShadowMap :: Boolean -> Renderer -> Effect Unit -------------------------------------------------------------------------------- /lib/three-ffi/Scene/Scene.js: -------------------------------------------------------------------------------- 1 | var Scene = require("three").Scene 2 | var Color = require("three").Color 3 | var Fog = require("three").Fog 4 | 5 | var create = function() { 6 | return new Scene() 7 | } 8 | 9 | // Color has to be a Three.Color 10 | var setBackground = function(color) { 11 | return function(scene) { 12 | return function() { 13 | // scene.fog = new Fog(new Color( 0x000000), 1800, 3000) 14 | scene.background = color 15 | return scene 16 | } 17 | } 18 | } 19 | 20 | var add = function(scene) { 21 | return function(object) { 22 | return function() { 23 | scene.add(object) 24 | return scene 25 | } 26 | } 27 | } 28 | 29 | var debug = function(scene) { 30 | return function() { 31 | window.scene = scene 32 | } 33 | } 34 | 35 | module.exports = { 36 | create: create, 37 | setBackground: setBackground, 38 | add: add, 39 | debug: debug 40 | } 41 | -------------------------------------------------------------------------------- /lib/three-ffi/Scene/Scene.purs: -------------------------------------------------------------------------------- 1 | module Three.Scene where 2 | 3 | import Prelude (Unit) 4 | import Three.Types (Color, Scene) 5 | import Effect 6 | 7 | foreign import create :: Effect Scene 8 | 9 | -- Do not return Scene on any of this side effectful functions 10 | foreign import setBackground :: Color -> Scene -> Effect Unit 11 | foreign import add :: ∀ t. Scene -> t -> Effect Unit 12 | foreign import debug :: Scene -> Effect Unit 13 | -------------------------------------------------------------------------------- /lib/three-ffi/Three.js: -------------------------------------------------------------------------------- 1 | // Debug only 2 | var THREE = require("three") 3 | window.THREE = THREE; 4 | // EO Debug only 5 | 6 | var Color = require("three").Color 7 | var AxesHelper = require("three").AxesHelper 8 | var Geometry = require("three").Geometry 9 | var Vector3 = require("three").Vector3 10 | var Vector2 = require("three").Vector2 11 | 12 | // Simple string implementation for color, no checks... 13 | exports.createColor = function(color) { 14 | return function() { 15 | return new Color(color) 16 | } 17 | } 18 | 19 | exports.createAxesHelper = function(size) { 20 | return function() { 21 | return new AxesHelper(size) 22 | } 23 | } 24 | 25 | exports.createGeometry = function() { 26 | return new Geometry() 27 | } 28 | 29 | exports.createVector2 = function (x) { 30 | return function(y) { 31 | return function() { 32 | return new Vector2(x, y) 33 | } 34 | } 35 | } 36 | 37 | // Vector3 38 | exports.createVector3 = function (x) { 39 | return function(y) { 40 | return function(z) { 41 | return function() { 42 | return new Vector3(x, y, z) 43 | } 44 | } 45 | } 46 | } 47 | 48 | exports.getVector3Position = function(vs) { 49 | return function() { 50 | return { 51 | x:vs.x, 52 | y:vs.y, 53 | z:vs.z 54 | } 55 | } 56 | } 57 | 58 | exports.updateVector3Position = function(x) { 59 | return function(y) { 60 | return function(z) { 61 | return function(v3) { 62 | return function() { 63 | v3.x = x 64 | v3.y = y 65 | v3.z = z 66 | } 67 | } 68 | } 69 | } 70 | } 71 | 72 | // how to make this actually inmutable, manage this ref handling from PS instead of JS 73 | exports.pushVertices = function(geometry) { 74 | return function(vector3) { 75 | return function() { 76 | geometry.vertices.push(vector3) 77 | return geometry 78 | } 79 | } 80 | } 81 | 82 | // Todo use DOM to abstract this to any event and use it directly from PS 83 | exports.onDOMContentLoaded = function(cb) { 84 | return function() { 85 | document.addEventListener("DOMContentLoaded", cb) 86 | } 87 | } 88 | 89 | exports.onResize = function(cb) { 90 | return function() { 91 | window.addEventListener("resize", cb) 92 | } 93 | } 94 | 95 | // debug function 96 | exports.voidEff = function() { 97 | return function() { 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /lib/three-ffi/Three.purs: -------------------------------------------------------------------------------- 1 | module Three where 2 | 3 | import Prelude 4 | import Effect 5 | import Three.Types (Color, Geometry, Vector2, Vector3) 6 | 7 | foreign import createColor :: String -> Effect Color 8 | foreign import createAxesHelper :: Number -> Effect Unit 9 | foreign import createGeometry :: Effect Geometry 10 | 11 | foreign import createVector2 :: Number -> Number -> Effect Vector2 12 | foreign import createVector3 :: Number -> Number -> Number -> Effect Vector3 13 | foreign import pushVertices :: Geometry -> Vector3 -> Effect Unit 14 | 15 | foreign import updateVector3Position :: Number -> Number -> Number -> Vector3 -> Effect Unit 16 | 17 | foreign import getVector3Position 18 | :: Vector3 19 | -> Effect { x :: Number, y :: Number, z :: Number } 20 | 21 | -- TODO this is too specific and JS reliant 22 | foreign import onDOMContentLoaded :: Effect Unit 23 | foreign import onResize :: Effect Unit 24 | 25 | foreign import voidEff :: Effect Unit 26 | 27 | -------------------------------------------------------------------------------- /lib/three-ffi/Types.purs: -------------------------------------------------------------------------------- 1 | module Three.Types where 2 | 3 | foreign import data Scene :: Type 4 | 5 | foreign import data Renderer :: Type 6 | 7 | foreign import data Camera :: Type 8 | 9 | foreign import data Color :: Type 10 | 11 | foreign import data Vector2 :: Type 12 | 13 | foreign import data Vector3 :: Type 14 | 15 | -- Core 16 | foreign import data Geometry :: Type 17 | 18 | -- Extras.Core 19 | foreign import data Path :: Type 20 | foreign import data Shape :: Type 21 | 22 | -- Materials 23 | foreign import data Material :: Type 24 | 25 | -- Internal ThreeJS representation of Object3D 26 | foreign import data Object3D_ :: Type 27 | 28 | foreign import data AxesHelper :: Type 29 | 30 | -- Objects (Amar recommendation) 31 | -- Here we lose the reference to Object3D_ 32 | -- data ObjectType = Mesh | Points | Light | Line 33 | 34 | -- Making Object3D polymorphic allows us to create instaces for it 35 | -- but making it completely polymorphic loses some safety 36 | -- data Object3D a = Object 37 | -- { objectType :: ObjectType 38 | -- , object :: a 39 | -- } 40 | 41 | -- instance Functor Object3D where 42 | -- map f (Object3D t a) = Object3D t (f a) 43 | 44 | -- from chexxor #purescript-beginners 45 | data Object3DTag = Mesh | Points | Light | Line 46 | 47 | newtype Object3D = Object3D 48 | { unObject3D :: Object3D_ 49 | , tag :: Object3DTag 50 | } 51 | -- setPosition :: forall e. Number -> Number -> Number -> { o :: Object3D_ | e } 52 | 53 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "rlucha_purescript_playground", 3 | "name": "Roberto Lucha - Purescript Playground", 4 | "start_url": "index.html", 5 | "background_color": "#000", 6 | "theme_color": "#FF5C60", 7 | "display": "standalone", 8 | "icons": [ 9 | { 10 | "src": "icon.png", 11 | "type": "image/png", 12 | "sizes": "144x144" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "purescript_linear", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "js": "webpack --watch --config config/webpack.config.js --mode development", 11 | "build": "webpack --config ./config/webpack.config.js --mode production", 12 | "ps": "pulp --psc-package --watch build -I src:lib", 13 | "repl": "pulp --psc-package repl -I src:lib", 14 | "start": "./run-dev.sh" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/rlucha/purescript-exercises.git" 19 | }, 20 | "author": "", 21 | "license": "ISC", 22 | "bugs": { 23 | "url": "https://github.com/rlucha/purescript-exercises/issues" 24 | }, 25 | "homepage": "https://github.com/rlucha/purescript-exercises#readme", 26 | "devDependencies": { 27 | "babel-core": "^6.26.0", 28 | "babel-loader": "^7.1.4", 29 | "babel-preset-env": "^1.6.1", 30 | "purty": "^0.5.0", 31 | "webpack": "^4.1.1", 32 | "webpack-cli": "^2.0.12", 33 | "webpack-dev-server": "^2.11.2" 34 | }, 35 | "dependencies": { 36 | "lodash": "^4.17.5", 37 | "lodash.curry": "^4.1.1", 38 | "rlite-router": "^2.0.3", 39 | "three": "^0.89.0", 40 | "three-orbit-controls": "^82.1.0", 41 | "ffi-utils": "file:lib/ffi-utils" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /psc-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "purescript-threejs", 3 | "set": "psc-0.12.0-20180625", 4 | "source": "https://github.com/purescript/package-sets.git", 5 | "depends": [ 6 | "web-html", 7 | "effect", 8 | "foreign", 9 | "foreign-generic", 10 | "generics-rep", 11 | "math", 12 | "maybe", 13 | "prelude", 14 | "psci-support", 15 | "console" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /run-dev.sh: -------------------------------------------------------------------------------- 1 | npm run js & 2 | P1=$! 3 | npm run ps & 4 | P2=$! 5 | http-server -c1 & 6 | P3=$! 7 | wait $P1 $P2 $P3 8 | -------------------------------------------------------------------------------- /scripts/building_importer.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var buildings = require("./se228np_1km.json") 3 | var results = JSON.stringify(buildings.map (b=> ({coordinates: JSON.parse(b.points).map(p => ({x: p[0], y: 0.0, z: p[1]}))}))) 4 | 5 | fs.writeFile("./buildings_se228np_1km.json", results , function(err) { 6 | if(err) { 7 | return console.log(err); 8 | } 9 | 10 | console.log("The file was saved!"); 11 | }); 12 | -------------------------------------------------------------------------------- /scripts/buildings_se228np_1km.json: -------------------------------------------------------------------------------- 1 | [{"coordinates":[{"x":-8193.47074475547,"y":0,"z":6699122.20429101},{"x":-8183.90840049633,"y":0,"z":6699116.34689956},{"x":-8169.73742931835,"y":0,"z":6699139.47290553},{"x":-8179.31090552657,"y":0,"z":6699145.33031358},{"x":-8193.47074475547,"y":0,"z":6699122.20429101}]},{"coordinates":[{"x":-8179.14392629038,"y":0,"z":6699125.99016821},{"x":-8166.93217815036,"y":0,"z":6699118.77557356},{"x":-8151.51442867549,"y":0,"z":6699144.81243282},{"x":-8163.72617681551,"y":0,"z":6699152.04490848},{"x":-8179.14392629038,"y":0,"z":6699125.99016821}]},{"coordinates":[{"x":-7112.82565593069,"y":0,"z":6698968.18129586},{"x":-7099.22241415575,"y":0,"z":6698953.716677},{"x":-7058.76891120148,"y":0,"z":6698991.75332228},{"x":-7072.36102102733,"y":0,"z":6699006.21800858},{"x":-7112.82565593069,"y":0,"z":6698968.18129586}]},{"coordinates":[{"x":-7050.72051201712,"y":0,"z":6699085.64923695},{"x":-7046.08962120012,"y":0,"z":6699080.27403275},{"x":-7039.24347251634,"y":0,"z":6699086.16711395},{"x":-7035.82596414898,"y":0,"z":6699082.20267704},{"x":-7031.02809409579,"y":0,"z":6699086.34569224},{"x":-7033.03184493007,"y":0,"z":6699088.66721029},{"x":-7025.88513362114,"y":0,"z":6699094.82816526},{"x":-7034.53465805578,"y":0,"z":6699104.86428158},{"x":-7046.8020659412,"y":0,"z":6699094.27457202},{"x":-7044.20832180572,"y":0,"z":6699091.27445444},{"x":-7050.72051201712,"y":0,"z":6699085.64923695}]},{"coordinates":[{"x":-6975.80249471325,"y":0,"z":6698854.94723062},{"x":-6974.644772009,"y":0,"z":6698835.62563102},{"x":-6971.51669431771,"y":0,"z":6698835.80420382},{"x":-6971.28292338704,"y":0,"z":6698831.91131767},{"x":-6964.01376063824,"y":0,"z":6698832.35774947},{"x":-6964.33658716154,"y":0,"z":6698837.7327903},{"x":-6961.64265548435,"y":0,"z":6698837.89350586},{"x":-6962.23264878555,"y":0,"z":6698847.85787684},{"x":-6957.7910011029,"y":0,"z":6698848.12573644},{"x":-6958.26967491331,"y":0,"z":6698856.00081269},{"x":-6975.80249471325,"y":0,"z":6698854.94723062}]},{"coordinates":[{"x":-6975.2904250556,"y":0,"z":6698873.21529156},{"x":-6974.51118862005,"y":0,"z":6698857.6436867},{"x":-6959.53871710835,"y":0,"z":6698858.4472665},{"x":-6959.7279602427,"y":0,"z":6698862.17944927},{"x":-6952.44766554482,"y":0,"z":6698862.57231071},{"x":-6953.03765884603,"y":0,"z":6698874.59030856},{"x":-6975.2904250556,"y":0,"z":6698873.21529156}]},{"coordinates":[{"x":-6976.00286979668,"y":0,"z":6698893.03698754},{"x":-6974.93420268506,"y":0,"z":6698877.48320221},{"x":-6957.70194551026,"y":0,"z":6698878.67964618},{"x":-6958.77061262188,"y":0,"z":6698894.2334338},{"x":-6976.00286979668,"y":0,"z":6698893.03698754}]},{"coordinates":[{"x":-6979.64301714562,"y":0,"z":6698918.16239573},{"x":-6977.17172445001,"y":0,"z":6698895.92988774},{"x":-6965.52770571303,"y":0,"z":6698897.23347891},{"x":-6965.83940028725,"y":0,"z":6698900.07280833},{"x":-6959.63890465007,"y":0,"z":6698900.76924777},{"x":-6961.78737082238,"y":0,"z":6698920.14457408},{"x":-6979.64301714562,"y":0,"z":6698918.16239573}]},{"coordinates":[{"x":-6985.01974855093,"y":0,"z":6698963.94905287},{"x":-6969.66879077054,"y":0,"z":6698943.19859372},{"x":-6953.70557579079,"y":0,"z":6698955.00241986},{"x":-6969.05653357118,"y":0,"z":6698975.77076662},{"x":-6985.01974855093,"y":0,"z":6698963.94905287}]},{"coordinates":[{"x":-7006.27063934337,"y":0,"z":6699000.98571786},{"x":-6995.06076662049,"y":0,"z":6698985.86030929},{"x":-6962.49981556345,"y":0,"z":6699010.28955453},{"x":-6973.72082023541,"y":0,"z":6699025.0757122},{"x":-6980.41112163209,"y":0,"z":6699019.98627085},{"x":-6987.79160387169,"y":0,"z":6699020.486286},{"x":-6990.00686173847,"y":0,"z":6699017.2897611},{"x":-6990.25176461822,"y":0,"z":6699012.86105829},{"x":-7006.27063934337,"y":0,"z":6699000.98571786}]},{"coordinates":[{"x":-6933.9352342259,"y":0,"z":6698938.80564615},{"x":-6923.09271582264,"y":0,"z":6698921.68031619},{"x":-6905.24820144847,"y":0,"z":6698934.84128086},{"x":-6881.2699831316,"y":0,"z":6698952.16307132},{"x":-6878.03058594952,"y":0,"z":6698950.14517013},{"x":-6860.62021758945,"y":0,"z":6698961.48470987},{"x":-6853.28426314617,"y":0,"z":6698965.82409696},{"x":-6827.39134958766,"y":0,"z":6698986.48532561},{"x":-6844.00021761401,"y":0,"z":6699007.3073255},{"x":-6849.4437407138,"y":0,"z":6699002.96791633},{"x":-6858.03760540305,"y":0,"z":6698996.61059679},{"x":-6863.35867706296,"y":0,"z":6699003.80722574},{"x":-6884.96579022594,"y":0,"z":6698987.87821932},{"x":-6878.91000992679,"y":0,"z":6698979.64586383},{"x":-6893.02532135937,"y":0,"z":6698969.59204401},{"x":-6887.75990944485,"y":0,"z":6698962.69902372},{"x":-6899.50411572354,"y":0,"z":6698953.37738378},{"x":-6914.48771918432,"y":0,"z":6698943.25216627},{"x":-6917.32636619954,"y":0,"z":6698948.93085814},{"x":-6933.9352342259,"y":0,"z":6698938.80564615}]},{"coordinates":[{"x":-6925.18552224955,"y":0,"z":6699015.93257773},{"x":-6896.82131599542,"y":0,"z":6698989.96756031},{"x":-6883.09562278061,"y":0,"z":6699004.28938226},{"x":-6911.7492597108,"y":0,"z":6699029.96872197},{"x":-6925.18552224955,"y":0,"z":6699015.93257773}]},{"coordinates":[{"x":-7041.30288309601,"y":0,"z":6699053.02305201},{"x":-7032.37505993439,"y":0,"z":6699041.11193765},{"x":-7019.75142967843,"y":0,"z":6699050.5586821},{"x":-7016.66787978346,"y":0,"z":6699046.45140056},{"x":-6997.32055228359,"y":0,"z":6699060.9518994},{"x":-7007.0053479826,"y":0,"z":6699074.16666218},{"x":-7026.11890455181,"y":0,"z":6699059.84471755},{"x":-7028.28963462228,"y":0,"z":6699062.75553468},{"x":-7041.30288309601,"y":0,"z":6699053.02305201}]},{"coordinates":[{"x":-6997.32055228359,"y":0,"z":6699060.9518994},{"x":-6974.27741768938,"y":0,"z":6699055.95172447},{"x":-6971.01575660914,"y":0,"z":6699070.98797404},{"x":-6994.05889120335,"y":0,"z":6699075.98815819},{"x":-6997.32055228359,"y":0,"z":6699060.9518994}]},{"coordinates":[{"x":-6971.48329847047,"y":0,"z":6699057.43391887},{"x":-6957.91345254277,"y":0,"z":6699037.98683556},{"x":-6954.90782629135,"y":0,"z":6699040.0761894},{"x":-6940.46968833547,"y":0,"z":6699019.36125196},{"x":-6924.53986920295,"y":0,"z":6699030.46873773},{"x":-6940.15799376124,"y":0,"z":6699052.88018997},{"x":-6947.5050801536,"y":0,"z":6699047.75501578},{"x":-6959.88380752981,"y":0,"z":6699065.52349059},{"x":-6971.48329847047,"y":0,"z":6699057.43391887}]},{"coordinates":[{"x":-6930.85168433093,"y":0,"z":6699065.7199262},{"x":-6901.93088062283,"y":0,"z":6699047.3978609},{"x":-6893.33701593359,"y":0,"z":6699060.96975718},{"x":-6922.25781964169,"y":0,"z":6699079.29185296},{"x":-6930.85168433093,"y":0,"z":6699065.7199262}]},{"coordinates":[{"x":-6975.00099437954,"y":0,"z":6699097.45326923},{"x":-6959.43852956664,"y":0,"z":6699087.57788251},{"x":-6953.40501316564,"y":0,"z":6699097.07825432},{"x":-6944.77775262916,"y":0,"z":6699091.6137534},{"x":-6932.78864347073,"y":0,"z":6699110.48951232},{"x":-6937.20802725522,"y":0,"z":6699113.2932002},{"x":-6933.07807414679,"y":0,"z":6699119.82918971},{"x":-6923.94987590174,"y":0,"z":6699114.02537363},{"x":-6916.84769238913,"y":0,"z":6699125.20441997},{"x":-6910.85870378445,"y":0,"z":6699121.40068523},{"x":-6901.15164418728,"y":0,"z":6699136.68706658},{"x":-6923.13724361895,"y":0,"z":6699150.65198674},{"x":-6929.70509357576,"y":0,"z":6699140.33008693},{"x":-6934.23579685104,"y":0,"z":6699143.20521688},{"x":-6943.58663407768,"y":0,"z":6699128.50813468},{"x":-6949.75373386762,"y":0,"z":6699132.41902031},{"x":-6967.39787315836,"y":0,"z":6699104.68570289},{"x":-6969.99161729384,"y":0,"z":6699105.34644406},{"x":-6975.00099437954,"y":0,"z":6699097.45326923}]},{"coordinates":[{"x":-6862.4235933403,"y":0,"z":6698945.87722146},{"x":-6852.91690882656,"y":0,"z":6698933.91269106},{"x":-6843.93342591954,"y":0,"z":6698941.05569217},{"x":-6839.55856993136,"y":0,"z":6698935.53772327},{"x":-6832.82374073837,"y":0,"z":6698940.89497458},{"x":-6836.66426317074,"y":0,"z":6698945.71650377},{"x":-6832.2671432844,"y":0,"z":6698949.21657859},{"x":-6828.63812788454,"y":0,"z":6698944.64505259},{"x":-6821.79197920076,"y":0,"z":6698950.09159753},{"x":-6825.66589748036,"y":0,"z":6698954.96670478},{"x":-6820.41161751492,"y":0,"z":6698959.14537045},{"x":-6816.84939380954,"y":0,"z":6698954.68098413},{"x":-6810.8381413067,"y":0,"z":6698959.46680636},{"x":-6814.05527459062,"y":0,"z":6698963.50261387},{"x":-6804.55972202596,"y":0,"z":6698971.05636513},{"x":-6814.70092763722,"y":0,"z":6698983.80668455},{"x":-6862.4235933403,"y":0,"z":6698945.87722146}]},{"coordinates":[{"x":-6804.17010380818,"y":0,"z":6699010.98600339},{"x":-6799.2609142642,"y":0,"z":6699008.28949662},{"x":-6803.71369389593,"y":0,"z":6699000.19998166},{"x":-6792.49268922397,"y":0,"z":6698994.03909816},{"x":-6777.62040525399,"y":0,"z":6699021.11130498},{"x":-6785.78012392913,"y":0,"z":6699025.59358536},{"x":-6788.86367382411,"y":0,"z":6699019.96841317},{"x":-6796.82301741583,"y":0,"z":6699024.34354676},{"x":-6804.17010380818,"y":0,"z":6699010.98600339}]},{"coordinates":[{"x":-6781.21602480661,"y":0,"z":6699107.73939903},{"x":-6772.49970867749,"y":0,"z":6699094.1138514},{"x":-6733.94976901578,"y":0,"z":6699118.77557356},{"x":-6742.58816150134,"y":0,"z":6699132.2940148},{"x":-6757.78327199462,"y":0,"z":6699122.57930707},{"x":-6767.21203286482,"y":0,"z":6699137.32995241},{"x":-6780.02490625512,"y":0,"z":6699129.13316193},{"x":-6770.66293707941,"y":0,"z":6699114.48967876},{"x":-6781.21602480661,"y":0,"z":6699107.73939903}]},{"coordinates":[{"x":-6742.2875988762,"y":0,"z":6699055.46956491},{"x":-6734.65108180778,"y":0,"z":6699043.57630471},{"x":-6697.05848976689,"y":0,"z":6699067.73785599},{"x":-6705.46311132178,"y":0,"z":6699080.82762504},{"x":-6715.93827540543,"y":0,"z":6699074.09523097},{"x":-6725.61193915537,"y":0,"z":6699089.14937182},{"x":-6740.70686210694,"y":0,"z":6699079.45257328},{"x":-6730.25396192145,"y":0,"z":6699063.20197912},{"x":-6742.2875988762,"y":0,"z":6699055.46956491}]},{"coordinates":[{"x":-8365.52614972556,"y":0,"z":6699609.70400863},{"x":-8355.2736246235,"y":0,"z":6699596.89913396},{"x":-8326.28602922093,"y":0,"z":6699620.08007942},{"x":-8336.53855432299,"y":0,"z":6699632.90284951},{"x":-8365.52614972556,"y":0,"z":6699609.70400863}]},{"coordinates":[{"x":-8302.77535276539,"y":0,"z":6699660.12004948},{"x":-8289.63965285178,"y":0,"z":6699646.42214286},{"x":-8259.75036957379,"y":0,"z":6699675.08597635},{"x":-8272.88606948739,"y":0,"z":6699688.7839311},{"x":-8302.77535276539,"y":0,"z":6699660.12004948}]},{"coordinates":[{"x":-8364.74691329,"y":0,"z":6699942.54850766},{"x":-8350.24198363964,"y":0,"z":6699925.56394751},{"x":-8323.08002788608,"y":0,"z":6699952.83570325},{"x":-8313.66239896497,"y":0,"z":6699969.07021018},{"x":-8309.66602924549,"y":0,"z":6699973.21367587},{"x":-8315.48803861398,"y":0,"z":6699980.07183061},{"x":-8314.70880217843,"y":0,"z":6699982.16142578},{"x":-8327.93355768467,"y":0,"z":6699993.82387701},{"x":-8339.32154159282,"y":0,"z":6699981.37559505},{"x":-8341.41434801973,"y":0,"z":6699982.6793597},{"x":-8361.8414745803,"y":0,"z":6699963.56940553},{"x":-8352.41271371011,"y":0,"z":6699954.40735927},{"x":-8364.74691329,"y":0,"z":6699942.54850766}]},{"coordinates":[{"x":-8369.23308876897,"y":0,"z":6700120.45095239},{"x":-8362.59844711769,"y":0,"z":6700099.14388945},{"x":-8343.15093207611,"y":0,"z":6700105.19844736},{"x":-8349.77444177831,"y":0,"z":6700126.50552611},{"x":-8369.23308876897,"y":0,"z":6700120.45095239}]},{"coordinates":[{"x":-7382.02958051606,"y":0,"z":6699355.82477814},{"x":-7365.23146935536,"y":0,"z":6699353.43175039},{"x":-7360.02171718623,"y":0,"z":6699390.09515552},{"x":-7376.81982834694,"y":0,"z":6699392.48819402},{"x":-7382.02958051606,"y":0,"z":6699355.82477814}]},{"coordinates":[{"x":-7362.04773191867,"y":0,"z":6699412.15042503},{"x":-7344.32566898438,"y":0,"z":6699409.15019053},{"x":-7338.0695136018,"y":0,"z":6699446.24245289},{"x":-7355.80270848517,"y":0,"z":6699449.22484241},{"x":-7362.04773191867,"y":0,"z":6699412.15042503}]},{"coordinates":[{"x":-7813.74882971054,"y":0,"z":6699735.45001742},{"x":-7808.04927178192,"y":0,"z":6699723.07356667},{"x":-7774.70908428934,"y":0,"z":6699738.43251268},{"x":-7780.41977416703,"y":0,"z":6699750.82684602},{"x":-7813.74882971054,"y":0,"z":6699735.45001742}]},{"coordinates":[{"x":-7758.56775812431,"y":0,"z":6699827.03276471},{"x":-7747.90335090632,"y":0,"z":6699796.0466772},{"x":-7738.00704817479,"y":0,"z":6699799.72571082},{"x":-7742.30398051941,"y":0,"z":6699812.19157497},{"x":-7714.07335765424,"y":0,"z":6699821.63921249},{"x":-7720.44083252761,"y":0,"z":6699840.1594713},{"x":-7758.56775812431,"y":0,"z":6699827.03276471}]},{"coordinates":[{"x":-7737.21667979016,"y":0,"z":6699954.6038163},{"x":-7723.89173674221,"y":0,"z":6699947.62066497},{"x":-7720.64120761104,"y":0,"z":6699953.83584796},{"x":-7718.9936791473,"y":0,"z":6699952.97858106},{"x":-7717.78029669766,"y":0,"z":6699955.28248605},{"x":-7719.4278251614,"y":0,"z":6699956.1397532},{"x":-7716.97879636395,"y":0,"z":6699960.80114486},{"x":-7727.06434222982,"y":0,"z":6699966.10549033},{"x":-7729.21280840213,"y":0,"z":6699962.01560749},{"x":-7732.44107363513,"y":0,"z":6699963.69442378},{"x":-7737.21667979016,"y":0,"z":6699954.6038163}]},{"coordinates":[{"x":-7647.89392037764,"y":0,"z":6699810.42349279},{"x":-7629.7711072765,"y":0,"z":6699805.85148409},{"x":-7626.754349076,"y":0,"z":6699817.74585582},{"x":-7644.87716217714,"y":0,"z":6699822.33573063},{"x":-7647.89392037764,"y":0,"z":6699810.42349279}]},{"coordinates":[{"x":-7459.36323077015,"y":0,"z":6699747.21927155},{"x":-7442.56511960945,"y":0,"z":6699721.8412804},{"x":-7420.90234670108,"y":0,"z":6699735.68218767},{"x":-7437.96762463968,"y":0,"z":6699761.52456385},{"x":-7459.36323077015,"y":0,"z":6699747.21927155}]},{"coordinates":[{"x":-7412.23055836828,"y":0,"z":6699744.54038065},{"x":-7383.30975466019,"y":0,"z":6699702.80337405},{"x":-7360.15530057519,"y":0,"z":6699718.85879119},{"x":-7389.0649723342,"y":0,"z":6699760.59587994},{"x":-7412.23055836828,"y":0,"z":6699744.54038065}]},{"coordinates":[{"x":-7468.85878333482,"y":0,"z":6699797.31469346},{"x":-7463.55997557306,"y":0,"z":6699788.49216189},{"x":-7457.81588984813,"y":0,"z":6699792.47480147},{"x":-7455.52270833778,"y":0,"z":6699788.67075555},{"x":-7456.75835468559,"y":0,"z":6699787.79564665},{"x":-7454.46517317525,"y":0,"z":6699783.81300934},{"x":-7459.85303652964,"y":0,"z":6699780.36615442},{"x":-7454.03102716115,"y":0,"z":6699771.36504791},{"x":-7449.43353219139,"y":0,"z":6699774.27611896},{"x":-7445.37037077744,"y":0,"z":6699768.6325711},{"x":-7451.54860251646,"y":0,"z":6699764.66780247},{"x":-7448.55410821413,"y":0,"z":6699759.89936708},{"x":-7428.6947110566,"y":0,"z":6699773.04382495},{"x":-7433.63729644783,"y":0,"z":6699780.90193488},{"x":-7431.86731654421,"y":0,"z":6699782.13423008},{"x":-7442.19776528983,"y":0,"z":6699798.2969597},{"x":-7440.33872979358,"y":0,"z":6699799.52925753},{"x":-7449.87881015456,"y":0,"z":6699814.35256481},{"x":-7465.76410149077,"y":0,"z":6699804.29771609},{"x":-7463.55997557306,"y":0,"z":6699800.94014947},{"x":-7468.85878333482,"y":0,"z":6699797.31469346}]},{"coordinates":[{"x":-7479.84601707611,"y":0,"z":6699842.23117113},{"x":-7475.78285566216,"y":0,"z":6699836.05179214},{"x":-7477.01850200996,"y":0,"z":6699835.35527283},{"x":-7472.52119458192,"y":0,"z":6699827.49711044},{"x":-7476.22813362533,"y":0,"z":6699825.371836},{"x":-7467.8457759686,"y":0,"z":6699811.42362003},{"x":-7455.31120130528,"y":0,"z":6699819.01387545},{"x":-7457.51532722298,"y":0,"z":6699822.55004391},{"x":-7452.39463064649,"y":0,"z":6699825.72902494},{"x":-7457.33721603771,"y":0,"z":6699834.55159679},{"x":-7445.15886374493,"y":0,"z":6699841.96327888},{"x":-7452.21651946122,"y":0,"z":6699854.41134807},{"x":-7466.16485165762,"y":0,"z":6699846.1245395},{"x":-7468.36897757533,"y":0,"z":6699849.30352973},{"x":-7479.84601707611,"y":0,"z":6699842.23117113}]},{"coordinates":[{"x":-7442.56511960945,"y":0,"z":6699870.9135523},{"x":-7416.82805333804,"y":0,"z":6699838.51639938},{"x":-7386.60481158767,"y":0,"z":6699862.51956979},{"x":-7412.34187785907,"y":0,"z":6699894.91681804},{"x":-7442.56511960945,"y":0,"z":6699870.9135523}]},{"coordinates":[{"x":-7356.55968102256,"y":0,"z":6699778.65165717},{"x":-7348.0326080278,"y":0,"z":6699766.22156292},{"x":-7327.66114121263,"y":0,"z":6699780.20542029},{"x":-7336.1882142074,"y":0,"z":6699792.63553585},{"x":-7356.55968102256,"y":0,"z":6699778.65165717}]},{"coordinates":[{"x":-7424.74286913344,"y":0,"z":6699830.78325016},{"x":-7397.13563541671,"y":0,"z":6699789.1886772},{"x":-7383.33201855834,"y":0,"z":6699798.35053786},{"x":-7410.928120326,"y":0,"z":6699839.96301703},{"x":-7424.74286913344,"y":0,"z":6699830.78325016}]},{"coordinates":[{"x":-7380.84959391366,"y":0,"z":6699829.47950978},{"x":-7367.01258120805,"y":0,"z":6699808.63755158},{"x":-7348.76731666703,"y":0,"z":6699820.72838118},{"x":-7362.60432937264,"y":0,"z":6699841.58822975},{"x":-7380.84959391366,"y":0,"z":6699829.47950978}]},{"coordinates":[{"x":-7514.02110074965,"y":0,"z":6700007.59380644},{"x":-7507.76494536707,"y":0,"z":6699972.03493111},{"x":-7494.64037740254,"y":0,"z":6699974.33884149},{"x":-7500.6404979563,"y":0,"z":6700010.16562463},{"x":-7514.02110074965,"y":0,"z":6700007.59380644}]},{"coordinates":[{"x":-7494.48453011543,"y":0,"z":6699910.72257847},{"x":-7466.32069894473,"y":0,"z":6699907.22209104},{"x":-7464.94033725889,"y":0,"z":6699918.29506664},{"x":-7493.10416842959,"y":0,"z":6699921.79555883},{"x":-7494.48453011543,"y":0,"z":6699910.72257847}]},{"coordinates":[{"x":-7451.88256098884,"y":0,"z":6699905.41826901},{"x":-7434.55011627233,"y":0,"z":6699882.62942318},{"x":-7417.67408146807,"y":0,"z":6699895.45260603},{"x":-7435.00652618458,"y":0,"z":6699918.25934734},{"x":-7451.88256098884,"y":0,"z":6699905.41826901}]},{"coordinates":[{"x":-7496.56620459326,"y":0,"z":6699936.56550925},{"x":-7459.41889051555,"y":0,"z":6699928.18931885},{"x":-7462.14621803998,"y":0,"z":6699916.04475102},{"x":-7453.73046453601,"y":0,"z":6699914.15162885},{"x":-7451.00313701158,"y":0,"z":6699926.29619385},{"x":-7442.76549469287,"y":0,"z":6699924.43878862},{"x":-7440.52797292793,"y":0,"z":6699934.35090797},{"x":-7434.30521339258,"y":0,"z":6699934.56522419},{"x":-7430.65393409457,"y":0,"z":6699938.38719785},{"x":-7432.07882357672,"y":0,"z":6699944.20946024},{"x":-7437.41102718572,"y":0,"z":6699948.19217586},{"x":-7435.1067137263,"y":0,"z":6699958.44365909},{"x":-7443.344356045,"y":0,"z":6699960.30107206},{"x":-7439.89345183041,"y":0,"z":6699973.21367587},{"x":-7447.15148263013,"y":0,"z":6699974.92821402},{"x":-7450.25729642326,"y":0,"z":6699961.87272952},{"x":-7488.90742362669,"y":0,"z":6699970.57043028},{"x":-7496.56620459326,"y":0,"z":6699936.56550925}]},{"coordinates":[{"x":-8279.17562071721,"y":0,"z":6700146.687471},{"x":-8250.2102892128,"y":0,"z":6700105.84140952},{"x":-8222.5362638016,"y":0,"z":6700125.45177992},{"x":-8251.50159530601,"y":0,"z":6700166.2979396},{"x":-8279.17562071721,"y":0,"z":6700146.687471}]},{"coordinates":[{"x":-8221.91287465316,"y":0,"z":6700182.1399464},{"x":-8205.61570120102,"y":0,"z":6700153.38503011},{"x":-8189.70814596666,"y":0,"z":6700162.40441841},{"x":-8206.0053194188,"y":0,"z":6700191.1593665},{"x":-8221.91287465316,"y":0,"z":6700182.1399464}]},{"coordinates":[{"x":-8183.71915736198,"y":0,"z":6700348.13459401},{"x":-8176.12716808988,"y":0,"z":6700345.11615462},{"x":-8174.36832013535,"y":0,"z":6700349.54558086},{"x":-8181.96030940745,"y":0,"z":6700352.56402189},{"x":-8183.71915736198,"y":0,"z":6700348.13459401}]},{"coordinates":[{"x":-7996.41298215322,"y":0,"z":6700187.10509128},{"x":-7984.94707460151,"y":0,"z":6700184.24745357},{"x":-7974.43851467063,"y":0,"z":6700230.11265972},{"x":-7986.85063789408,"y":0,"z":6700232.9703135},{"x":-7996.41298215322,"y":0,"z":6700187.10509128}]},{"coordinates":[{"x":-7982.07503173905,"y":0,"z":6700167.99465814},{"x":-7869.33065146362,"y":0,"z":6700142.2045745},{"x":-7865.51239292941,"y":0,"z":6700156.52841975},{"x":-7978.25677320484,"y":0,"z":6700182.33640891},{"x":-7982.07503173905,"y":0,"z":6700167.99465814}]},{"coordinates":[{"x":-7972.52381942898,"y":0,"z":6700370.54966706},{"x":-7901.82481082618,"y":0,"z":6700322.79045414},{"x":-7858.82209153273,"y":0,"z":6700285.51560082},{"x":-7831.11467027429,"y":0,"z":6700258.76068415},{"x":-7820.6061103434,"y":0,"z":6700270.22706626},{"x":-7848.31353160185,"y":0,"z":6700296.98202055},{"x":-7892.26246656703,"y":0,"z":6700338.07908723},{"x":-7964.87617041148,"y":0,"z":6700385.83838968},{"x":-7972.52381942898,"y":0,"z":6700370.54966706}]},{"coordinates":[{"x":-7827.29641174008,"y":0,"z":6700133.59599133},{"x":-7761.36187734322,"y":0,"z":6700112.57465525},{"x":-7757.54361880901,"y":0,"z":6700128.82734024},{"x":-7824.42436887761,"y":0,"z":6700150.7953066},{"x":-7827.29641174008,"y":0,"z":6700133.59599133}]},{"coordinates":[{"x":-7819.64876272258,"y":0,"z":6700239.66794347},{"x":-7778.56073867078,"y":0,"z":6700186.15849868},{"x":-7764.23392020569,"y":0,"z":6700197.62477872},{"x":-7805.32194425749,"y":0,"z":6700249.20537804},{"x":-7819.64876272258,"y":0,"z":6700239.66794347}]},{"coordinates":[{"x":-7735.92537369696,"y":0,"z":6700164.88698446},{"x":-7724.47059809433,"y":0,"z":6700149.68797679},{"x":-7718.35915804978,"y":0,"z":6700154.29589857},{"x":-7714.49637171925,"y":0,"z":6700149.18789242},{"x":-7709.36454319368,"y":0,"z":6700153.04568698},{"x":-7713.79505892726,"y":0,"z":6700158.92168313},{"x":-7709.32001539737,"y":0,"z":6700162.2972573},{"x":-7706.15854185884,"y":0,"z":6700158.10011502},{"x":-7700.22521299956,"y":0,"z":6700162.56516007},{"x":-7696.81883658128,"y":0,"z":6700158.0465345},{"x":-7692.66661957469,"y":0,"z":6700161.17206575},{"x":-7695.76130141875,"y":0,"z":6700165.26204846},{"x":-7688.77043739693,"y":0,"z":6700170.54866671},{"x":-7699.64635164743,"y":0,"z":6700184.94400267},{"x":-7716.7895532296,"y":0,"z":6700172.03106365},{"x":-7720.29611718958,"y":0,"z":6700176.67471848},{"x":-7735.92537369696,"y":0,"z":6700164.88698446}]},{"coordinates":[{"x":-7708.03984125324,"y":0,"z":6700215.82440585},{"x":-7691.19720229622,"y":0,"z":6700191.98093793},{"x":-7686.39933224303,"y":0,"z":6700195.35652578},{"x":-7677.46037713233,"y":0,"z":6700182.71147372},{"x":-7681.55693439353,"y":0,"z":6700179.8181171},{"x":-7665.98333763155,"y":0,"z":6700157.7607717},{"x":-7649.89767121192,"y":0,"z":6700169.13771083},{"x":-7646.70280182615,"y":0,"z":6700164.61908161},{"x":-7633.97898402848,"y":0,"z":6700173.62062212},{"x":-7647.17034368748,"y":0,"z":6700192.28456218},{"x":-7649.94219900824,"y":0,"z":6700190.3199349},{"x":-7665.88315008983,"y":0,"z":6700212.8774566},{"x":-7662.97771138013,"y":0,"z":6700214.94925111},{"x":-7680.25449635124,"y":0,"z":6700239.41789852},{"x":-7694.71489820529,"y":0,"z":6700229.20178279},{"x":-7692.84473075996,"y":0,"z":6700226.55845424},{"x":-7708.03984125324,"y":0,"z":6700215.82440585}]},{"coordinates":[{"x":-7762.31922496405,"y":0,"z":6700302.71523646},{"x":-7709.77642530962,"y":0,"z":6700237.75688582},{"x":-7697.35317013709,"y":0,"z":6700245.40111909},{"x":-7752.76801265398,"y":0,"z":6700312.27060526},{"x":-7762.31922496405,"y":0,"z":6700302.71523646}]},{"coordinates":[{"x":-7941.94435530807,"y":0,"z":6700433.61583257},{"x":-7880.79655901533,"y":0,"z":6700395.39385587},{"x":-7823.46702125679,"y":0,"z":6700352.40327648},{"x":-7776.65717537822,"y":0,"z":6700308.4484564},{"x":-7766.14861544733,"y":0,"z":6700318.00383192},{"x":-7812.00111370508,"y":0,"z":6700365.78087744},{"x":-7872.20269432609,"y":0,"z":6700408.77152734},{"x":-7931.43579537719,"y":0,"z":6700446.04694397},{"x":-7941.94435530807,"y":0,"z":6700433.61583257}]},{"coordinates":[{"x":-7661.59734969429,"y":0,"z":6700640.98210854},{"x":-7656.4766531178,"y":0,"z":6700625.55001805},{"x":-7654.77346490866,"y":0,"z":6700626.12157644},{"x":-7649.57484468862,"y":0,"z":6700627.83625184},{"x":-7650.32068527693,"y":0,"z":6700630.10462505},{"x":-7646.43563504825,"y":0,"z":6700631.40849341},{"x":-7645.67866251085,"y":0,"z":6700629.12225862},{"x":-7639.53382661906,"y":0,"z":6700631.15843645},{"x":-7641.47078575887,"y":0,"z":6700637.03477706},{"x":-7624.96210527422,"y":0,"z":6700642.50031347},{"x":-7630.43902422125,"y":0,"z":6700659.05769611},{"x":-7647.11468394209,"y":0,"z":6700653.53856482},{"x":-7644.79923853359,"y":0,"z":6700646.53695382},{"x":-7651.93481789344,"y":0,"z":6700644.17926983},{"x":-7651.43388018487,"y":0,"z":6700642.69678706},{"x":-7654.27252720009,"y":0,"z":6700641.75014158},{"x":-7654.76233295958,"y":0,"z":6700643.25048541},{"x":-7661.59734969429,"y":0,"z":6700640.98210854}]},{"coordinates":[{"x":-7633.40012267635,"y":0,"z":6700668.72065016},{"x":-7628.56885677593,"y":0,"z":6700654.11012517},{"x":-7614.63165652861,"y":0,"z":6700658.71833194},{"x":-7619.46292242904,"y":0,"z":6700673.32886518},{"x":-7633.40012267635,"y":0,"z":6700668.72065016}]},{"coordinates":[{"x":-7621.50006911056,"y":0,"z":6700680.54483502},{"x":-7616.12333770524,"y":0,"z":6700664.30891186},{"x":-7565.16127482008,"y":0,"z":6700681.18784255},{"x":-7570.5380062254,"y":0,"z":6700697.42379931},{"x":-7580.36751726244,"y":0,"z":6700694.15517175},{"x":-7579.84431565571,"y":0,"z":6700692.58337317},{"x":-7583.10597673595,"y":0,"z":6700691.49383116},{"x":-7583.62917834268,"y":0,"z":6700693.08349087},{"x":-7596.80940605261,"y":0,"z":6700688.70746207},{"x":-7596.23054470048,"y":0,"z":6700686.9570512},{"x":-7599.2361709519,"y":0,"z":6700685.97467793},{"x":-7599.81503230403,"y":0,"z":6700687.72508857},{"x":-7612.63903764341,"y":0,"z":6700683.47409193},{"x":-7612.03791239313,"y":0,"z":6700681.6522369},{"x":-7615.60013609851,"y":0,"z":6700680.47338974},{"x":-7616.2012613488,"y":0,"z":6700682.29524451},{"x":-7621.50006911056,"y":0,"z":6700680.54483502}]},{"coordinates":[{"x":-7566.93125472369,"y":0,"z":6700688.88607544},{"x":-7559.75114756752,"y":0,"z":6700667.20244035},{"x":-7501.25275515566,"y":0,"z":6700686.58196321},{"x":-7502.78896412861,"y":0,"z":6700691.20804967},{"x":-7510.08039077557,"y":0,"z":6700713.23111499},{"x":-7520.48876316474,"y":0,"z":6700709.80172865},{"x":-7518.83010275192,"y":0,"z":6700704.80054282},{"x":-7525.39795270872,"y":0,"z":6700702.62145566},{"x":-7524.85248720384,"y":0,"z":6700700.96034863},{"x":-7528.01396074236,"y":0,"z":6700699.90652822},{"x":-7528.55942624725,"y":0,"z":6700701.5854964},{"x":-7541.45022328111,"y":0,"z":6700697.31663117},{"x":-7540.79343828543,"y":0,"z":6700695.31615953},{"x":-7543.88812012948,"y":0,"z":6700694.29806255},{"x":-7544.54490512516,"y":0,"z":6700696.28067258},{"x":-7566.93125472369,"y":0,"z":6700688.88607544}]},{"coordinates":[{"x":-7509.2566265437,"y":0,"z":6700710.74838202},{"x":-7502.78896412861,"y":0,"z":6700691.20804967},{"x":-7491.65701504928,"y":0,"z":6700694.8874871},{"x":-7498.12467746437,"y":0,"z":6700714.44568967},{"x":-7509.2566265437,"y":0,"z":6700710.74838202}]},{"coordinates":[{"x":-7498.12467746437,"y":0,"z":6700714.44568967},{"x":-7491.65701504928,"y":0,"z":6700694.8874871},{"x":-7480.52506596995,"y":0,"z":6700698.56692619},{"x":-7487.00386033412,"y":0,"z":6700718.12513759},{"x":-7498.12467746437,"y":0,"z":6700714.44568967}]},{"coordinates":[{"x":-7487.00386033412,"y":0,"z":6700718.12513759},{"x":-7480.52506596995,"y":0,"z":6700698.56692619},{"x":-7469.39311689063,"y":0,"z":6700702.24636695},{"x":-7474.66966075423,"y":0,"z":6700718.17872179},{"x":-7477.92018988539,"y":0,"z":6700717.10703776},{"x":-7478.40999564488,"y":0,"z":6700718.58953405},{"x":-7480.63638546075,"y":0,"z":6700717.85721657},{"x":-7481.34883020182,"y":0,"z":6700720.00058498},{"x":-7487.00386033412,"y":0,"z":6700718.12513759}]},{"coordinates":[{"x":-7477.04076590812,"y":0,"z":6700725.82340535},{"x":-7471.90893738255,"y":0,"z":6700710.31970879},{"x":-7455.13309012001,"y":0,"z":6700715.89246268},{"x":-7457.25929239416,"y":0,"z":6700722.32256807},{"x":-7441.75248732666,"y":0,"z":6700727.4487946},{"x":-7443.51133528119,"y":0,"z":6700732.77150012},{"x":-7426.73548801864,"y":0,"z":6700738.30854647},{"x":-7428.85055834372,"y":0,"z":6700744.7029466},{"x":-7402.65708216006,"y":0,"z":6700753.38362073},{"x":-7408.3455081396,"y":0,"z":6700770.56638153},{"x":-7400.82031056197,"y":0,"z":6700773.06699423},{"x":-7407.93362602366,"y":0,"z":6700794.55443351},{"x":-7409.98190465426,"y":0,"z":6700793.87569392},{"x":-7411.18415515482,"y":0,"z":6700797.51945452},{"x":-7409.13587652423,"y":0,"z":6700798.19819442},{"x":-7411.12849540943,"y":0,"z":6700804.19968652},{"x":-7426.88020335668,"y":0,"z":6700798.98410385},{"x":-7424.28645922119,"y":0,"z":6700791.14287454},{"x":-7422.93949338259,"y":0,"z":6700791.58941359},{"x":-7416.99503257423,"y":0,"z":6700773.62070144},{"x":-7418.34199841283,"y":0,"z":6700773.17416337},{"x":-7416.31598368039,"y":0,"z":6700767.08338656},{"x":-7434.69483161036,"y":0,"z":6700760.99261429},{"x":-7432.55749738713,"y":0,"z":6700754.50889398},{"x":-7449.76749066377,"y":0,"z":6700748.81108341},{"x":-7447.83053152397,"y":0,"z":6700742.97038518},{"x":-7463.78261455464,"y":0,"z":6700737.70125733},{"x":-7461.55622473878,"y":0,"z":6700730.96749551},{"x":-7477.04076590812,"y":0,"z":6700725.82340535}]},{"coordinates":[{"x":-7300.03164359774,"y":0,"z":6699302.62472248},{"x":-7285.64916538725,"y":0,"z":6699301.92824872},{"x":-7285.68256123449,"y":0,"z":6699309.00013885},{"x":-7264.6209135764,"y":0,"z":6699307.91078164},{"x":-7264.73223306719,"y":0,"z":6699302.60686418},{"x":-7248.42392766598,"y":0,"z":6699302.48185606},{"x":-7247.31073275804,"y":0,"z":6699286.23081756},{"x":-7232.57203217701,"y":0,"z":6699285.5343452},{"x":-7232.87259480216,"y":0,"z":6699302.57114757},{"x":-7165.55769871946,"y":0,"z":6699303.42834612},{"x":-7165.39071948327,"y":0,"z":6699284.15925893},{"x":-7150.3514562771,"y":0,"z":6699284.24855024},{"x":-7151.18635245805,"y":0,"z":6699300.60673458},{"x":-7140.0655353278,"y":0,"z":6699300.35671842},{"x":-7139.78723660082,"y":0,"z":6699312.26821135},{"x":-7264.68770527088,"y":0,"z":6699315.08982692},{"x":-7264.565253831,"y":0,"z":6699320.66162761},{"x":-7282.61014328859,"y":0,"z":6699321.07236948},{"x":-7285.59350564185,"y":0,"z":6699333.07318451},{"x":-7299.84240046339,"y":0,"z":6699333.76966093},{"x":-7300.03164359774,"y":0,"z":6699302.62472248}]},{"coordinates":[{"x":-7235.57765842843,"y":0,"z":6699387.04135367},{"x":-7234.80955394196,"y":0,"z":6699339.77007557},{"x":-7222.85384063076,"y":0,"z":6699339.9665178},{"x":-7223.62194511724,"y":0,"z":6699387.23779703},{"x":-7235.57765842843,"y":0,"z":6699387.04135367}]},{"coordinates":[{"x":-7221.02820098175,"y":0,"z":6699247.01415908},{"x":-7220.93914538912,"y":0,"z":6699235.47778269},{"x":-7136.87066594204,"y":0,"z":6699236.08495999},{"x":-7136.95972153467,"y":0,"z":6699247.62133724},{"x":-7221.02820098175,"y":0,"z":6699247.01415908}]},{"coordinates":[{"x":-7066.92862987663,"y":0,"z":6699173.83166402},{"x":-7040.20082013716,"y":0,"z":6699143.0087794},{"x":-7008.09627899238,"y":0,"z":6699170.86723321},{"x":-7034.82408873184,"y":0,"z":6699201.67236502},{"x":-7066.92862987663,"y":0,"z":6699173.83166402}]},{"coordinates":[{"x":-7333.69465761363,"y":0,"z":6699466.86918116},{"x":-7317.1748451799,"y":0,"z":6699464.13680637},{"x":-7311.13019682983,"y":0,"z":6699500.8007091},{"x":-7327.65000926355,"y":0,"z":6699503.53309618},{"x":-7333.69465761363,"y":0,"z":6699466.86918116}]},{"coordinates":[{"x":-7280.52846881076,"y":0,"z":6699508.40853422},{"x":-7268.23879702718,"y":0,"z":6699507.60489038},{"x":-7269.6302906621,"y":0,"z":6699487.71026607},{"x":-7261.5484956305,"y":0,"z":6699487.2637984},{"x":-7260.15700199559,"y":0,"z":6699507.03341037},{"x":-7247.19941326725,"y":0,"z":6699506.12261419},{"x":-7246.60941996605,"y":0,"z":6699514.76625266},{"x":-7279.93847550955,"y":0,"z":6699517.05217511},{"x":-7280.52846881076,"y":0,"z":6699508.40853422}]},{"coordinates":[{"x":-7239.66308374055,"y":0,"z":6699478.38802614},{"x":-7237.82631214246,"y":0,"z":6699397.32784866},{"x":-7223.02081986695,"y":0,"z":6699397.7564529},{"x":-7224.85759146504,"y":0,"z":6699478.62018907},{"x":-7239.66308374055,"y":0,"z":6699478.38802614}]},{"coordinates":[{"x":-7227.42907170237,"y":0,"z":6699478.65590644},{"x":-7174.51891772832,"y":0,"z":6699478.8702107},{"x":-7174.35193849213,"y":0,"z":6699490.2283442},{"x":-7227.42907170237,"y":0,"z":6699489.38898474},{"x":-7227.42907170237,"y":0,"z":6699478.65590644}]},{"coordinates":[{"x":-7306.61062550362,"y":0,"z":6699524.35641599},{"x":-7297.02601734632,"y":0,"z":6699524.35641599},{"x":-7297.02601734632,"y":0,"z":6699541.85804665},{"x":-7306.61062550362,"y":0,"z":6699541.85804665},{"x":-7306.61062550362,"y":0,"z":6699524.35641599}]},{"coordinates":[{"x":-7282.34297651069,"y":0,"z":6699530.14266523},{"x":-7266.30183788738,"y":0,"z":6699529.10685488},{"x":-7265.77863628065,"y":0,"z":6699537.07188269},{"x":-7281.81977490396,"y":0,"z":6699538.10769406},{"x":-7282.34297651069,"y":0,"z":6699530.14266523}]},{"coordinates":[{"x":-7293.07417542316,"y":0,"z":6699546.03701299},{"x":-7285.17049157684,"y":0,"z":6699545.92985998},{"x":-7284.95898454433,"y":0,"z":6699561.96710947},{"x":-7292.86266839065,"y":0,"z":6699562.07426269},{"x":-7293.07417542316,"y":0,"z":6699546.03701299}]},{"coordinates":[{"x":-7284.94785259525,"y":0,"z":6699566.64613474},{"x":-7275.77512655388,"y":0,"z":6699566.53898146},{"x":-7275.56361952138,"y":0,"z":6699583.41564052},{"x":-7284.73634556274,"y":0,"z":6699583.52279402},{"x":-7284.94785259525,"y":0,"z":6699566.64613474}]},{"coordinates":[{"x":-7295.99074608194,"y":0,"z":6699618.31203889},{"x":-7295.3673569335,"y":0,"z":6699593.95240833},{"x":-7277.65642594829,"y":0,"z":6699594.39888184},{"x":-7278.27981509673,"y":0,"z":6699618.77637273},{"x":-7295.99074608194,"y":0,"z":6699618.31203889}]},{"coordinates":[{"x":-7244.70585667348,"y":0,"z":6699556.05582564},{"x":-7244.61680108085,"y":0,"z":6699532.66075647},{"x":-7224.20080646936,"y":0,"z":6699532.73219169},{"x":-7224.27873011292,"y":0,"z":6699556.12726107},{"x":-7244.70585667348,"y":0,"z":6699556.05582564}]},{"coordinates":[{"x":-7196.20395453485,"y":0,"z":6699562.39572236},{"x":-7196.05923919682,"y":0,"z":6699519.49882719},{"x":-7180.19621175878,"y":0,"z":6699519.55240352},{"x":-7180.34092709681,"y":0,"z":6699562.44929897},{"x":-7196.20395453485,"y":0,"z":6699562.39572236}]},{"coordinates":[{"x":-7221.15065242163,"y":0,"z":6699585.13009672},{"x":-7207.21345217431,"y":0,"z":6699578.16512063},{"x":-7196.04810724774,"y":0,"z":6699600.50664194},{"x":-7209.97417554598,"y":0,"z":6699607.47163712},{"x":-7221.15065242163,"y":0,"z":6699585.13009672}]},{"coordinates":[{"x":-7222.89836842708,"y":0,"z":6699397.79216993},{"x":-7141.18986218482,"y":0,"z":6699396.82781041},{"x":-7141.54608455536,"y":0,"z":6699411.63252733},{"x":-7222.60893775102,"y":0,"z":6699410.68602472},{"x":-7222.89836842708,"y":0,"z":6699397.79216993}]},{"coordinates":[{"x":-7153.20123524141,"y":0,"z":6699466.97633313},{"x":-7153.19010329233,"y":0,"z":6699438.79541317},{"x":-7140.29930625847,"y":0,"z":6699438.79541317},{"x":-7140.29930625847,"y":0,"z":6699466.97633313},{"x":-7153.20123524141,"y":0,"z":6699466.97633313}]},{"coordinates":[{"x":-7156.20686149283,"y":0,"z":6699553.21626786},{"x":-7156.03988225664,"y":0,"z":6699505.49755804},{"x":-7140.36609795295,"y":0,"z":6699505.55113428},{"x":-7140.53307718913,"y":0,"z":6699553.26984442},{"x":-7156.20686149283,"y":0,"z":6699553.21626786}]},{"coordinates":[{"x":-7164.36658016798,"y":0,"z":6699618.88352669},{"x":-7164.19960093179,"y":0,"z":6699569.55713274},{"x":-7148.36996934098,"y":0,"z":6699569.6107094},{"x":-7148.53694857717,"y":0,"z":6699618.93710368},{"x":-7164.36658016798,"y":0,"z":6699618.88352669}]},{"coordinates":[{"x":-6976.84889792671,"y":0,"z":6699198.45791105},{"x":-6963.96923284193,"y":0,"z":6699188.49311178},{"x":-6949.03015717747,"y":0,"z":6699207.79768916},{"x":-6961.90982226225,"y":0,"z":6699217.76251201},{"x":-6976.84889792671,"y":0,"z":6699198.45791105}]},{"coordinates":[{"x":-6958.39212635318,"y":0,"z":6699221.67344043},{"x":-6943.41965484149,"y":0,"z":6699213.4765652},{"x":-6930.13923958985,"y":0,"z":6699237.78148503},{"x":-6945.11171110154,"y":0,"z":6699245.97838469},{"x":-6958.39212635318,"y":0,"z":6699221.67344043}]},{"coordinates":[{"x":-7034.3120190742,"y":0,"z":6699230.03104719},{"x":-7016.08901843134,"y":0,"z":6699219.49474948},{"x":-6963.43489928612,"y":0,"z":6699309.01799716},{"x":-6982.05865009583,"y":0,"z":6699319.14366871},{"x":-7034.3120190742,"y":0,"z":6699230.03104719}]},{"coordinates":[{"x":-6938.84442376988,"y":0,"z":6699256.24684359},{"x":-6923.51572988765,"y":0,"z":6699247.72848633},{"x":-6906.71761872695,"y":0,"z":6699277.98030271},{"x":-6922.04631260918,"y":0,"z":6699286.49869156},{"x":-6938.84442376988,"y":0,"z":6699256.24684359}]},{"coordinates":[{"x":-6919.81992279331,"y":0,"z":6699296.17787795},{"x":-6904.72499984174,"y":0,"z":6699288.15951055},{"x":-6885.23295700384,"y":0,"z":6699324.85833899},{"x":-6900.31674800633,"y":0,"z":6699332.87674246},{"x":-6919.81992279331,"y":0,"z":6699296.17787795}]},{"coordinates":[{"x":-6971.42763872507,"y":0,"z":6699326.05484858},{"x":-6956.121208741,"y":0,"z":6699317.03638506},{"x":-6934.9593735412,"y":0,"z":6699352.98529007},{"x":-6950.25467157619,"y":0,"z":6699361.9859349},{"x":-6971.42763872507,"y":0,"z":6699326.05484858}]},{"coordinates":[{"x":-6919.3969087283,"y":0,"z":6699177.49255898},{"x":-6847.13942725438,"y":0,"z":6699129.7224734},{"x":-6806.22951438786,"y":0,"z":6699104.34640339},{"x":-6797.86942062928,"y":0,"z":6699119.27559476},{"x":-6908.34288329253,"y":0,"z":6699190.33249138},{"x":-6919.3969087283,"y":0,"z":6699177.49255898}]},{"coordinates":[{"x":-6847.5624413194,"y":0,"z":6699235.53135716},{"x":-6817.76221363404,"y":0,"z":6699229.8703239},{"x":-6812.36321833057,"y":0,"z":6699258.30053692},{"x":-6842.174577965,"y":0,"z":6699263.94373169},{"x":-6847.5624413194,"y":0,"z":6699235.53135716}]},{"coordinates":[{"x":-6832.35619887704,"y":0,"z":6699173.51021967},{"x":-6820.99047886705,"y":0,"z":6699164.5990728},{"x":-6759.28608512033,"y":0,"z":6699243.24608389},{"x":-6770.65180513033,"y":0,"z":6699252.17517486},{"x":-6832.35619887704,"y":0,"z":6699173.51021967}]},{"coordinates":[{"x":-6805.58386134126,"y":0,"z":6699282.92703897},{"x":-6754.74424989597,"y":0,"z":6699246.33554826},{"x":-6746.88509384596,"y":0,"z":6699257.26476109},{"x":-6797.72470529125,"y":0,"z":6699293.85630083},{"x":-6805.58386134126,"y":0,"z":6699282.92703897}]},{"coordinates":[{"x":-6939.38988927477,"y":0,"z":6699366.71842079},{"x":-6925.88683504155,"y":0,"z":6699357.48561124},{"x":-6875.62608494838,"y":0,"z":6699430.99120857},{"x":-6889.12913918161,"y":0,"z":6699440.22410131},{"x":-6939.38988927477,"y":0,"z":6699366.71842079}]},{"coordinates":[{"x":-6943.97625229545,"y":0,"z":6699576.50424259},{"x":-6931.39714983581,"y":0,"z":6699556.52015594},{"x":-6925.49721682377,"y":0,"z":6699560.23479926},{"x":-6938.07631928341,"y":0,"z":6699580.21889501},{"x":-6943.97625229545,"y":0,"z":6699576.50424259}]},{"coordinates":[{"x":-6892.61343924344,"y":0,"z":6699451.70719141},{"x":-6879.57792687155,"y":0,"z":6699441.47420365},{"x":-6859.7296616631,"y":0,"z":6699469.01222085},{"x":-6872.73177818776,"y":0,"z":6699478.95950414},{"x":-6892.61343924344,"y":0,"z":6699451.70719141}]},{"coordinates":[{"x":-6867.09901195362,"y":0,"z":6699506.97983412},{"x":-6824.57496647059,"y":0,"z":6699478.97736283},{"x":-6816.18147686478,"y":0,"z":6699491.72847623},{"x":-6858.69439039873,"y":0,"z":6699519.7309913},{"x":-6867.09901195362,"y":0,"z":6699506.97983412}]},{"coordinates":[{"x":-6821.36896513574,"y":0,"z":6699476.40571212},{"x":-6769.38276293528,"y":0,"z":6699453.15374045},{"x":-6763.47169797416,"y":0,"z":6699466.36913865},{"x":-6815.45790017462,"y":0,"z":6699489.62114799},{"x":-6821.36896513574,"y":0,"z":6699476.40571212}]},{"coordinates":[{"x":-6825.82174476747,"y":0,"z":6699541.822329},{"x":-6741.16327201919,"y":0,"z":6699536.42896536},{"x":-6740.07234100941,"y":0,"z":6699553.41271523},{"x":-6824.74194570678,"y":0,"z":6699558.82394895},{"x":-6825.82174476747,"y":0,"z":6699541.822329}]},{"coordinates":[{"x":-7310.15058531085,"y":0,"z":6699644.77910998},{"x":-7308.90380701396,"y":0,"z":6699621.02660633},{"x":-7291.47117475574,"y":0,"z":6699621.93741534},{"x":-7292.7290850017,"y":0,"z":6699645.68992165},{"x":-7310.15058531085,"y":0,"z":6699644.77910998}]},{"coordinates":[{"x":-7323.27515327537,"y":0,"z":6699672.28209536},{"x":-7322.86327115944,"y":0,"z":6699647.69013586},{"x":-7305.98723635518,"y":0,"z":6699647.97588079},{"x":-7306.41025042019,"y":0,"z":6699672.56784115},{"x":-7323.27515327537,"y":0,"z":6699672.28209536}]},{"coordinates":[{"x":-7328.97471120399,"y":0,"z":6699683.71193474},{"x":-7328.82999586596,"y":0,"z":6699674.63949842},{"x":-7303.37122832154,"y":0,"z":6699675.05025811},{"x":-7303.50481171049,"y":0,"z":6699684.10483575},{"x":-7328.97471120399,"y":0,"z":6699683.71193474}]},{"coordinates":[{"x":-7288.69931943498,"y":0,"z":6699701.03531559},{"x":-7288.48781240248,"y":0,"z":6699674.56806195},{"x":-7270.96612455162,"y":0,"z":6699674.71093488},{"x":-7271.17763158412,"y":0,"z":6699701.16032981},{"x":-7288.69931943498,"y":0,"z":6699701.03531559}]},{"coordinates":[{"x":-7360.55605074204,"y":0,"z":6699688.15886095},{"x":-7354.2219717159,"y":0,"z":6699680.58658644},{"x":-7305.72006957728,"y":0,"z":6699721.14477084},{"x":-7321.05989540859,"y":0,"z":6699739.48620887},{"x":-7337.82461072205,"y":0,"z":6699725.44884364},{"x":-7328.82999586596,"y":0,"z":6699714.69759551},{"x":-7360.55605074204,"y":0,"z":6699688.15886095}]},{"coordinates":[{"x":-7292.1390917005,"y":0,"z":6699703.51774122},{"x":-7275.26305689624,"y":0,"z":6699703.32129024},{"x":-7275.15173740544,"y":0,"z":6699711.85798251},{"x":-7292.0277722097,"y":0,"z":6699712.07229289},{"x":-7292.1390917005,"y":0,"z":6699703.51774122}]},{"coordinates":[{"x":-7261.82679435749,"y":0,"z":6699644.56480136},{"x":-7260.78039114403,"y":0,"z":6699619.99078443},{"x":-7243.32549498764,"y":0,"z":6699620.72300334},{"x":-7244.36076625202,"y":0,"z":6699645.31488153},{"x":-7261.82679435749,"y":0,"z":6699644.56480136}]},{"coordinates":[{"x":-7263.69696180282,"y":0,"z":6699672.47854559},{"x":-7262.86206562186,"y":0,"z":6699647.90444456},{"x":-7245.1288707385,"y":0,"z":6699648.51165255},{"x":-7245.96376691945,"y":0,"z":6699673.08575541},{"x":-7263.69696180282,"y":0,"z":6699672.47854559}]},{"coordinates":[{"x":-7212.37867654711,"y":0,"z":6699629.93825184},{"x":-7204.0408466867,"y":0,"z":6699626.33073084},{"x":-7197.04998266488,"y":0,"z":6699642.49315173},{"x":-7205.37668057622,"y":0,"z":6699646.10067988},{"x":-7212.37867654711,"y":0,"z":6699629.93825184}]},{"coordinates":[{"x":-7230.1007394814,"y":0,"z":6699637.22473477},{"x":-7223.04308376511,"y":0,"z":6699634.1708404},{"x":-7215.49562228933,"y":0,"z":6699651.6191295},{"x":-7222.54214605654,"y":0,"z":6699654.6730304},{"x":-7230.1007394814,"y":0,"z":6699637.22473477}]},{"coordinates":[{"x":-7201.25785941687,"y":0,"z":6699618.95496267},{"x":-7193.04248099632,"y":0,"z":6699614.32948434},{"x":-7178.04774558647,"y":0,"z":6699640.99299198},{"x":-7186.26312400701,"y":0,"z":6699645.61848543},{"x":-7201.25785941687,"y":0,"z":6699618.95496267}]},{"coordinates":[{"x":-7349.12353903757,"y":0,"z":6699762.36395132},{"x":-7334.52955379458,"y":0,"z":6699741.07568305},{"x":-7313.45677418741,"y":0,"z":6699755.54169822},{"x":-7328.05075943041,"y":0,"z":6699776.81214491},{"x":-7349.12353903757,"y":0,"z":6699762.36395132}]},{"coordinates":[{"x":-7252.79878365415,"y":0,"z":6699769.5433966},{"x":-7244.22718286307,"y":0,"z":6699757.48836149},{"x":-7229.65546151823,"y":0,"z":6699767.86462027},{"x":-7238.22706230931,"y":0,"z":6699779.90181138},{"x":-7252.79878365415,"y":0,"z":6699769.5433966}]},{"coordinates":[{"x":-6870.38293693202,"y":0,"z":6699642.90390981},{"x":-6858.20458463923,"y":0,"z":6699641.56448138},{"x":-6858.62759870425,"y":0,"z":6699637.72478776},{"x":-6836.31917274928,"y":0,"z":6699635.27810022},{"x":-6832.67902540034,"y":0,"z":6699670.17472047},{"x":-6866.97656051375,"y":0,"z":6699673.9429929},{"x":-6870.38293693202,"y":0,"z":6699642.90390981}]},{"coordinates":[{"x":-6836.61973537442,"y":0,"z":6699632.56352803},{"x":-6818.02938041194,"y":0,"z":6699630.52759949},{"x":-6817.71768583772,"y":0,"z":6699633.34932515},{"x":-6815.37997653106,"y":0,"z":6699633.09929879},{"x":-6815.62487941081,"y":0,"z":6699630.84906185},{"x":-6787.92859010144,"y":0,"z":6699627.79516987},{"x":-6788.08443738855,"y":0,"z":6699626.4200259},{"x":-6755.11160421559,"y":0,"z":6699622.81250645},{"x":-6742.78853658477,"y":0,"z":6699734.96781768},{"x":-6773.90233426149,"y":0,"z":6699738.37893491},{"x":-6777.06380780002,"y":0,"z":6699709.60772385},{"x":-6785.17899867885,"y":0,"z":6699710.50068355},{"x":-6787.78387476341,"y":0,"z":6699686.85514338},{"x":-6800.70806764451,"y":0,"z":6699688.28387498},{"x":-6800.26278968134,"y":0,"z":6699692.33790225},{"x":-6798.12545545811,"y":0,"z":6699711.78654571},{"x":-6805.85102811916,"y":0,"z":6699712.62592806},{"x":-6805.57272939218,"y":0,"z":6699715.21551245},{"x":-6827.45814128213,"y":0,"z":6699717.62650556},{"x":-6830.68640651514,"y":0,"z":6699688.26601583},{"x":-6832.67902540034,"y":0,"z":6699670.17472047},{"x":-6836.31917274928,"y":0,"z":6699635.27810022},{"x":-6836.61973537442,"y":0,"z":6699632.56352803}]},{"coordinates":[{"x":-6809.88079368588,"y":0,"z":6699728.12772827},{"x":-6793.95097455336,"y":0,"z":6699726.43110124},{"x":-6794.20700938218,"y":0,"z":6699724.03796475},{"x":-6785.44616545675,"y":0,"z":6699723.10928511},{"x":-6785.16786672977,"y":0,"z":6699725.71673206},{"x":-6779.72434362998,"y":0,"z":6699725.14523677},{"x":-6778.3662458423,"y":0,"z":6699737.98603128},{"x":-6808.48930005096,"y":0,"z":6699741.20069789},{"x":-6809.88079368588,"y":0,"z":6699728.12772827}]},{"coordinates":[{"x":-6861.76680834462,"y":0,"z":6699926.17117618},{"x":-6860.55342589497,"y":0,"z":6699918.13432979},{"x":-6853.92991619277,"y":0,"z":6699914.16948849},{"x":-6846.2154754808,"y":0,"z":6699914.84815488},{"x":-6841.65137635828,"y":0,"z":6699921.0990322},{"x":-6842.51966838646,"y":0,"z":6699928.70724935},{"x":-6848.8537474126,"y":0,"z":6699933.60080121},{"x":-6857.42534820368,"y":0,"z":6699932.4935009},{"x":-6861.76680834462,"y":0,"z":6699926.17117618}]},{"coordinates":[{"x":-6805.39461820691,"y":0,"z":6699918.24148769},{"x":-6797.09018419373,"y":0,"z":6699912.72285768},{"x":-6780.61489955632,"y":0,"z":6699937.54779227},{"x":-6788.90820162042,"y":0,"z":6699943.06643907},{"x":-6805.39461820691,"y":0,"z":6699918.24148769}]},{"coordinates":[{"x":-6806.74158404551,"y":0,"z":6699964.49811255},{"x":-6775.85042535037,"y":0,"z":6699944.76311117},{"x":-6767.44580379548,"y":0,"z":6699957.9257267},{"x":-6786.51483256837,"y":0,"z":6699970.10607641},{"x":-6798.33696249061,"y":0,"z":6699977.66075993},{"x":-6806.74158404551,"y":0,"z":6699964.49811255}]},{"coordinates":[{"x":-6762.28057942267,"y":0,"z":6699989.59110182},{"x":-6747.49735104533,"y":0,"z":6699980.35758718},{"x":-6734.80692909489,"y":0,"z":6700000.64632941},{"x":-6749.59015747224,"y":0,"z":6700009.89772687},{"x":-6762.28057942267,"y":0,"z":6699989.59110182}]},{"coordinates":[{"x":-6817.20561618007,"y":0,"z":6700035.66953225},{"x":-6799.53921299118,"y":0,"z":6700025.13219381},{"x":-6791.91382787184,"y":0,"z":6700037.90202096},{"x":-6809.58023106073,"y":0,"z":6700048.4393759},{"x":-6817.20561618007,"y":0,"z":6700035.66953225}]},{"coordinates":[{"x":-6760.67757875525,"y":0,"z":6700021.20302024},{"x":-6747.89810121218,"y":0,"z":6700012.52312536},{"x":-6740.33950778732,"y":0,"z":6700023.64982356},{"x":-6732.11299741769,"y":0,"z":6700018.05968276},{"x":-6716.14978243794,"y":0,"z":6700041.509724},{"x":-6737.15577035063,"y":0,"z":6700055.79767251},{"x":-6760.67757875525,"y":0,"z":6700021.20302024}]},{"coordinates":[{"x":-6785.15673478069,"y":0,"z":6700101.17993497},{"x":-6778.52209312941,"y":0,"z":6700096.00052192},{"x":-6782.44053920533,"y":0,"z":6700090.96399239},{"x":-6777.14173144357,"y":0,"z":6700086.82046688},{"x":-6763.32698263613,"y":0,"z":6700104.53762518},{"x":-6775.27156399825,"y":0,"z":6700113.84272072},{"x":-6785.15673478069,"y":0,"z":6700101.17993497}]},{"coordinates":[{"x":-6756.79252852656,"y":0,"z":6700072.96110375},{"x":-6744.72549572457,"y":0,"z":6700065.40633196},{"x":-6733.44883130722,"y":0,"z":6700083.40920393},{"x":-6745.51586410921,"y":0,"z":6700090.96399239},{"x":-6756.79252852656,"y":0,"z":6700072.96110375}]},{"coordinates":[{"x":-6748.08734434653,"y":0,"z":6699185.49295955},{"x":-6735.04070002556,"y":0,"z":6699178.72476302},{"x":-6730.73263573186,"y":0,"z":6699187.01089357},{"x":-6660.45664119407,"y":0,"z":6699150.54483893},{"x":-6665.13205980738,"y":0,"z":6699141.54442741},{"x":-6652.5195615005,"y":0,"z":6699134.99056257},{"x":-6623.74347313044,"y":0,"z":6699190.45749777},{"x":-6640.65290378194,"y":0,"z":6699199.22580827},{"x":-6654.1893538624,"y":0,"z":6699173.13520126},{"x":-6718.87710996238,"y":0,"z":6699206.70834546},{"x":-6713.96792041839,"y":0,"z":6699216.15528169},{"x":-6728.30587083257,"y":0,"z":6699223.60211815},{"x":-6748.08734434653,"y":0,"z":6699185.49295955}]},{"coordinates":[{"x":-6715.81582396556,"y":0,"z":6699255.80038858},{"x":-6685.47013077531,"y":0,"z":6699235.90637843},{"x":-6677.38833574372,"y":0,"z":6699248.54996275},{"x":-6707.84534842476,"y":0,"z":6699268.12255565},{"x":-6715.81582396556,"y":0,"z":6699255.80038858}]},{"coordinates":[{"x":-6677.38833574372,"y":0,"z":6699248.54996275},{"x":-6647.65489975284,"y":0,"z":6699230.42392635},{"x":-6639.9738548881,"y":0,"z":6699242.5496152},{"x":-6669.69615892991,"y":0,"z":6699261.33643236},{"x":-6677.38833574372,"y":0,"z":6699248.54996275}]},{"coordinates":[{"x":-6628.51907928547,"y":0,"z":6699161.93823124},{"x":-6617.29807461351,"y":0,"z":6699150.72341862},{"x":-6605.63179197838,"y":0,"z":6699162.38468111},{"x":-6616.85279665034,"y":0,"z":6699173.61736778},{"x":-6628.51907928547,"y":0,"z":6699161.93823124}]},{"coordinates":[{"x":-6627.23890514135,"y":0,"z":6699225.94153341},{"x":-6613.71358700997,"y":0,"z":6699218.31611364},{"x":-6592.07307799976,"y":0,"z":6699255.69323939},{"x":-6606.08820189063,"y":0,"z":6699263.81872417},{"x":-6627.23890514135,"y":0,"z":6699225.94153341}]},{"coordinates":[{"x":-6688.40896533226,"y":0,"z":6699278.44461718},{"x":-6673.97082737637,"y":0,"z":6699268.01540629},{"x":-6635.22051263123,"y":0,"z":6699325.73339823},{"x":-6650.46015092083,"y":0,"z":6699335.62693166},{"x":-6688.40896533226,"y":0,"z":6699278.44461718}]},{"coordinates":[{"x":-6720.14615215742,"y":0,"z":6699315.87559346},{"x":-6688.80971549911,"y":0,"z":6699313.08969427},{"x":-6686.09351992376,"y":0,"z":6699343.59177054},{"x":-6717.42995658206,"y":0,"z":6699346.37768015},{"x":-6720.14615215742,"y":0,"z":6699315.87559346}]},{"coordinates":[{"x":-6614.91583751054,"y":0,"z":6699300.08884396},{"x":-6585.99503380244,"y":0,"z":6699279.15894718},{"x":-6577.76852343282,"y":0,"z":6699291.80259854},{"x":-6606.90083417342,"y":0,"z":6699312.37536129},{"x":-6614.91583751054,"y":0,"z":6699300.08884396}]},{"coordinates":[{"x":-6630.41151062896,"y":0,"z":6699343.9132216},{"x":-6594.33286366286,"y":0,"z":6699318.78650196},{"x":-6584.71485965832,"y":0,"z":6699331.87667389},{"x":-6621.59500695813,"y":0,"z":6699357.00343386},{"x":-6630.41151062896,"y":0,"z":6699343.9132216}]},{"coordinates":[{"x":-6584.49222067674,"y":0,"z":6699276.55164298},{"x":-6556.69574382565,"y":0,"z":6699258.10409667},{"x":-6550.79581081361,"y":0,"z":6699267.21178615},{"x":-6578.33625283587,"y":0,"z":6699285.40933735},{"x":-6584.49222067674,"y":0,"z":6699276.55164298}]},{"coordinates":[{"x":-6571.62368754103,"y":0,"z":6699290.19535364},{"x":-6550.23921335964,"y":0,"z":6699276.83737491},{"x":-6545.16304457947,"y":0,"z":6699286.19510103},{"x":-6567.08185231667,"y":0,"z":6699299.01734624},{"x":-6571.62368754103,"y":0,"z":6699290.19535364}]},{"coordinates":[{"x":-6557.60856365016,"y":0,"z":6699324.51903033},{"x":-6548.82545582657,"y":0,"z":6699320.05444402},{"x":-6550.57317183202,"y":0,"z":6699316.6256434},{"x":-6529.37794078499,"y":0,"z":6699305.8392175},{"x":-6520.46124957244,"y":0,"z":6699323.376096},{"x":-6523.63385506005,"y":0,"z":6699324.98334744},{"x":-6517.5780747609,"y":0,"z":6699336.89487634},{"x":-6529.13303790524,"y":0,"z":6699342.77028455},{"x":-6530.26849671133,"y":0,"z":6699340.55584449},{"x":-6545.50813500093,"y":0,"z":6699348.30638735},{"x":-6557.60856365016,"y":0,"z":6699324.51903033}]},{"coordinates":[{"x":-6559.04458508139,"y":0,"z":6699373.30818873},{"x":-6547.10000371927,"y":0,"z":6699367.21845719},{"x":-6550.17242166517,"y":0,"z":6699361.21802235},{"x":-6525.80458513052,"y":0,"z":6699348.78856423},{"x":-6519.90465211848,"y":0,"z":6699360.36081774},{"x":-6518.2237278075,"y":0,"z":6699363.66462769},{"x":-6522.77669498094,"y":0,"z":6699365.98622468},{"x":-6517.74505399709,"y":0,"z":6699375.86194848},{"x":-6547.43396219165,"y":0,"z":6699390.98808025},{"x":-6552.00919326326,"y":0,"z":6699382.02312037},{"x":-6554.06860384293,"y":0,"z":6699383.05891204},{"x":-6556.59555628394,"y":0,"z":6699378.11211506},{"x":-6559.04458508139,"y":0,"z":6699373.30818873}]},{"coordinates":[{"x":-6723.96441069163,"y":0,"z":6699436.7059572},{"x":-6688.28651389238,"y":0,"z":6699432.29488525},{"x":-6684.55731095081,"y":0,"z":6699462.42237559},{"x":-6720.23520775005,"y":0,"z":6699466.83346384},{"x":-6723.96441069163,"y":0,"z":6699436.7059572}]},{"coordinates":[{"x":-6645.80699620567,"y":0,"z":6699413.25765471},{"x":-6635.18711678399,"y":0,"z":6699407.97152728},{"x":-6637.25765931275,"y":0,"z":6699403.8104902},{"x":-6626.87155082173,"y":0,"z":6699398.63151996},{"x":-6624.7342165985,"y":0,"z":6699402.91756406},{"x":-6615.45017106634,"y":0,"z":6699398.31006675},{"x":-6607.35724408567,"y":0,"z":6699414.5791871},{"x":-6637.6584094796,"y":0,"z":6699429.65181494},{"x":-6645.80699620567,"y":0,"z":6699413.25765471}]},{"coordinates":[{"x":-6645.32832239526,"y":0,"z":6699452.9572955},{"x":-6626.66004378923,"y":0,"z":6699443.70652973},{"x":-6611.67644032845,"y":0,"z":6699473.90549693},{"x":-6630.4449064762,"y":0,"z":6699483.20987305},{"x":-6635.63239474716,"y":0,"z":6699472.76254168},{"x":-6638.7382085403,"y":0,"z":6699474.29838784},{"x":-6643.17985622295,"y":0,"z":6699465.33333639},{"x":-6639.9738548881,"y":0,"z":6699463.74391595},{"x":-6645.32832239526,"y":0,"z":6699452.9572955}]},{"coordinates":[{"x":-6672.63499348685,"y":0,"z":6699516.6235646},{"x":-6638.52670150779,"y":0,"z":6699514.14119585},{"x":-6636.40049923364,"y":0,"z":6699543.17959988},{"x":-6670.51992316178,"y":0,"z":6699545.66197747},{"x":-6672.63499348685,"y":0,"z":6699516.6235646}]},{"coordinates":[{"x":-6740.06120906033,"y":0,"z":6699622.90180147},{"x":-6736.86633967457,"y":0,"z":6699615.20457463},{"x":-6707.40007046159,"y":0,"z":6699627.40227157},{"x":-6710.59493984735,"y":0,"z":6699635.09950991},{"x":-6740.06120906033,"y":0,"z":6699622.90180147}]},{"coordinates":[{"x":-6676.7538146462,"y":0,"z":6699621.72310733},{"x":-6673.7370564457,"y":0,"z":6699614.75809998},{"x":-6644.90530833025,"y":0,"z":6699627.24154045},{"x":-6647.92206653074,"y":0,"z":6699634.20655846},{"x":-6676.7538146462,"y":0,"z":6699621.72310733}]},{"coordinates":[{"x":-6596.47019788609,"y":0,"z":6699542.48310558},{"x":-6587.0414370159,"y":0,"z":6699537.4112002},{"x":-6593.00816172242,"y":0,"z":6699526.33874165},{"x":-6587.28633989565,"y":0,"z":6699523.26703001},{"x":-6580.35113561922,"y":0,"z":6699535.44673065},{"x":-6574.37327896363,"y":0,"z":6699531.85711024},{"x":-6568.10599163197,"y":0,"z":6699543.5010588},{"x":-6574.41780675994,"y":0,"z":6699547.16211968},{"x":-6574.78516107956,"y":0,"z":6699551.16250028},{"x":-6577.32324546965,"y":0,"z":6699552.96624396},{"x":-6580.21755223027,"y":0,"z":6699551.51967722},{"x":-6583.12299093998,"y":0,"z":6699552.60906696},{"x":-6583.03393534734,"y":0,"z":6699555.73436622},{"x":-6586.38465202022,"y":0,"z":6699557.32380459},{"x":-6589.64631310046,"y":0,"z":6699555.14502398},{"x":-6596.47019788609,"y":0,"z":6699542.48310558}]},{"coordinates":[{"x":-6633.28355349143,"y":0,"z":6699624.38409888},{"x":-6632.92733112089,"y":0,"z":6699611.20416263},{"x":-6591.11573037893,"y":0,"z":6699612.34713729},{"x":-6591.47195274947,"y":0,"z":6699625.52707539},{"x":-6633.28355349143,"y":0,"z":6699624.38409888}]},{"coordinates":[{"x":-6567.9278804467,"y":0,"z":6699427.45520985},{"x":-6555.23745849626,"y":0,"z":6699420.54394408},{"x":-6541.85685570291,"y":0,"z":6699414.06128924},{"x":-6534.8103319357,"y":0,"z":6699427.77666422},{"x":-6560.88135667948,"y":0,"z":6699441.17060735},{"x":-6567.9278804467,"y":0,"z":6699427.45520985}]},{"coordinates":[{"x":-6535.03297091728,"y":0,"z":6699400.11377662},{"x":-6491.51818196619,"y":0,"z":6699377.02274862},{"x":-6481.20999711874,"y":0,"z":6699396.47064025},{"x":-6513.73755232853,"y":0,"z":6699413.72197687},{"x":-6511.09928039673,"y":0,"z":6699418.68665401},{"x":-6522.08651413803,"y":0,"z":6699424.50854544},{"x":-6535.03297091728,"y":0,"z":6699400.11377662}]},{"coordinates":[{"x":-6524.26837615757,"y":0,"z":6699438.95614057},{"x":-6509.58533532194,"y":0,"z":6699431.83056202},{"x":-6502.62786714736,"y":0,"z":6699446.17101843},{"x":-6517.32203993207,"y":0,"z":6699453.29660951},{"x":-6524.26837615757,"y":0,"z":6699438.95614057}]},{"coordinates":[{"x":-6492.3753420453,"y":0,"z":6699430.27686527},{"x":-6473.81838293006,"y":0,"z":6699420.7582468},{"x":-6449.01640038132,"y":0,"z":6699469.08365552},{"x":-6467.57335949656,"y":0,"z":6699478.60233038},{"x":-6492.3753420453,"y":0,"z":6699430.27686527}]},{"coordinates":[{"x":-6573.8500773569,"y":0,"z":6699477.26292893},{"x":-6554.09086774109,"y":0,"z":6699466.58344258},{"x":-6547.28924685362,"y":0,"z":6699479.15594972},{"x":-6542.85873112005,"y":0,"z":6699478.1737219},{"x":-6536.83634666813,"y":0,"z":6699489.33540861},{"x":-6542.44684900412,"y":0,"z":6699492.37139004},{"x":-6531.76017788796,"y":0,"z":6699512.14101439},{"x":-6525.37043911643,"y":0,"z":6699508.69427426},{"x":-6518.72466551607,"y":0,"z":6699520.98110582},{"x":-6522.64311159199,"y":0,"z":6699523.08844216},{"x":-6516.609595191,"y":0,"z":6699534.23233153},{"x":-6537.05898564972,"y":0,"z":6699545.28694195},{"x":-6573.8500773569,"y":0,"z":6699477.26292893}]},{"coordinates":[{"x":-6531.64885839717,"y":0,"z":6699555.52005995},{"x":-6517.48901916826,"y":0,"z":6699548.07292045},{"x":-6512.57982962428,"y":0,"z":6699557.41309889},{"x":-6494.67965550472,"y":0,"z":6699549.4837689},{"x":-6481.08754567886,"y":0,"z":6699572.61100292},{"x":-6499.36620606712,"y":0,"z":6699582.21909317},{"x":-6503.37370773568,"y":0,"z":6699574.59334032},{"x":-6517.67826230261,"y":0,"z":6699582.11193969},{"x":-6531.64885839717,"y":0,"z":6699555.52005995}]},{"coordinates":[{"x":-6502.51654765657,"y":0,"z":6699534.71451939},{"x":-6458.17799447361,"y":0,"z":6699511.1587826},{"x":-6460.29306479868,"y":0,"z":6699507.17628037},{"x":-6447.58037895009,"y":0,"z":6699500.40781692},{"x":-6454.66029856454,"y":0,"z":6699487.08521134},{"x":-6439.72122290008,"y":0,"z":6699479.13809102},{"x":-6422.67820885963,"y":0,"z":6699511.21235888},{"x":-6494.67965550472,"y":0,"z":6699549.4837689},{"x":-6502.51654765657,"y":0,"z":6699534.71451939}]},{"coordinates":[{"x":-6506.74668830671,"y":0,"z":6699615.36530551},{"x":-6497.11755235309,"y":0,"z":6699609.75758555},{"x":-6494.98021812986,"y":0,"z":6699613.22222736},{"x":-6490.4383829055,"y":0,"z":6699610.8291241},{"x":-6488.83538223807,"y":0,"z":6699613.22222736},{"x":-6482.42337956838,"y":0,"z":6699610.29335481},{"x":-6477.88154434402,"y":0,"z":6699619.6336045},{"x":-6479.85189933106,"y":0,"z":6699620.2408104},{"x":-6498.45338624261,"y":0,"z":6699630.59903557},{"x":-6506.74668830671,"y":0,"z":6699615.36530551}]},{"coordinates":[{"x":-6731.77903894531,"y":0,"z":6699671.01409854},{"x":-6722.28348638065,"y":0,"z":6699648.56522974},{"x":-6711.58568331542,"y":0,"z":6699653.10143213},{"x":-6721.09236782916,"y":0,"z":6699675.5324543},{"x":-6731.77903894531,"y":0,"z":6699671.01409854}]},{"coordinates":[{"x":-6673.64800085307,"y":0,"z":6699671.83561758},{"x":-6670.66463849981,"y":0,"z":6699664.85270835},{"x":-6641.67704309724,"y":0,"z":6699677.22907075},{"x":-6644.6604054505,"y":0,"z":6699684.22984972},{"x":-6673.64800085307,"y":0,"z":6699671.83561758}]},{"coordinates":[{"x":-6734.01656071026,"y":0,"z":6699719.43028605},{"x":-6726.29098804921,"y":0,"z":6699719.3767084},{"x":-6726.30211999829,"y":0,"z":6699716.67996744},{"x":-6715.40394184962,"y":0,"z":6699716.6085306},{"x":-6715.29262235883,"y":0,"z":6699734.89638069},{"x":-6733.91637316855,"y":0,"z":6699735.02139543},{"x":-6734.01656071026,"y":0,"z":6699719.43028605}]},{"coordinates":[{"x":-6715.40394184962,"y":0,"z":6699716.6085306},{"x":-6702.74691574643,"y":0,"z":6699716.37636089},{"x":-6702.72465184827,"y":0,"z":6699720.53755744},{"x":-6698.81733772143,"y":0,"z":6699720.51969822},{"x":-6698.75054602695,"y":0,"z":6699734.96781768},{"x":-6715.29262235883,"y":0,"z":6699734.89638069},{"x":-6715.40394184962,"y":0,"z":6699716.6085306}]},{"coordinates":[{"x":-6678.4236070081,"y":0,"z":6699716.78712269},{"x":-6646.3301978124,"y":0,"z":6699716.67996744},{"x":-6646.274538067,"y":0,"z":6699732.21749384},{"x":-6678.3679472627,"y":0,"z":6699732.30679005},{"x":-6678.4236070081,"y":0,"z":6699716.78712269}]},{"coordinates":[{"x":-6634.53033178831,"y":0,"z":6699651.69056576},{"x":-6634.07392187606,"y":0,"z":6699634.88520156},{"x":-6630.84565664305,"y":0,"z":6699631.43840956},{"x":-6596.57038542781,"y":0,"z":6699632.36707877},{"x":-6597.12698288177,"y":0,"z":6699652.70853261},{"x":-6634.53033178831,"y":0,"z":6699651.69056576}]},{"coordinates":[{"x":-6589.93574377653,"y":0,"z":6699658.92349088},{"x":-6587.11936065946,"y":0,"z":6699657.22687824},{"x":-6589.02292395202,"y":0,"z":6699654.04796287},{"x":-6574.03932049125,"y":0,"z":6699645.10057291},{"x":-6562.13926692545,"y":0,"z":6699665.0312993},{"x":-6558.52138347466,"y":0,"z":6699671.5141536},{"x":-6571.2118054251,"y":0,"z":6699678.21132254},{"x":-6574.57365404705,"y":0,"z":6699672.44282736},{"x":-6580.50698290634,"y":0,"z":6699662.49530811},{"x":-6585.88371431165,"y":0,"z":6699665.70994496},{"x":-6589.93574377653,"y":0,"z":6699658.92349088}]},{"coordinates":[{"x":-6730.49886480119,"y":0,"z":6699788.92078668},{"x":-6729.00718362456,"y":0,"z":6699773.99036961},{"x":-6703.92690234884,"y":0,"z":6699776.68712953},{"x":-6705.11802090033,"y":0,"z":6699791.90330151},{"x":-6730.49886480119,"y":0,"z":6699788.92078668}]},{"coordinates":[{"x":-6726.9923008412,"y":0,"z":6699810.42349279},{"x":-6724.91062636337,"y":0,"z":6699793.42134839},{"x":-6689.43310464755,"y":0,"z":6699797.77903748},{"x":-6691.52591107447,"y":0,"z":6699814.78119097},{"x":-6726.9923008412,"y":0,"z":6699810.42349279}]},{"coordinates":[{"x":-6675.71854338182,"y":0,"z":6699766.38229678},{"x":-6619.27956154963,"y":0,"z":6699765.77508001},{"x":-6619.1348462116,"y":0,"z":6699780.25899833},{"x":-6675.56269609471,"y":0,"z":6699780.84835684},{"x":-6675.71854338182,"y":0,"z":6699766.38229678}]},{"coordinates":[{"x":-6575.04119590839,"y":0,"z":6699680.78303687},{"x":-6553.5454022362,"y":0,"z":6699670.12114315},{"x":-6544.45059983839,"y":0,"z":6699689.42686044},{"x":-6561.5715375224,"y":0,"z":6699698.24928484},{"x":-6566.22469223756,"y":0,"z":6699691.266353},{"x":-6569.11899899818,"y":0,"z":6699692.71294453},{"x":-6575.04119590839,"y":0,"z":6699680.78303687}]},{"coordinates":[{"x":-6561.5715375224,"y":0,"z":6699698.24928484},{"x":-6544.45059983839,"y":0,"z":6699689.42686044},{"x":-6538.12765276134,"y":0,"z":6699701.66038672},{"x":-6543.05910620348,"y":0,"z":6699704.33926354},{"x":-6539.3299032619,"y":0,"z":6699710.76857149},{"x":-6551.53051945285,"y":0,"z":6699717.73366082},{"x":-6561.5715375224,"y":0,"z":6699698.24928484}]},{"coordinates":[{"x":-6551.46372775837,"y":0,"z":6699726.73470815},{"x":-6533.06261593024,"y":0,"z":6699716.89427794},{"x":-6523.5559314165,"y":0,"z":6699734.69992896},{"x":-6541.95704324463,"y":0,"z":6699744.52252138},{"x":-6551.46372775837,"y":0,"z":6699726.73470815}]},{"coordinates":[{"x":-6498.45338624261,"y":0,"z":6699630.59903557},{"x":-6479.85189933106,"y":0,"z":6699620.2408104},{"x":-6475.98911300053,"y":0,"z":6699628.38451735},{"x":-6480.16359390528,"y":0,"z":6699630.36686831},{"x":-6478.37135010351,"y":0,"z":6699634.15298137},{"x":-6492.84288390663,"y":0,"z":6699641.01085102},{"x":-6498.45338624261,"y":0,"z":6699630.59903557}]},{"coordinates":[{"x":-6488.7129307982,"y":0,"z":6699650.47614933},{"x":-6469.13183236767,"y":0,"z":6699640.33220741},{"x":-6462.24115588756,"y":0,"z":6699654.10154009},{"x":-6481.8222543181,"y":0,"z":6699664.62054011},{"x":-6488.7129307982,"y":0,"z":6699650.47614933}]},{"coordinates":[{"x":-6476.72382163977,"y":0,"z":6699667.88875511},{"x":-6460.84966225265,"y":0,"z":6699658.3162821},{"x":-6453.38012442042,"y":0,"z":6699670.7283528},{"x":-6469.24315185846,"y":0,"z":6699680.28298124},{"x":-6476.72382163977,"y":0,"z":6699667.88875511}]},{"coordinates":[{"x":-6465.1799904445,"y":0,"z":6699691.90928254},{"x":-6447.14623293599,"y":0,"z":6699682.33678134},{"x":-6439.4985839185,"y":0,"z":6699696.74911484},{"x":-6457.53234142701,"y":0,"z":6699706.32163295},{"x":-6465.1799904445,"y":0,"z":6699691.90928254}]},{"coordinates":[{"x":-6455.95160465774,"y":0,"z":6699710.94716345},{"x":-6441.79176542884,"y":0,"z":6699703.73205138},{"x":-6431.26094159979,"y":0,"z":6699724.35943081},{"x":-6445.4207808287,"y":0,"z":6699731.59242036},{"x":-6455.95160465774,"y":0,"z":6699710.94716345}]},{"coordinates":[{"x":-6567.76090121051,"y":0,"z":6699770.91856471},{"x":-6514.53905266224,"y":0,"z":6699734.61063272},{"x":-6507.96007075636,"y":0,"z":6699744.2724916},{"x":-6561.17078735554,"y":0,"z":6699780.56260725},{"x":-6567.76090121051,"y":0,"z":6699770.91856471}]},{"coordinates":[{"x":-6539.29650741467,"y":0,"z":6699767.79318299},{"x":-6525.59307809801,"y":0,"z":6699759.00640196},{"x":-6520.31653423441,"y":0,"z":6699767.23954407},{"x":-6514.20509418986,"y":0,"z":6699763.32835405},{"x":-6496.7390660844,"y":0,"z":6699790.61742672},{"x":-6512.73567691139,"y":0,"z":6699800.85085251},{"x":-6531.15905263768,"y":0,"z":6699772.07942107},{"x":-6534.98844312097,"y":0,"z":6699774.52614966},{"x":-6539.29650741467,"y":0,"z":6699767.79318299}]},{"coordinates":[{"x":-6510.55381489184,"y":0,"z":6699801.36877492},{"x":-6491.44025832264,"y":0,"z":6699791.02819225},{"x":-6481.37697635493,"y":0,"z":6699809.6198192},{"x":-6478.17097502008,"y":0,"z":6699807.8874564},{"x":-6469.94446465046,"y":0,"z":6699823.08582714},{"x":-6489.29179215033,"y":0,"z":6699833.55146671},{"x":-6497.35132328376,"y":0,"z":6699818.63882737},{"x":-6500.33468563702,"y":0,"z":6699820.2461764},{"x":-6510.55381489184,"y":0,"z":6699801.36877492}]},{"coordinates":[{"x":-6482.21187253588,"y":0,"z":6699833.81935868},{"x":-6466.53808823218,"y":0,"z":6699824.26455038},{"x":-6438.91972256637,"y":0,"z":6699869.6455246},{"x":-6454.59350687006,"y":0,"z":6699879.18252649},{"x":-6482.21187253588,"y":0,"z":6699833.81935868}]},{"coordinates":[{"x":-6703.41483269119,"y":0,"z":6699868.34177801},{"x":-6690.99157751866,"y":0,"z":6699865.0734827},{"x":-6683.56656748275,"y":0,"z":6699893.27373509},{"x":-6695.9786907062,"y":0,"z":6699896.54204171},{"x":-6703.41483269119,"y":0,"z":6699868.34177801}]},{"coordinates":[{"x":-6715.01432363185,"y":0,"z":6699928.29647688},{"x":-6709.29250180507,"y":0,"z":6699924.77812224},{"x":-6703.12540201513,"y":0,"z":6699934.79740011},{"x":-6708.85835579098,"y":0,"z":6699938.31575908},{"x":-6715.01432363185,"y":0,"z":6699928.29647688}]},{"coordinates":[{"x":-6695.39982935407,"y":0,"z":6699898.04224846},{"x":-6686.48313814153,"y":0,"z":6699896.61348012},{"x":-6683.52203968643,"y":0,"z":6699912.24064747},{"x":-6692.21609191739,"y":0,"z":6699913.90159387},{"x":-6695.39982935407,"y":0,"z":6699898.04224846}]},{"coordinates":[{"x":-6721.27047901443,"y":0,"z":6699962.81929609},{"x":-6705.75254199785,"y":0,"z":6699953.12145887},{"x":-6692.61684208424,"y":0,"z":6699974.16024376},{"x":-6708.13477910082,"y":0,"z":6699983.85810601},{"x":-6721.27047901443,"y":0,"z":6699962.81929609}]},{"coordinates":[{"x":-6663.46226744548,"y":0,"z":6699933.17216882},{"x":-6649.31356016566,"y":0,"z":6699924.15303401},{"x":-6641.48779996289,"y":0,"z":6699936.42263173},{"x":-6644.78285689037,"y":0,"z":6699939.99457049},{"x":-6637.29105515998,"y":0,"z":6699951.74626005},{"x":-6651.25051930546,"y":0,"z":6699960.64040717},{"x":-6659.20986289718,"y":0,"z":6699948.17431614},{"x":-6655.42500021021,"y":0,"z":6699945.76325489},{"x":-6663.46226744548,"y":0,"z":6699933.17216882}]},{"coordinates":[{"x":-6632.19262248165,"y":0,"z":6699925.47464918},{"x":-6602.25881140734,"y":0,"z":6699909.82959684},{"x":-6595.66869755238,"y":0,"z":6699922.43850654},{"x":-6625.60250862669,"y":0,"z":6699938.08358305},{"x":-6632.19262248165,"y":0,"z":6699925.47464918}]},{"coordinates":[{"x":-6591.57214029119,"y":0,"z":6699893.89882096},{"x":-6576.72212021936,"y":0,"z":6699888.68382037},{"x":-6568.35089451171,"y":0,"z":6699912.50854203},{"x":-6583.20091458353,"y":0,"z":6699917.72355785},{"x":-6591.57214029119,"y":0,"z":6699893.89882096}]},{"coordinates":[{"x":-6640.77535522181,"y":0,"z":6699971.67773576},{"x":-6628.27417640573,"y":0,"z":6699964.49811255},{"x":-6620.09219383242,"y":0,"z":6699978.71448703},{"x":-6632.59337264851,"y":0,"z":6699985.91198254},{"x":-6640.77535522181,"y":0,"z":6699971.67773576}]},{"coordinates":[{"x":-6604.37388173241,"y":0,"z":6699978.58946855},{"x":-6569.96502712821,"y":0,"z":6699960.03317593},{"x":-6561.63832921688,"y":0,"z":6699975.48186704},{"x":-6596.04718382108,"y":0,"z":6699994.0381948},{"x":-6604.37388173241,"y":0,"z":6699978.58946855}]},{"coordinates":[{"x":-6713.01057279757,"y":0,"z":6700047.67139872},{"x":-6687.99708321632,"y":0,"z":6700032.54404909},{"x":-6678.93567666575,"y":0,"z":6700047.52851926},{"x":-6703.949166247,"y":0,"z":6700062.65589668},{"x":-6713.01057279757,"y":0,"z":6700047.67139872}]},{"coordinates":[{"x":-6701.29976236612,"y":0,"z":6699994.32395186},{"x":-6686.36068670166,"y":0,"z":6699984.55463799},{"x":-6655.06877783967,"y":0,"z":6700032.47260949},{"x":-6670.01898545321,"y":0,"z":6700042.22412083},{"x":-6701.29976236612,"y":0,"z":6699994.32395186}]},{"coordinates":[{"x":-6627.71757895176,"y":0,"z":6699993.84173682},{"x":-6613.86943429708,"y":0,"z":6699985.71552477},{"x":-6606.33310477038,"y":0,"z":6699998.57458934},{"x":-6620.17011747598,"y":0,"z":6700006.70081421},{"x":-6627.71757895176,"y":0,"z":6699993.84173682}]},{"coordinates":[{"x":-6600.27732447122,"y":0,"z":6700044.26015214},{"x":-6577.1340023353,"y":0,"z":6700031.8653729},{"x":-6569.63106865583,"y":0,"z":6700045.88540557},{"x":-6579.11548927142,"y":0,"z":6700050.95762715},{"x":-6571.90198626802,"y":0,"z":6700064.44189351},{"x":-6585.57201973743,"y":0,"z":6700071.76448458},{"x":-6600.27732447122,"y":0,"z":6700044.26015214}]},{"coordinates":[{"x":-6564.52150402842,"y":0,"z":6699964.73028932},{"x":-6551.57504724916,"y":0,"z":6699959.51524345},{"x":-6545.20757237579,"y":0,"z":6699975.33898883},{"x":-6558.16516110413,"y":0,"z":6699980.55404483},{"x":-6564.52150402842,"y":0,"z":6699964.73028932}]},{"coordinates":[{"x":-6555.69386840851,"y":0,"z":6699943.1735973},{"x":-6520.31653423441,"y":0,"z":6699931.43977977},{"x":-6510.87664141514,"y":0,"z":6699959.92601748},{"x":-6530.79169831806,"y":0,"z":6699966.53412446},{"x":-6529.54492002118,"y":0,"z":6699970.30253381},{"x":-6545.20757237579,"y":0,"z":6699975.33898883},{"x":-6555.69386840851,"y":0,"z":6699943.1735973}]},{"coordinates":[{"x":-6503.2512562958,"y":0,"z":6699946.69195988},{"x":-6495.68153092186,"y":0,"z":6699944.88812913},{"x":-6496.72793413532,"y":0,"z":6699940.53036144},{"x":-6489.94857714601,"y":0,"z":6699938.905129},{"x":-6488.14520139516,"y":0,"z":6699946.49550305},{"x":-6485.60711700507,"y":0,"z":6699957.12203857},{"x":-6499.94506741924,"y":0,"z":6699960.55110845},{"x":-6503.2512562958,"y":0,"z":6699946.69195988}]},{"coordinates":[{"x":-6488.14520139516,"y":0,"z":6699946.49550305},{"x":-6482.81299778616,"y":0,"z":6699945.20960389},{"x":-6483.40299108736,"y":0,"z":6699941.85197926},{"x":-6472.17085446632,"y":0,"z":6699938.70867235},{"x":-6469.41013109465,"y":0,"z":6699953.26433668},{"x":-6485.60711700507,"y":0,"z":6699957.12203857},{"x":-6488.14520139516,"y":0,"z":6699946.49550305}]},{"coordinates":[{"x":-6472.17085446632,"y":0,"z":6699938.70867235},{"x":-6469.61050617808,"y":0,"z":6699938.905129},{"x":-6470.03352024309,"y":0,"z":6699936.72624646},{"x":-6459.09081429811,"y":0,"z":6699934.63666293},{"x":-6456.0295283013,"y":0,"z":6699950.71039615},{"x":-6469.41013109465,"y":0,"z":6699953.26433668},{"x":-6472.17085446632,"y":0,"z":6699938.70867235}]},{"coordinates":[{"x":-6567.52713027984,"y":0,"z":6700032.66906839},{"x":-6545.81982957515,"y":0,"z":6700023.66768344},{"x":-6539.15179207663,"y":0,"z":6700039.72373219},{"x":-6560.85909278132,"y":0,"z":6700048.72513487},{"x":-6567.52713027984,"y":0,"z":6700032.66906839}]},{"coordinates":[{"x":-6521.70802786933,"y":0,"z":6700017.1488295},{"x":-6505.7336809405,"y":0,"z":6700011.88017055},{"x":-6501.35882495232,"y":0,"z":6700025.257213},{"x":-6517.31090798299,"y":0,"z":6700030.47230091},{"x":-6521.70802786933,"y":0,"z":6700017.1488295}]},{"coordinates":[{"x":-6536.4801242976,"y":0,"z":6700021.54235788},{"x":-6521.70802786933,"y":0,"z":6700017.1488295},{"x":-6516.34242841309,"y":0,"z":6700035.18731477},{"x":-6531.11452484136,"y":0,"z":6700039.58085287},{"x":-6536.4801242976,"y":0,"z":6700021.54235788}]},{"coordinates":[{"x":-6572.8259380416,"y":0,"z":6700080.3908625},{"x":-6556.74027162197,"y":0,"z":6700070.40712574},{"x":-6535.97918658903,"y":0,"z":6700103.87680306},{"x":-6552.06485300865,"y":0,"z":6700113.86058079},{"x":-6572.8259380416,"y":0,"z":6700080.3908625}]},{"coordinates":[{"x":-6505.7336809405,"y":0,"z":6700011.88017055},{"x":-6494.15645389799,"y":0,"z":6700007.7724049},{"x":-6487.46615250132,"y":0,"z":6700026.86460275},{"x":-6499.00998369658,"y":0,"z":6700030.91879832},{"x":-6501.35882495232,"y":0,"z":6700025.257213},{"x":-6505.7336809405,"y":0,"z":6700011.88017055}]},{"coordinates":[{"x":-6494.15645389799,"y":0,"z":6700007.7724049},{"x":-6480.25264949791,"y":0,"z":6700002.93238804},{"x":-6473.96309826809,"y":0,"z":6700022.3103326},{"x":-6487.46615250132,"y":0,"z":6700026.86460275},{"x":-6494.15645389799,"y":0,"z":6700007.7724049}]},{"coordinates":[{"x":-6544.50625958379,"y":0,"z":6700123.18354706},{"x":-6528.08663469178,"y":0,"z":6700114.52140372},{"x":-6489.57009087731,"y":0,"z":6700179.30017065},{"x":-6504.79859721783,"y":0,"z":6700188.26600688},{"x":-6544.50625958379,"y":0,"z":6700123.18354706}]}] -------------------------------------------------------------------------------- /scripts/se228np_1km.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "points": "[[-8193.47074475547,6699122.20429101],[-8183.90840049633,6699116.34689956],[-8169.73742931835,6699139.47290553],[-8179.31090552657,6699145.33031358],[-8193.47074475547,6699122.20429101]]" 4 | }, 5 | { 6 | "points": "[[-8179.14392629038,6699125.99016821],[-8166.93217815036,6699118.77557356],[-8151.51442867549,6699144.81243282],[-8163.72617681551,6699152.04490848],[-8179.14392629038,6699125.99016821]]" 7 | }, 8 | { 9 | "points": "[[-7112.82565593069,6698968.18129586],[-7099.22241415575,6698953.716677],[-7058.76891120148,6698991.75332228],[-7072.36102102733,6699006.21800858],[-7112.82565593069,6698968.18129586]]" 10 | }, 11 | { 12 | "points": "[[-7050.72051201712,6699085.64923695],[-7046.08962120012,6699080.27403275],[-7039.24347251634,6699086.16711395],[-7035.82596414898,6699082.20267704],[-7031.02809409579,6699086.34569224],[-7033.03184493007,6699088.66721029],[-7025.88513362114,6699094.82816526],[-7034.53465805578,6699104.86428158],[-7046.8020659412,6699094.27457202],[-7044.20832180572,6699091.27445444],[-7050.72051201712,6699085.64923695]]" 13 | }, 14 | { 15 | "points": "[[-6975.80249471325,6698854.94723062],[-6974.644772009,6698835.62563102],[-6971.51669431771,6698835.80420382],[-6971.28292338704,6698831.91131767],[-6964.01376063824,6698832.35774947],[-6964.33658716154,6698837.7327903],[-6961.64265548435,6698837.89350586],[-6962.23264878555,6698847.85787684],[-6957.7910011029,6698848.12573644],[-6958.26967491331,6698856.00081269],[-6975.80249471325,6698854.94723062]]" 16 | }, 17 | { 18 | "points": "[[-6975.2904250556,6698873.21529156],[-6974.51118862005,6698857.6436867],[-6959.53871710835,6698858.4472665],[-6959.7279602427,6698862.17944927],[-6952.44766554482,6698862.57231071],[-6953.03765884603,6698874.59030856],[-6975.2904250556,6698873.21529156]]" 19 | }, 20 | { 21 | "points": "[[-6976.00286979668,6698893.03698754],[-6974.93420268506,6698877.48320221],[-6957.70194551026,6698878.67964618],[-6958.77061262188,6698894.2334338],[-6976.00286979668,6698893.03698754]]" 22 | }, 23 | { 24 | "points": "[[-6979.64301714562,6698918.16239573],[-6977.17172445001,6698895.92988774],[-6965.52770571303,6698897.23347891],[-6965.83940028725,6698900.07280833],[-6959.63890465007,6698900.76924777],[-6961.78737082238,6698920.14457408],[-6979.64301714562,6698918.16239573]]" 25 | }, 26 | { 27 | "points": "[[-6985.01974855093,6698963.94905287],[-6969.66879077054,6698943.19859372],[-6953.70557579079,6698955.00241986],[-6969.05653357118,6698975.77076662],[-6985.01974855093,6698963.94905287]]" 28 | }, 29 | { 30 | "points": "[[-7006.27063934337,6699000.98571786],[-6995.06076662049,6698985.86030929],[-6962.49981556345,6699010.28955453],[-6973.72082023541,6699025.0757122],[-6980.41112163209,6699019.98627085],[-6987.79160387169,6699020.486286],[-6990.00686173847,6699017.2897611],[-6990.25176461822,6699012.86105829],[-7006.27063934337,6699000.98571786]]" 31 | }, 32 | { 33 | "points": "[[-6933.9352342259,6698938.80564615],[-6923.09271582264,6698921.68031619],[-6905.24820144847,6698934.84128086],[-6881.2699831316,6698952.16307132],[-6878.03058594952,6698950.14517013],[-6860.62021758945,6698961.48470987],[-6853.28426314617,6698965.82409696],[-6827.39134958766,6698986.48532561],[-6844.00021761401,6699007.3073255],[-6849.4437407138,6699002.96791633],[-6858.03760540305,6698996.61059679],[-6863.35867706296,6699003.80722574],[-6884.96579022594,6698987.87821932],[-6878.91000992679,6698979.64586383],[-6893.02532135937,6698969.59204401],[-6887.75990944485,6698962.69902372],[-6899.50411572354,6698953.37738378],[-6914.48771918432,6698943.25216627],[-6917.32636619954,6698948.93085814],[-6933.9352342259,6698938.80564615]]" 34 | }, 35 | { 36 | "points": "[[-6925.18552224955,6699015.93257773],[-6896.82131599542,6698989.96756031],[-6883.09562278061,6699004.28938226],[-6911.7492597108,6699029.96872197],[-6925.18552224955,6699015.93257773]]" 37 | }, 38 | { 39 | "points": "[[-7041.30288309601,6699053.02305201],[-7032.37505993439,6699041.11193765],[-7019.75142967843,6699050.5586821],[-7016.66787978346,6699046.45140056],[-6997.32055228359,6699060.9518994],[-7007.0053479826,6699074.16666218],[-7026.11890455181,6699059.84471755],[-7028.28963462228,6699062.75553468],[-7041.30288309601,6699053.02305201]]" 40 | }, 41 | { 42 | "points": "[[-6997.32055228359,6699060.9518994],[-6974.27741768938,6699055.95172447],[-6971.01575660914,6699070.98797404],[-6994.05889120335,6699075.98815819],[-6997.32055228359,6699060.9518994]]" 43 | }, 44 | { 45 | "points": "[[-6971.48329847047,6699057.43391887],[-6957.91345254277,6699037.98683556],[-6954.90782629135,6699040.0761894],[-6940.46968833547,6699019.36125196],[-6924.53986920295,6699030.46873773],[-6940.15799376124,6699052.88018997],[-6947.5050801536,6699047.75501578],[-6959.88380752981,6699065.52349059],[-6971.48329847047,6699057.43391887]]" 46 | }, 47 | { 48 | "points": "[[-6930.85168433093,6699065.7199262],[-6901.93088062283,6699047.3978609],[-6893.33701593359,6699060.96975718],[-6922.25781964169,6699079.29185296],[-6930.85168433093,6699065.7199262]]" 49 | }, 50 | { 51 | "points": "[[-6975.00099437954,6699097.45326923],[-6959.43852956664,6699087.57788251],[-6953.40501316564,6699097.07825432],[-6944.77775262916,6699091.6137534],[-6932.78864347073,6699110.48951232],[-6937.20802725522,6699113.2932002],[-6933.07807414679,6699119.82918971],[-6923.94987590174,6699114.02537363],[-6916.84769238913,6699125.20441997],[-6910.85870378445,6699121.40068523],[-6901.15164418728,6699136.68706658],[-6923.13724361895,6699150.65198674],[-6929.70509357576,6699140.33008693],[-6934.23579685104,6699143.20521688],[-6943.58663407768,6699128.50813468],[-6949.75373386762,6699132.41902031],[-6967.39787315836,6699104.68570289],[-6969.99161729384,6699105.34644406],[-6975.00099437954,6699097.45326923]]" 52 | }, 53 | { 54 | "points": "[[-6862.4235933403,6698945.87722146],[-6852.91690882656,6698933.91269106],[-6843.93342591954,6698941.05569217],[-6839.55856993136,6698935.53772327],[-6832.82374073837,6698940.89497458],[-6836.66426317074,6698945.71650377],[-6832.2671432844,6698949.21657859],[-6828.63812788454,6698944.64505259],[-6821.79197920076,6698950.09159753],[-6825.66589748036,6698954.96670478],[-6820.41161751492,6698959.14537045],[-6816.84939380954,6698954.68098413],[-6810.8381413067,6698959.46680636],[-6814.05527459062,6698963.50261387],[-6804.55972202596,6698971.05636513],[-6814.70092763722,6698983.80668455],[-6862.4235933403,6698945.87722146]]" 55 | }, 56 | { 57 | "points": "[[-6804.17010380818,6699010.98600339],[-6799.2609142642,6699008.28949662],[-6803.71369389593,6699000.19998166],[-6792.49268922397,6698994.03909816],[-6777.62040525399,6699021.11130498],[-6785.78012392913,6699025.59358536],[-6788.86367382411,6699019.96841317],[-6796.82301741583,6699024.34354676],[-6804.17010380818,6699010.98600339]]" 58 | }, 59 | { 60 | "points": "[[-6781.21602480661,6699107.73939903],[-6772.49970867749,6699094.1138514],[-6733.94976901578,6699118.77557356],[-6742.58816150134,6699132.2940148],[-6757.78327199462,6699122.57930707],[-6767.21203286482,6699137.32995241],[-6780.02490625512,6699129.13316193],[-6770.66293707941,6699114.48967876],[-6781.21602480661,6699107.73939903]]" 61 | }, 62 | { 63 | "points": "[[-6742.2875988762,6699055.46956491],[-6734.65108180778,6699043.57630471],[-6697.05848976689,6699067.73785599],[-6705.46311132178,6699080.82762504],[-6715.93827540543,6699074.09523097],[-6725.61193915537,6699089.14937182],[-6740.70686210694,6699079.45257328],[-6730.25396192145,6699063.20197912],[-6742.2875988762,6699055.46956491]]" 64 | }, 65 | { 66 | "points": "[[-8365.52614972556,6699609.70400863],[-8355.2736246235,6699596.89913396],[-8326.28602922093,6699620.08007942],[-8336.53855432299,6699632.90284951],[-8365.52614972556,6699609.70400863]]" 67 | }, 68 | { 69 | "points": "[[-8302.77535276539,6699660.12004948],[-8289.63965285178,6699646.42214286],[-8259.75036957379,6699675.08597635],[-8272.88606948739,6699688.7839311],[-8302.77535276539,6699660.12004948]]" 70 | }, 71 | { 72 | "points": "[[-8364.74691329,6699942.54850766],[-8350.24198363964,6699925.56394751],[-8323.08002788608,6699952.83570325],[-8313.66239896497,6699969.07021018],[-8309.66602924549,6699973.21367587],[-8315.48803861398,6699980.07183061],[-8314.70880217843,6699982.16142578],[-8327.93355768467,6699993.82387701],[-8339.32154159282,6699981.37559505],[-8341.41434801973,6699982.6793597],[-8361.8414745803,6699963.56940553],[-8352.41271371011,6699954.40735927],[-8364.74691329,6699942.54850766]]" 73 | }, 74 | { 75 | "points": "[[-8369.23308876897,6700120.45095239],[-8362.59844711769,6700099.14388945],[-8343.15093207611,6700105.19844736],[-8349.77444177831,6700126.50552611],[-8369.23308876897,6700120.45095239]]" 76 | }, 77 | { 78 | "points": "[[-7382.02958051606,6699355.82477814],[-7365.23146935536,6699353.43175039],[-7360.02171718623,6699390.09515552],[-7376.81982834694,6699392.48819402],[-7382.02958051606,6699355.82477814]]" 79 | }, 80 | { 81 | "points": "[[-7362.04773191867,6699412.15042503],[-7344.32566898438,6699409.15019053],[-7338.0695136018,6699446.24245289],[-7355.80270848517,6699449.22484241],[-7362.04773191867,6699412.15042503]]" 82 | }, 83 | { 84 | "points": "[[-7813.74882971054,6699735.45001742],[-7808.04927178192,6699723.07356667],[-7774.70908428934,6699738.43251268],[-7780.41977416703,6699750.82684602],[-7813.74882971054,6699735.45001742]]" 85 | }, 86 | { 87 | "points": "[[-7758.56775812431,6699827.03276471],[-7747.90335090632,6699796.0466772],[-7738.00704817479,6699799.72571082],[-7742.30398051941,6699812.19157497],[-7714.07335765424,6699821.63921249],[-7720.44083252761,6699840.1594713],[-7758.56775812431,6699827.03276471]]" 88 | }, 89 | { 90 | "points": "[[-7737.21667979016,6699954.6038163],[-7723.89173674221,6699947.62066497],[-7720.64120761104,6699953.83584796],[-7718.9936791473,6699952.97858106],[-7717.78029669766,6699955.28248605],[-7719.4278251614,6699956.1397532],[-7716.97879636395,6699960.80114486],[-7727.06434222982,6699966.10549033],[-7729.21280840213,6699962.01560749],[-7732.44107363513,6699963.69442378],[-7737.21667979016,6699954.6038163]]" 91 | }, 92 | { 93 | "points": "[[-7647.89392037764,6699810.42349279],[-7629.7711072765,6699805.85148409],[-7626.754349076,6699817.74585582],[-7644.87716217714,6699822.33573063],[-7647.89392037764,6699810.42349279]]" 94 | }, 95 | { 96 | "points": "[[-7459.36323077015,6699747.21927155],[-7442.56511960945,6699721.8412804],[-7420.90234670108,6699735.68218767],[-7437.96762463968,6699761.52456385],[-7459.36323077015,6699747.21927155]]" 97 | }, 98 | { 99 | "points": "[[-7412.23055836828,6699744.54038065],[-7383.30975466019,6699702.80337405],[-7360.15530057519,6699718.85879119],[-7389.0649723342,6699760.59587994],[-7412.23055836828,6699744.54038065]]" 100 | }, 101 | { 102 | "points": "[[-7468.85878333482,6699797.31469346],[-7463.55997557306,6699788.49216189],[-7457.81588984813,6699792.47480147],[-7455.52270833778,6699788.67075555],[-7456.75835468559,6699787.79564665],[-7454.46517317525,6699783.81300934],[-7459.85303652964,6699780.36615442],[-7454.03102716115,6699771.36504791],[-7449.43353219139,6699774.27611896],[-7445.37037077744,6699768.6325711],[-7451.54860251646,6699764.66780247],[-7448.55410821413,6699759.89936708],[-7428.6947110566,6699773.04382495],[-7433.63729644783,6699780.90193488],[-7431.86731654421,6699782.13423008],[-7442.19776528983,6699798.2969597],[-7440.33872979358,6699799.52925753],[-7449.87881015456,6699814.35256481],[-7465.76410149077,6699804.29771609],[-7463.55997557306,6699800.94014947],[-7468.85878333482,6699797.31469346]]" 103 | }, 104 | { 105 | "points": "[[-7479.84601707611,6699842.23117113],[-7475.78285566216,6699836.05179214],[-7477.01850200996,6699835.35527283],[-7472.52119458192,6699827.49711044],[-7476.22813362533,6699825.371836],[-7467.8457759686,6699811.42362003],[-7455.31120130528,6699819.01387545],[-7457.51532722298,6699822.55004391],[-7452.39463064649,6699825.72902494],[-7457.33721603771,6699834.55159679],[-7445.15886374493,6699841.96327888],[-7452.21651946122,6699854.41134807],[-7466.16485165762,6699846.1245395],[-7468.36897757533,6699849.30352973],[-7479.84601707611,6699842.23117113]]" 106 | }, 107 | { 108 | "points": "[[-7442.56511960945,6699870.9135523],[-7416.82805333804,6699838.51639938],[-7386.60481158767,6699862.51956979],[-7412.34187785907,6699894.91681804],[-7442.56511960945,6699870.9135523]]" 109 | }, 110 | { 111 | "points": "[[-7356.55968102256,6699778.65165717],[-7348.0326080278,6699766.22156292],[-7327.66114121263,6699780.20542029],[-7336.1882142074,6699792.63553585],[-7356.55968102256,6699778.65165717]]" 112 | }, 113 | { 114 | "points": "[[-7424.74286913344,6699830.78325016],[-7397.13563541671,6699789.1886772],[-7383.33201855834,6699798.35053786],[-7410.928120326,6699839.96301703],[-7424.74286913344,6699830.78325016]]" 115 | }, 116 | { 117 | "points": "[[-7380.84959391366,6699829.47950978],[-7367.01258120805,6699808.63755158],[-7348.76731666703,6699820.72838118],[-7362.60432937264,6699841.58822975],[-7380.84959391366,6699829.47950978]]" 118 | }, 119 | { 120 | "points": "[[-7514.02110074965,6700007.59380644],[-7507.76494536707,6699972.03493111],[-7494.64037740254,6699974.33884149],[-7500.6404979563,6700010.16562463],[-7514.02110074965,6700007.59380644]]" 121 | }, 122 | { 123 | "points": "[[-7494.48453011543,6699910.72257847],[-7466.32069894473,6699907.22209104],[-7464.94033725889,6699918.29506664],[-7493.10416842959,6699921.79555883],[-7494.48453011543,6699910.72257847]]" 124 | }, 125 | { 126 | "points": "[[-7451.88256098884,6699905.41826901],[-7434.55011627233,6699882.62942318],[-7417.67408146807,6699895.45260603],[-7435.00652618458,6699918.25934734],[-7451.88256098884,6699905.41826901]]" 127 | }, 128 | { 129 | "points": "[[-7496.56620459326,6699936.56550925],[-7459.41889051555,6699928.18931885],[-7462.14621803998,6699916.04475102],[-7453.73046453601,6699914.15162885],[-7451.00313701158,6699926.29619385],[-7442.76549469287,6699924.43878862],[-7440.52797292793,6699934.35090797],[-7434.30521339258,6699934.56522419],[-7430.65393409457,6699938.38719785],[-7432.07882357672,6699944.20946024],[-7437.41102718572,6699948.19217586],[-7435.1067137263,6699958.44365909],[-7443.344356045,6699960.30107206],[-7439.89345183041,6699973.21367587],[-7447.15148263013,6699974.92821402],[-7450.25729642326,6699961.87272952],[-7488.90742362669,6699970.57043028],[-7496.56620459326,6699936.56550925]]" 130 | }, 131 | { 132 | "points": "[[-8279.17562071721,6700146.687471],[-8250.2102892128,6700105.84140952],[-8222.5362638016,6700125.45177992],[-8251.50159530601,6700166.2979396],[-8279.17562071721,6700146.687471]]" 133 | }, 134 | { 135 | "points": "[[-8221.91287465316,6700182.1399464],[-8205.61570120102,6700153.38503011],[-8189.70814596666,6700162.40441841],[-8206.0053194188,6700191.1593665],[-8221.91287465316,6700182.1399464]]" 136 | }, 137 | { 138 | "points": "[[-8183.71915736198,6700348.13459401],[-8176.12716808988,6700345.11615462],[-8174.36832013535,6700349.54558086],[-8181.96030940745,6700352.56402189],[-8183.71915736198,6700348.13459401]]" 139 | }, 140 | { 141 | "points": "[[-7996.41298215322,6700187.10509128],[-7984.94707460151,6700184.24745357],[-7974.43851467063,6700230.11265972],[-7986.85063789408,6700232.9703135],[-7996.41298215322,6700187.10509128]]" 142 | }, 143 | { 144 | "points": "[[-7982.07503173905,6700167.99465814],[-7869.33065146362,6700142.2045745],[-7865.51239292941,6700156.52841975],[-7978.25677320484,6700182.33640891],[-7982.07503173905,6700167.99465814]]" 145 | }, 146 | { 147 | "points": "[[-7972.52381942898,6700370.54966706],[-7901.82481082618,6700322.79045414],[-7858.82209153273,6700285.51560082],[-7831.11467027429,6700258.76068415],[-7820.6061103434,6700270.22706626],[-7848.31353160185,6700296.98202055],[-7892.26246656703,6700338.07908723],[-7964.87617041148,6700385.83838968],[-7972.52381942898,6700370.54966706]]" 148 | }, 149 | { 150 | "points": "[[-7827.29641174008,6700133.59599133],[-7761.36187734322,6700112.57465525],[-7757.54361880901,6700128.82734024],[-7824.42436887761,6700150.7953066],[-7827.29641174008,6700133.59599133]]" 151 | }, 152 | { 153 | "points": "[[-7819.64876272258,6700239.66794347],[-7778.56073867078,6700186.15849868],[-7764.23392020569,6700197.62477872],[-7805.32194425749,6700249.20537804],[-7819.64876272258,6700239.66794347]]" 154 | }, 155 | { 156 | "points": "[[-7735.92537369696,6700164.88698446],[-7724.47059809433,6700149.68797679],[-7718.35915804978,6700154.29589857],[-7714.49637171925,6700149.18789242],[-7709.36454319368,6700153.04568698],[-7713.79505892726,6700158.92168313],[-7709.32001539737,6700162.2972573],[-7706.15854185884,6700158.10011502],[-7700.22521299956,6700162.56516007],[-7696.81883658128,6700158.0465345],[-7692.66661957469,6700161.17206575],[-7695.76130141875,6700165.26204846],[-7688.77043739693,6700170.54866671],[-7699.64635164743,6700184.94400267],[-7716.7895532296,6700172.03106365],[-7720.29611718958,6700176.67471848],[-7735.92537369696,6700164.88698446]]" 157 | }, 158 | { 159 | "points": "[[-7708.03984125324,6700215.82440585],[-7691.19720229622,6700191.98093793],[-7686.39933224303,6700195.35652578],[-7677.46037713233,6700182.71147372],[-7681.55693439353,6700179.8181171],[-7665.98333763155,6700157.7607717],[-7649.89767121192,6700169.13771083],[-7646.70280182615,6700164.61908161],[-7633.97898402848,6700173.62062212],[-7647.17034368748,6700192.28456218],[-7649.94219900824,6700190.3199349],[-7665.88315008983,6700212.8774566],[-7662.97771138013,6700214.94925111],[-7680.25449635124,6700239.41789852],[-7694.71489820529,6700229.20178279],[-7692.84473075996,6700226.55845424],[-7708.03984125324,6700215.82440585]]" 160 | }, 161 | { 162 | "points": "[[-7762.31922496405,6700302.71523646],[-7709.77642530962,6700237.75688582],[-7697.35317013709,6700245.40111909],[-7752.76801265398,6700312.27060526],[-7762.31922496405,6700302.71523646]]" 163 | }, 164 | { 165 | "points": "[[-7941.94435530807,6700433.61583257],[-7880.79655901533,6700395.39385587],[-7823.46702125679,6700352.40327648],[-7776.65717537822,6700308.4484564],[-7766.14861544733,6700318.00383192],[-7812.00111370508,6700365.78087744],[-7872.20269432609,6700408.77152734],[-7931.43579537719,6700446.04694397],[-7941.94435530807,6700433.61583257]]" 166 | }, 167 | { 168 | "points": "[[-7661.59734969429,6700640.98210854],[-7656.4766531178,6700625.55001805],[-7654.77346490866,6700626.12157644],[-7649.57484468862,6700627.83625184],[-7650.32068527693,6700630.10462505],[-7646.43563504825,6700631.40849341],[-7645.67866251085,6700629.12225862],[-7639.53382661906,6700631.15843645],[-7641.47078575887,6700637.03477706],[-7624.96210527422,6700642.50031347],[-7630.43902422125,6700659.05769611],[-7647.11468394209,6700653.53856482],[-7644.79923853359,6700646.53695382],[-7651.93481789344,6700644.17926983],[-7651.43388018487,6700642.69678706],[-7654.27252720009,6700641.75014158],[-7654.76233295958,6700643.25048541],[-7661.59734969429,6700640.98210854]]" 169 | }, 170 | { 171 | "points": "[[-7633.40012267635,6700668.72065016],[-7628.56885677593,6700654.11012517],[-7614.63165652861,6700658.71833194],[-7619.46292242904,6700673.32886518],[-7633.40012267635,6700668.72065016]]" 172 | }, 173 | { 174 | "points": "[[-7621.50006911056,6700680.54483502],[-7616.12333770524,6700664.30891186],[-7565.16127482008,6700681.18784255],[-7570.5380062254,6700697.42379931],[-7580.36751726244,6700694.15517175],[-7579.84431565571,6700692.58337317],[-7583.10597673595,6700691.49383116],[-7583.62917834268,6700693.08349087],[-7596.80940605261,6700688.70746207],[-7596.23054470048,6700686.9570512],[-7599.2361709519,6700685.97467793],[-7599.81503230403,6700687.72508857],[-7612.63903764341,6700683.47409193],[-7612.03791239313,6700681.6522369],[-7615.60013609851,6700680.47338974],[-7616.2012613488,6700682.29524451],[-7621.50006911056,6700680.54483502]]" 175 | }, 176 | { 177 | "points": "[[-7566.93125472369,6700688.88607544],[-7559.75114756752,6700667.20244035],[-7501.25275515566,6700686.58196321],[-7502.78896412861,6700691.20804967],[-7510.08039077557,6700713.23111499],[-7520.48876316474,6700709.80172865],[-7518.83010275192,6700704.80054282],[-7525.39795270872,6700702.62145566],[-7524.85248720384,6700700.96034863],[-7528.01396074236,6700699.90652822],[-7528.55942624725,6700701.5854964],[-7541.45022328111,6700697.31663117],[-7540.79343828543,6700695.31615953],[-7543.88812012948,6700694.29806255],[-7544.54490512516,6700696.28067258],[-7566.93125472369,6700688.88607544]]" 178 | }, 179 | { 180 | "points": "[[-7509.2566265437,6700710.74838202],[-7502.78896412861,6700691.20804967],[-7491.65701504928,6700694.8874871],[-7498.12467746437,6700714.44568967],[-7509.2566265437,6700710.74838202]]" 181 | }, 182 | { 183 | "points": "[[-7498.12467746437,6700714.44568967],[-7491.65701504928,6700694.8874871],[-7480.52506596995,6700698.56692619],[-7487.00386033412,6700718.12513759],[-7498.12467746437,6700714.44568967]]" 184 | }, 185 | { 186 | "points": "[[-7487.00386033412,6700718.12513759],[-7480.52506596995,6700698.56692619],[-7469.39311689063,6700702.24636695],[-7474.66966075423,6700718.17872179],[-7477.92018988539,6700717.10703776],[-7478.40999564488,6700718.58953405],[-7480.63638546075,6700717.85721657],[-7481.34883020182,6700720.00058498],[-7487.00386033412,6700718.12513759]]" 187 | }, 188 | { 189 | "points": "[[-7477.04076590812,6700725.82340535],[-7471.90893738255,6700710.31970879],[-7455.13309012001,6700715.89246268],[-7457.25929239416,6700722.32256807],[-7441.75248732666,6700727.4487946],[-7443.51133528119,6700732.77150012],[-7426.73548801864,6700738.30854647],[-7428.85055834372,6700744.7029466],[-7402.65708216006,6700753.38362073],[-7408.3455081396,6700770.56638153],[-7400.82031056197,6700773.06699423],[-7407.93362602366,6700794.55443351],[-7409.98190465426,6700793.87569392],[-7411.18415515482,6700797.51945452],[-7409.13587652423,6700798.19819442],[-7411.12849540943,6700804.19968652],[-7426.88020335668,6700798.98410385],[-7424.28645922119,6700791.14287454],[-7422.93949338259,6700791.58941359],[-7416.99503257423,6700773.62070144],[-7418.34199841283,6700773.17416337],[-7416.31598368039,6700767.08338656],[-7434.69483161036,6700760.99261429],[-7432.55749738713,6700754.50889398],[-7449.76749066377,6700748.81108341],[-7447.83053152397,6700742.97038518],[-7463.78261455464,6700737.70125733],[-7461.55622473878,6700730.96749551],[-7477.04076590812,6700725.82340535]]" 190 | }, 191 | { 192 | "points": "[[-7300.03164359774,6699302.62472248],[-7285.64916538725,6699301.92824872],[-7285.68256123449,6699309.00013885],[-7264.6209135764,6699307.91078164],[-7264.73223306719,6699302.60686418],[-7248.42392766598,6699302.48185606],[-7247.31073275804,6699286.23081756],[-7232.57203217701,6699285.5343452],[-7232.87259480216,6699302.57114757],[-7165.55769871946,6699303.42834612],[-7165.39071948327,6699284.15925893],[-7150.3514562771,6699284.24855024],[-7151.18635245805,6699300.60673458],[-7140.0655353278,6699300.35671842],[-7139.78723660082,6699312.26821135],[-7264.68770527088,6699315.08982692],[-7264.565253831,6699320.66162761],[-7282.61014328859,6699321.07236948],[-7285.59350564185,6699333.07318451],[-7299.84240046339,6699333.76966093],[-7300.03164359774,6699302.62472248]]" 193 | }, 194 | { 195 | "points": "[[-7235.57765842843,6699387.04135367],[-7234.80955394196,6699339.77007557],[-7222.85384063076,6699339.9665178],[-7223.62194511724,6699387.23779703],[-7235.57765842843,6699387.04135367]]" 196 | }, 197 | { 198 | "points": "[[-7221.02820098175,6699247.01415908],[-7220.93914538912,6699235.47778269],[-7136.87066594204,6699236.08495999],[-7136.95972153467,6699247.62133724],[-7221.02820098175,6699247.01415908]]" 199 | }, 200 | { 201 | "points": "[[-7066.92862987663,6699173.83166402],[-7040.20082013716,6699143.0087794],[-7008.09627899238,6699170.86723321],[-7034.82408873184,6699201.67236502],[-7066.92862987663,6699173.83166402]]" 202 | }, 203 | { 204 | "points": "[[-7333.69465761363,6699466.86918116],[-7317.1748451799,6699464.13680637],[-7311.13019682983,6699500.8007091],[-7327.65000926355,6699503.53309618],[-7333.69465761363,6699466.86918116]]" 205 | }, 206 | { 207 | "points": "[[-7280.52846881076,6699508.40853422],[-7268.23879702718,6699507.60489038],[-7269.6302906621,6699487.71026607],[-7261.5484956305,6699487.2637984],[-7260.15700199559,6699507.03341037],[-7247.19941326725,6699506.12261419],[-7246.60941996605,6699514.76625266],[-7279.93847550955,6699517.05217511],[-7280.52846881076,6699508.40853422]]" 208 | }, 209 | { 210 | "points": "[[-7239.66308374055,6699478.38802614],[-7237.82631214246,6699397.32784866],[-7223.02081986695,6699397.7564529],[-7224.85759146504,6699478.62018907],[-7239.66308374055,6699478.38802614]]" 211 | }, 212 | { 213 | "points": "[[-7227.42907170237,6699478.65590644],[-7174.51891772832,6699478.8702107],[-7174.35193849213,6699490.2283442],[-7227.42907170237,6699489.38898474],[-7227.42907170237,6699478.65590644]]" 214 | }, 215 | { 216 | "points": "[[-7306.61062550362,6699524.35641599],[-7297.02601734632,6699524.35641599],[-7297.02601734632,6699541.85804665],[-7306.61062550362,6699541.85804665],[-7306.61062550362,6699524.35641599]]" 217 | }, 218 | { 219 | "points": "[[-7282.34297651069,6699530.14266523],[-7266.30183788738,6699529.10685488],[-7265.77863628065,6699537.07188269],[-7281.81977490396,6699538.10769406],[-7282.34297651069,6699530.14266523]]" 220 | }, 221 | { 222 | "points": "[[-7293.07417542316,6699546.03701299],[-7285.17049157684,6699545.92985998],[-7284.95898454433,6699561.96710947],[-7292.86266839065,6699562.07426269],[-7293.07417542316,6699546.03701299]]" 223 | }, 224 | { 225 | "points": "[[-7284.94785259525,6699566.64613474],[-7275.77512655388,6699566.53898146],[-7275.56361952138,6699583.41564052],[-7284.73634556274,6699583.52279402],[-7284.94785259525,6699566.64613474]]" 226 | }, 227 | { 228 | "points": "[[-7295.99074608194,6699618.31203889],[-7295.3673569335,6699593.95240833],[-7277.65642594829,6699594.39888184],[-7278.27981509673,6699618.77637273],[-7295.99074608194,6699618.31203889]]" 229 | }, 230 | { 231 | "points": "[[-7244.70585667348,6699556.05582564],[-7244.61680108085,6699532.66075647],[-7224.20080646936,6699532.73219169],[-7224.27873011292,6699556.12726107],[-7244.70585667348,6699556.05582564]]" 232 | }, 233 | { 234 | "points": "[[-7196.20395453485,6699562.39572236],[-7196.05923919682,6699519.49882719],[-7180.19621175878,6699519.55240352],[-7180.34092709681,6699562.44929897],[-7196.20395453485,6699562.39572236]]" 235 | }, 236 | { 237 | "points": "[[-7221.15065242163,6699585.13009672],[-7207.21345217431,6699578.16512063],[-7196.04810724774,6699600.50664194],[-7209.97417554598,6699607.47163712],[-7221.15065242163,6699585.13009672]]" 238 | }, 239 | { 240 | "points": "[[-7222.89836842708,6699397.79216993],[-7141.18986218482,6699396.82781041],[-7141.54608455536,6699411.63252733],[-7222.60893775102,6699410.68602472],[-7222.89836842708,6699397.79216993]]" 241 | }, 242 | { 243 | "points": "[[-7153.20123524141,6699466.97633313],[-7153.19010329233,6699438.79541317],[-7140.29930625847,6699438.79541317],[-7140.29930625847,6699466.97633313],[-7153.20123524141,6699466.97633313]]" 244 | }, 245 | { 246 | "points": "[[-7156.20686149283,6699553.21626786],[-7156.03988225664,6699505.49755804],[-7140.36609795295,6699505.55113428],[-7140.53307718913,6699553.26984442],[-7156.20686149283,6699553.21626786]]" 247 | }, 248 | { 249 | "points": "[[-7164.36658016798,6699618.88352669],[-7164.19960093179,6699569.55713274],[-7148.36996934098,6699569.6107094],[-7148.53694857717,6699618.93710368],[-7164.36658016798,6699618.88352669]]" 250 | }, 251 | { 252 | "points": "[[-6976.84889792671,6699198.45791105],[-6963.96923284193,6699188.49311178],[-6949.03015717747,6699207.79768916],[-6961.90982226225,6699217.76251201],[-6976.84889792671,6699198.45791105]]" 253 | }, 254 | { 255 | "points": "[[-6958.39212635318,6699221.67344043],[-6943.41965484149,6699213.4765652],[-6930.13923958985,6699237.78148503],[-6945.11171110154,6699245.97838469],[-6958.39212635318,6699221.67344043]]" 256 | }, 257 | { 258 | "points": "[[-7034.3120190742,6699230.03104719],[-7016.08901843134,6699219.49474948],[-6963.43489928612,6699309.01799716],[-6982.05865009583,6699319.14366871],[-7034.3120190742,6699230.03104719]]" 259 | }, 260 | { 261 | "points": "[[-6938.84442376988,6699256.24684359],[-6923.51572988765,6699247.72848633],[-6906.71761872695,6699277.98030271],[-6922.04631260918,6699286.49869156],[-6938.84442376988,6699256.24684359]]" 262 | }, 263 | { 264 | "points": "[[-6919.81992279331,6699296.17787795],[-6904.72499984174,6699288.15951055],[-6885.23295700384,6699324.85833899],[-6900.31674800633,6699332.87674246],[-6919.81992279331,6699296.17787795]]" 265 | }, 266 | { 267 | "points": "[[-6971.42763872507,6699326.05484858],[-6956.121208741,6699317.03638506],[-6934.9593735412,6699352.98529007],[-6950.25467157619,6699361.9859349],[-6971.42763872507,6699326.05484858]]" 268 | }, 269 | { 270 | "points": "[[-6919.3969087283,6699177.49255898],[-6847.13942725438,6699129.7224734],[-6806.22951438786,6699104.34640339],[-6797.86942062928,6699119.27559476],[-6908.34288329253,6699190.33249138],[-6919.3969087283,6699177.49255898]]" 271 | }, 272 | { 273 | "points": "[[-6847.5624413194,6699235.53135716],[-6817.76221363404,6699229.8703239],[-6812.36321833057,6699258.30053692],[-6842.174577965,6699263.94373169],[-6847.5624413194,6699235.53135716]]" 274 | }, 275 | { 276 | "points": "[[-6832.35619887704,6699173.51021967],[-6820.99047886705,6699164.5990728],[-6759.28608512033,6699243.24608389],[-6770.65180513033,6699252.17517486],[-6832.35619887704,6699173.51021967]]" 277 | }, 278 | { 279 | "points": "[[-6805.58386134126,6699282.92703897],[-6754.74424989597,6699246.33554826],[-6746.88509384596,6699257.26476109],[-6797.72470529125,6699293.85630083],[-6805.58386134126,6699282.92703897]]" 280 | }, 281 | { 282 | "points": "[[-6939.38988927477,6699366.71842079],[-6925.88683504155,6699357.48561124],[-6875.62608494838,6699430.99120857],[-6889.12913918161,6699440.22410131],[-6939.38988927477,6699366.71842079]]" 283 | }, 284 | { 285 | "points": "[[-6943.97625229545,6699576.50424259],[-6931.39714983581,6699556.52015594],[-6925.49721682377,6699560.23479926],[-6938.07631928341,6699580.21889501],[-6943.97625229545,6699576.50424259]]" 286 | }, 287 | { 288 | "points": "[[-6892.61343924344,6699451.70719141],[-6879.57792687155,6699441.47420365],[-6859.7296616631,6699469.01222085],[-6872.73177818776,6699478.95950414],[-6892.61343924344,6699451.70719141]]" 289 | }, 290 | { 291 | "points": "[[-6867.09901195362,6699506.97983412],[-6824.57496647059,6699478.97736283],[-6816.18147686478,6699491.72847623],[-6858.69439039873,6699519.7309913],[-6867.09901195362,6699506.97983412]]" 292 | }, 293 | { 294 | "points": "[[-6821.36896513574,6699476.40571212],[-6769.38276293528,6699453.15374045],[-6763.47169797416,6699466.36913865],[-6815.45790017462,6699489.62114799],[-6821.36896513574,6699476.40571212]]" 295 | }, 296 | { 297 | "points": "[[-6825.82174476747,6699541.822329],[-6741.16327201919,6699536.42896536],[-6740.07234100941,6699553.41271523],[-6824.74194570678,6699558.82394895],[-6825.82174476747,6699541.822329]]" 298 | }, 299 | { 300 | "points": "[[-7310.15058531085,6699644.77910998],[-7308.90380701396,6699621.02660633],[-7291.47117475574,6699621.93741534],[-7292.7290850017,6699645.68992165],[-7310.15058531085,6699644.77910998]]" 301 | }, 302 | { 303 | "points": "[[-7323.27515327537,6699672.28209536],[-7322.86327115944,6699647.69013586],[-7305.98723635518,6699647.97588079],[-7306.41025042019,6699672.56784115],[-7323.27515327537,6699672.28209536]]" 304 | }, 305 | { 306 | "points": "[[-7328.97471120399,6699683.71193474],[-7328.82999586596,6699674.63949842],[-7303.37122832154,6699675.05025811],[-7303.50481171049,6699684.10483575],[-7328.97471120399,6699683.71193474]]" 307 | }, 308 | { 309 | "points": "[[-7288.69931943498,6699701.03531559],[-7288.48781240248,6699674.56806195],[-7270.96612455162,6699674.71093488],[-7271.17763158412,6699701.16032981],[-7288.69931943498,6699701.03531559]]" 310 | }, 311 | { 312 | "points": "[[-7360.55605074204,6699688.15886095],[-7354.2219717159,6699680.58658644],[-7305.72006957728,6699721.14477084],[-7321.05989540859,6699739.48620887],[-7337.82461072205,6699725.44884364],[-7328.82999586596,6699714.69759551],[-7360.55605074204,6699688.15886095]]" 313 | }, 314 | { 315 | "points": "[[-7292.1390917005,6699703.51774122],[-7275.26305689624,6699703.32129024],[-7275.15173740544,6699711.85798251],[-7292.0277722097,6699712.07229289],[-7292.1390917005,6699703.51774122]]" 316 | }, 317 | { 318 | "points": "[[-7261.82679435749,6699644.56480136],[-7260.78039114403,6699619.99078443],[-7243.32549498764,6699620.72300334],[-7244.36076625202,6699645.31488153],[-7261.82679435749,6699644.56480136]]" 319 | }, 320 | { 321 | "points": "[[-7263.69696180282,6699672.47854559],[-7262.86206562186,6699647.90444456],[-7245.1288707385,6699648.51165255],[-7245.96376691945,6699673.08575541],[-7263.69696180282,6699672.47854559]]" 322 | }, 323 | { 324 | "points": "[[-7212.37867654711,6699629.93825184],[-7204.0408466867,6699626.33073084],[-7197.04998266488,6699642.49315173],[-7205.37668057622,6699646.10067988],[-7212.37867654711,6699629.93825184]]" 325 | }, 326 | { 327 | "points": "[[-7230.1007394814,6699637.22473477],[-7223.04308376511,6699634.1708404],[-7215.49562228933,6699651.6191295],[-7222.54214605654,6699654.6730304],[-7230.1007394814,6699637.22473477]]" 328 | }, 329 | { 330 | "points": "[[-7201.25785941687,6699618.95496267],[-7193.04248099632,6699614.32948434],[-7178.04774558647,6699640.99299198],[-7186.26312400701,6699645.61848543],[-7201.25785941687,6699618.95496267]]" 331 | }, 332 | { 333 | "points": "[[-7349.12353903757,6699762.36395132],[-7334.52955379458,6699741.07568305],[-7313.45677418741,6699755.54169822],[-7328.05075943041,6699776.81214491],[-7349.12353903757,6699762.36395132]]" 334 | }, 335 | { 336 | "points": "[[-7252.79878365415,6699769.5433966],[-7244.22718286307,6699757.48836149],[-7229.65546151823,6699767.86462027],[-7238.22706230931,6699779.90181138],[-7252.79878365415,6699769.5433966]]" 337 | }, 338 | { 339 | "points": "[[-6870.38293693202,6699642.90390981],[-6858.20458463923,6699641.56448138],[-6858.62759870425,6699637.72478776],[-6836.31917274928,6699635.27810022],[-6832.67902540034,6699670.17472047],[-6866.97656051375,6699673.9429929],[-6870.38293693202,6699642.90390981]]" 340 | }, 341 | { 342 | "points": "[[-6836.61973537442,6699632.56352803],[-6818.02938041194,6699630.52759949],[-6817.71768583772,6699633.34932515],[-6815.37997653106,6699633.09929879],[-6815.62487941081,6699630.84906185],[-6787.92859010144,6699627.79516987],[-6788.08443738855,6699626.4200259],[-6755.11160421559,6699622.81250645],[-6742.78853658477,6699734.96781768],[-6773.90233426149,6699738.37893491],[-6777.06380780002,6699709.60772385],[-6785.17899867885,6699710.50068355],[-6787.78387476341,6699686.85514338],[-6800.70806764451,6699688.28387498],[-6800.26278968134,6699692.33790225],[-6798.12545545811,6699711.78654571],[-6805.85102811916,6699712.62592806],[-6805.57272939218,6699715.21551245],[-6827.45814128213,6699717.62650556],[-6830.68640651514,6699688.26601583],[-6832.67902540034,6699670.17472047],[-6836.31917274928,6699635.27810022],[-6836.61973537442,6699632.56352803]]" 343 | }, 344 | { 345 | "points": "[[-6809.88079368588,6699728.12772827],[-6793.95097455336,6699726.43110124],[-6794.20700938218,6699724.03796475],[-6785.44616545675,6699723.10928511],[-6785.16786672977,6699725.71673206],[-6779.72434362998,6699725.14523677],[-6778.3662458423,6699737.98603128],[-6808.48930005096,6699741.20069789],[-6809.88079368588,6699728.12772827]]" 346 | }, 347 | { 348 | "points": "[[-6861.76680834462,6699926.17117618],[-6860.55342589497,6699918.13432979],[-6853.92991619277,6699914.16948849],[-6846.2154754808,6699914.84815488],[-6841.65137635828,6699921.0990322],[-6842.51966838646,6699928.70724935],[-6848.8537474126,6699933.60080121],[-6857.42534820368,6699932.4935009],[-6861.76680834462,6699926.17117618]]" 349 | }, 350 | { 351 | "points": "[[-6805.39461820691,6699918.24148769],[-6797.09018419373,6699912.72285768],[-6780.61489955632,6699937.54779227],[-6788.90820162042,6699943.06643907],[-6805.39461820691,6699918.24148769]]" 352 | }, 353 | { 354 | "points": "[[-6806.74158404551,6699964.49811255],[-6775.85042535037,6699944.76311117],[-6767.44580379548,6699957.9257267],[-6786.51483256837,6699970.10607641],[-6798.33696249061,6699977.66075993],[-6806.74158404551,6699964.49811255]]" 355 | }, 356 | { 357 | "points": "[[-6762.28057942267,6699989.59110182],[-6747.49735104533,6699980.35758718],[-6734.80692909489,6700000.64632941],[-6749.59015747224,6700009.89772687],[-6762.28057942267,6699989.59110182]]" 358 | }, 359 | { 360 | "points": "[[-6817.20561618007,6700035.66953225],[-6799.53921299118,6700025.13219381],[-6791.91382787184,6700037.90202096],[-6809.58023106073,6700048.4393759],[-6817.20561618007,6700035.66953225]]" 361 | }, 362 | { 363 | "points": "[[-6760.67757875525,6700021.20302024],[-6747.89810121218,6700012.52312536],[-6740.33950778732,6700023.64982356],[-6732.11299741769,6700018.05968276],[-6716.14978243794,6700041.509724],[-6737.15577035063,6700055.79767251],[-6760.67757875525,6700021.20302024]]" 364 | }, 365 | { 366 | "points": "[[-6785.15673478069,6700101.17993497],[-6778.52209312941,6700096.00052192],[-6782.44053920533,6700090.96399239],[-6777.14173144357,6700086.82046688],[-6763.32698263613,6700104.53762518],[-6775.27156399825,6700113.84272072],[-6785.15673478069,6700101.17993497]]" 367 | }, 368 | { 369 | "points": "[[-6756.79252852656,6700072.96110375],[-6744.72549572457,6700065.40633196],[-6733.44883130722,6700083.40920393],[-6745.51586410921,6700090.96399239],[-6756.79252852656,6700072.96110375]]" 370 | }, 371 | { 372 | "points": "[[-6748.08734434653,6699185.49295955],[-6735.04070002556,6699178.72476302],[-6730.73263573186,6699187.01089357],[-6660.45664119407,6699150.54483893],[-6665.13205980738,6699141.54442741],[-6652.5195615005,6699134.99056257],[-6623.74347313044,6699190.45749777],[-6640.65290378194,6699199.22580827],[-6654.1893538624,6699173.13520126],[-6718.87710996238,6699206.70834546],[-6713.96792041839,6699216.15528169],[-6728.30587083257,6699223.60211815],[-6748.08734434653,6699185.49295955]]" 373 | }, 374 | { 375 | "points": "[[-6715.81582396556,6699255.80038858],[-6685.47013077531,6699235.90637843],[-6677.38833574372,6699248.54996275],[-6707.84534842476,6699268.12255565],[-6715.81582396556,6699255.80038858]]" 376 | }, 377 | { 378 | "points": "[[-6677.38833574372,6699248.54996275],[-6647.65489975284,6699230.42392635],[-6639.9738548881,6699242.5496152],[-6669.69615892991,6699261.33643236],[-6677.38833574372,6699248.54996275]]" 379 | }, 380 | { 381 | "points": "[[-6628.51907928547,6699161.93823124],[-6617.29807461351,6699150.72341862],[-6605.63179197838,6699162.38468111],[-6616.85279665034,6699173.61736778],[-6628.51907928547,6699161.93823124]]" 382 | }, 383 | { 384 | "points": "[[-6627.23890514135,6699225.94153341],[-6613.71358700997,6699218.31611364],[-6592.07307799976,6699255.69323939],[-6606.08820189063,6699263.81872417],[-6627.23890514135,6699225.94153341]]" 385 | }, 386 | { 387 | "points": "[[-6688.40896533226,6699278.44461718],[-6673.97082737637,6699268.01540629],[-6635.22051263123,6699325.73339823],[-6650.46015092083,6699335.62693166],[-6688.40896533226,6699278.44461718]]" 388 | }, 389 | { 390 | "points": "[[-6720.14615215742,6699315.87559346],[-6688.80971549911,6699313.08969427],[-6686.09351992376,6699343.59177054],[-6717.42995658206,6699346.37768015],[-6720.14615215742,6699315.87559346]]" 391 | }, 392 | { 393 | "points": "[[-6614.91583751054,6699300.08884396],[-6585.99503380244,6699279.15894718],[-6577.76852343282,6699291.80259854],[-6606.90083417342,6699312.37536129],[-6614.91583751054,6699300.08884396]]" 394 | }, 395 | { 396 | "points": "[[-6630.41151062896,6699343.9132216],[-6594.33286366286,6699318.78650196],[-6584.71485965832,6699331.87667389],[-6621.59500695813,6699357.00343386],[-6630.41151062896,6699343.9132216]]" 397 | }, 398 | { 399 | "points": "[[-6584.49222067674,6699276.55164298],[-6556.69574382565,6699258.10409667],[-6550.79581081361,6699267.21178615],[-6578.33625283587,6699285.40933735],[-6584.49222067674,6699276.55164298]]" 400 | }, 401 | { 402 | "points": "[[-6571.62368754103,6699290.19535364],[-6550.23921335964,6699276.83737491],[-6545.16304457947,6699286.19510103],[-6567.08185231667,6699299.01734624],[-6571.62368754103,6699290.19535364]]" 403 | }, 404 | { 405 | "points": "[[-6557.60856365016,6699324.51903033],[-6548.82545582657,6699320.05444402],[-6550.57317183202,6699316.6256434],[-6529.37794078499,6699305.8392175],[-6520.46124957244,6699323.376096],[-6523.63385506005,6699324.98334744],[-6517.5780747609,6699336.89487634],[-6529.13303790524,6699342.77028455],[-6530.26849671133,6699340.55584449],[-6545.50813500093,6699348.30638735],[-6557.60856365016,6699324.51903033]]" 406 | }, 407 | { 408 | "points": "[[-6559.04458508139,6699373.30818873],[-6547.10000371927,6699367.21845719],[-6550.17242166517,6699361.21802235],[-6525.80458513052,6699348.78856423],[-6519.90465211848,6699360.36081774],[-6518.2237278075,6699363.66462769],[-6522.77669498094,6699365.98622468],[-6517.74505399709,6699375.86194848],[-6547.43396219165,6699390.98808025],[-6552.00919326326,6699382.02312037],[-6554.06860384293,6699383.05891204],[-6556.59555628394,6699378.11211506],[-6559.04458508139,6699373.30818873]]" 409 | }, 410 | { 411 | "points": "[[-6723.96441069163,6699436.7059572],[-6688.28651389238,6699432.29488525],[-6684.55731095081,6699462.42237559],[-6720.23520775005,6699466.83346384],[-6723.96441069163,6699436.7059572]]" 412 | }, 413 | { 414 | "points": "[[-6645.80699620567,6699413.25765471],[-6635.18711678399,6699407.97152728],[-6637.25765931275,6699403.8104902],[-6626.87155082173,6699398.63151996],[-6624.7342165985,6699402.91756406],[-6615.45017106634,6699398.31006675],[-6607.35724408567,6699414.5791871],[-6637.6584094796,6699429.65181494],[-6645.80699620567,6699413.25765471]]" 415 | }, 416 | { 417 | "points": "[[-6645.32832239526,6699452.9572955],[-6626.66004378923,6699443.70652973],[-6611.67644032845,6699473.90549693],[-6630.4449064762,6699483.20987305],[-6635.63239474716,6699472.76254168],[-6638.7382085403,6699474.29838784],[-6643.17985622295,6699465.33333639],[-6639.9738548881,6699463.74391595],[-6645.32832239526,6699452.9572955]]" 418 | }, 419 | { 420 | "points": "[[-6672.63499348685,6699516.6235646],[-6638.52670150779,6699514.14119585],[-6636.40049923364,6699543.17959988],[-6670.51992316178,6699545.66197747],[-6672.63499348685,6699516.6235646]]" 421 | }, 422 | { 423 | "points": "[[-6740.06120906033,6699622.90180147],[-6736.86633967457,6699615.20457463],[-6707.40007046159,6699627.40227157],[-6710.59493984735,6699635.09950991],[-6740.06120906033,6699622.90180147]]" 424 | }, 425 | { 426 | "points": "[[-6676.7538146462,6699621.72310733],[-6673.7370564457,6699614.75809998],[-6644.90530833025,6699627.24154045],[-6647.92206653074,6699634.20655846],[-6676.7538146462,6699621.72310733]]" 427 | }, 428 | { 429 | "points": "[[-6596.47019788609,6699542.48310558],[-6587.0414370159,6699537.4112002],[-6593.00816172242,6699526.33874165],[-6587.28633989565,6699523.26703001],[-6580.35113561922,6699535.44673065],[-6574.37327896363,6699531.85711024],[-6568.10599163197,6699543.5010588],[-6574.41780675994,6699547.16211968],[-6574.78516107956,6699551.16250028],[-6577.32324546965,6699552.96624396],[-6580.21755223027,6699551.51967722],[-6583.12299093998,6699552.60906696],[-6583.03393534734,6699555.73436622],[-6586.38465202022,6699557.32380459],[-6589.64631310046,6699555.14502398],[-6596.47019788609,6699542.48310558]]" 430 | }, 431 | { 432 | "points": "[[-6633.28355349143,6699624.38409888],[-6632.92733112089,6699611.20416263],[-6591.11573037893,6699612.34713729],[-6591.47195274947,6699625.52707539],[-6633.28355349143,6699624.38409888]]" 433 | }, 434 | { 435 | "points": "[[-6567.9278804467,6699427.45520985],[-6555.23745849626,6699420.54394408],[-6541.85685570291,6699414.06128924],[-6534.8103319357,6699427.77666422],[-6560.88135667948,6699441.17060735],[-6567.9278804467,6699427.45520985]]" 436 | }, 437 | { 438 | "points": "[[-6535.03297091728,6699400.11377662],[-6491.51818196619,6699377.02274862],[-6481.20999711874,6699396.47064025],[-6513.73755232853,6699413.72197687],[-6511.09928039673,6699418.68665401],[-6522.08651413803,6699424.50854544],[-6535.03297091728,6699400.11377662]]" 439 | }, 440 | { 441 | "points": "[[-6524.26837615757,6699438.95614057],[-6509.58533532194,6699431.83056202],[-6502.62786714736,6699446.17101843],[-6517.32203993207,6699453.29660951],[-6524.26837615757,6699438.95614057]]" 442 | }, 443 | { 444 | "points": "[[-6492.3753420453,6699430.27686527],[-6473.81838293006,6699420.7582468],[-6449.01640038132,6699469.08365552],[-6467.57335949656,6699478.60233038],[-6492.3753420453,6699430.27686527]]" 445 | }, 446 | { 447 | "points": "[[-6573.8500773569,6699477.26292893],[-6554.09086774109,6699466.58344258],[-6547.28924685362,6699479.15594972],[-6542.85873112005,6699478.1737219],[-6536.83634666813,6699489.33540861],[-6542.44684900412,6699492.37139004],[-6531.76017788796,6699512.14101439],[-6525.37043911643,6699508.69427426],[-6518.72466551607,6699520.98110582],[-6522.64311159199,6699523.08844216],[-6516.609595191,6699534.23233153],[-6537.05898564972,6699545.28694195],[-6573.8500773569,6699477.26292893]]" 448 | }, 449 | { 450 | "points": "[[-6531.64885839717,6699555.52005995],[-6517.48901916826,6699548.07292045],[-6512.57982962428,6699557.41309889],[-6494.67965550472,6699549.4837689],[-6481.08754567886,6699572.61100292],[-6499.36620606712,6699582.21909317],[-6503.37370773568,6699574.59334032],[-6517.67826230261,6699582.11193969],[-6531.64885839717,6699555.52005995]]" 451 | }, 452 | { 453 | "points": "[[-6502.51654765657,6699534.71451939],[-6458.17799447361,6699511.1587826],[-6460.29306479868,6699507.17628037],[-6447.58037895009,6699500.40781692],[-6454.66029856454,6699487.08521134],[-6439.72122290008,6699479.13809102],[-6422.67820885963,6699511.21235888],[-6494.67965550472,6699549.4837689],[-6502.51654765657,6699534.71451939]]" 454 | }, 455 | { 456 | "points": "[[-6506.74668830671,6699615.36530551],[-6497.11755235309,6699609.75758555],[-6494.98021812986,6699613.22222736],[-6490.4383829055,6699610.8291241],[-6488.83538223807,6699613.22222736],[-6482.42337956838,6699610.29335481],[-6477.88154434402,6699619.6336045],[-6479.85189933106,6699620.2408104],[-6498.45338624261,6699630.59903557],[-6506.74668830671,6699615.36530551]]" 457 | }, 458 | { 459 | "points": "[[-6731.77903894531,6699671.01409854],[-6722.28348638065,6699648.56522974],[-6711.58568331542,6699653.10143213],[-6721.09236782916,6699675.5324543],[-6731.77903894531,6699671.01409854]]" 460 | }, 461 | { 462 | "points": "[[-6673.64800085307,6699671.83561758],[-6670.66463849981,6699664.85270835],[-6641.67704309724,6699677.22907075],[-6644.6604054505,6699684.22984972],[-6673.64800085307,6699671.83561758]]" 463 | }, 464 | { 465 | "points": "[[-6734.01656071026,6699719.43028605],[-6726.29098804921,6699719.3767084],[-6726.30211999829,6699716.67996744],[-6715.40394184962,6699716.6085306],[-6715.29262235883,6699734.89638069],[-6733.91637316855,6699735.02139543],[-6734.01656071026,6699719.43028605]]" 466 | }, 467 | { 468 | "points": "[[-6715.40394184962,6699716.6085306],[-6702.74691574643,6699716.37636089],[-6702.72465184827,6699720.53755744],[-6698.81733772143,6699720.51969822],[-6698.75054602695,6699734.96781768],[-6715.29262235883,6699734.89638069],[-6715.40394184962,6699716.6085306]]" 469 | }, 470 | { 471 | "points": "[[-6678.4236070081,6699716.78712269],[-6646.3301978124,6699716.67996744],[-6646.274538067,6699732.21749384],[-6678.3679472627,6699732.30679005],[-6678.4236070081,6699716.78712269]]" 472 | }, 473 | { 474 | "points": "[[-6634.53033178831,6699651.69056576],[-6634.07392187606,6699634.88520156],[-6630.84565664305,6699631.43840956],[-6596.57038542781,6699632.36707877],[-6597.12698288177,6699652.70853261],[-6634.53033178831,6699651.69056576]]" 475 | }, 476 | { 477 | "points": "[[-6589.93574377653,6699658.92349088],[-6587.11936065946,6699657.22687824],[-6589.02292395202,6699654.04796287],[-6574.03932049125,6699645.10057291],[-6562.13926692545,6699665.0312993],[-6558.52138347466,6699671.5141536],[-6571.2118054251,6699678.21132254],[-6574.57365404705,6699672.44282736],[-6580.50698290634,6699662.49530811],[-6585.88371431165,6699665.70994496],[-6589.93574377653,6699658.92349088]]" 478 | }, 479 | { 480 | "points": "[[-6730.49886480119,6699788.92078668],[-6729.00718362456,6699773.99036961],[-6703.92690234884,6699776.68712953],[-6705.11802090033,6699791.90330151],[-6730.49886480119,6699788.92078668]]" 481 | }, 482 | { 483 | "points": "[[-6726.9923008412,6699810.42349279],[-6724.91062636337,6699793.42134839],[-6689.43310464755,6699797.77903748],[-6691.52591107447,6699814.78119097],[-6726.9923008412,6699810.42349279]]" 484 | }, 485 | { 486 | "points": "[[-6675.71854338182,6699766.38229678],[-6619.27956154963,6699765.77508001],[-6619.1348462116,6699780.25899833],[-6675.56269609471,6699780.84835684],[-6675.71854338182,6699766.38229678]]" 487 | }, 488 | { 489 | "points": "[[-6575.04119590839,6699680.78303687],[-6553.5454022362,6699670.12114315],[-6544.45059983839,6699689.42686044],[-6561.5715375224,6699698.24928484],[-6566.22469223756,6699691.266353],[-6569.11899899818,6699692.71294453],[-6575.04119590839,6699680.78303687]]" 490 | }, 491 | { 492 | "points": "[[-6561.5715375224,6699698.24928484],[-6544.45059983839,6699689.42686044],[-6538.12765276134,6699701.66038672],[-6543.05910620348,6699704.33926354],[-6539.3299032619,6699710.76857149],[-6551.53051945285,6699717.73366082],[-6561.5715375224,6699698.24928484]]" 493 | }, 494 | { 495 | "points": "[[-6551.46372775837,6699726.73470815],[-6533.06261593024,6699716.89427794],[-6523.5559314165,6699734.69992896],[-6541.95704324463,6699744.52252138],[-6551.46372775837,6699726.73470815]]" 496 | }, 497 | { 498 | "points": "[[-6498.45338624261,6699630.59903557],[-6479.85189933106,6699620.2408104],[-6475.98911300053,6699628.38451735],[-6480.16359390528,6699630.36686831],[-6478.37135010351,6699634.15298137],[-6492.84288390663,6699641.01085102],[-6498.45338624261,6699630.59903557]]" 499 | }, 500 | { 501 | "points": "[[-6488.7129307982,6699650.47614933],[-6469.13183236767,6699640.33220741],[-6462.24115588756,6699654.10154009],[-6481.8222543181,6699664.62054011],[-6488.7129307982,6699650.47614933]]" 502 | }, 503 | { 504 | "points": "[[-6476.72382163977,6699667.88875511],[-6460.84966225265,6699658.3162821],[-6453.38012442042,6699670.7283528],[-6469.24315185846,6699680.28298124],[-6476.72382163977,6699667.88875511]]" 505 | }, 506 | { 507 | "points": "[[-6465.1799904445,6699691.90928254],[-6447.14623293599,6699682.33678134],[-6439.4985839185,6699696.74911484],[-6457.53234142701,6699706.32163295],[-6465.1799904445,6699691.90928254]]" 508 | }, 509 | { 510 | "points": "[[-6455.95160465774,6699710.94716345],[-6441.79176542884,6699703.73205138],[-6431.26094159979,6699724.35943081],[-6445.4207808287,6699731.59242036],[-6455.95160465774,6699710.94716345]]" 511 | }, 512 | { 513 | "points": "[[-6567.76090121051,6699770.91856471],[-6514.53905266224,6699734.61063272],[-6507.96007075636,6699744.2724916],[-6561.17078735554,6699780.56260725],[-6567.76090121051,6699770.91856471]]" 514 | }, 515 | { 516 | "points": "[[-6539.29650741467,6699767.79318299],[-6525.59307809801,6699759.00640196],[-6520.31653423441,6699767.23954407],[-6514.20509418986,6699763.32835405],[-6496.7390660844,6699790.61742672],[-6512.73567691139,6699800.85085251],[-6531.15905263768,6699772.07942107],[-6534.98844312097,6699774.52614966],[-6539.29650741467,6699767.79318299]]" 517 | }, 518 | { 519 | "points": "[[-6510.55381489184,6699801.36877492],[-6491.44025832264,6699791.02819225],[-6481.37697635493,6699809.6198192],[-6478.17097502008,6699807.8874564],[-6469.94446465046,6699823.08582714],[-6489.29179215033,6699833.55146671],[-6497.35132328376,6699818.63882737],[-6500.33468563702,6699820.2461764],[-6510.55381489184,6699801.36877492]]" 520 | }, 521 | { 522 | "points": "[[-6482.21187253588,6699833.81935868],[-6466.53808823218,6699824.26455038],[-6438.91972256637,6699869.6455246],[-6454.59350687006,6699879.18252649],[-6482.21187253588,6699833.81935868]]" 523 | }, 524 | { 525 | "points": "[[-6703.41483269119,6699868.34177801],[-6690.99157751866,6699865.0734827],[-6683.56656748275,6699893.27373509],[-6695.9786907062,6699896.54204171],[-6703.41483269119,6699868.34177801]]" 526 | }, 527 | { 528 | "points": "[[-6715.01432363185,6699928.29647688],[-6709.29250180507,6699924.77812224],[-6703.12540201513,6699934.79740011],[-6708.85835579098,6699938.31575908],[-6715.01432363185,6699928.29647688]]" 529 | }, 530 | { 531 | "points": "[[-6695.39982935407,6699898.04224846],[-6686.48313814153,6699896.61348012],[-6683.52203968643,6699912.24064747],[-6692.21609191739,6699913.90159387],[-6695.39982935407,6699898.04224846]]" 532 | }, 533 | { 534 | "points": "[[-6721.27047901443,6699962.81929609],[-6705.75254199785,6699953.12145887],[-6692.61684208424,6699974.16024376],[-6708.13477910082,6699983.85810601],[-6721.27047901443,6699962.81929609]]" 535 | }, 536 | { 537 | "points": "[[-6663.46226744548,6699933.17216882],[-6649.31356016566,6699924.15303401],[-6641.48779996289,6699936.42263173],[-6644.78285689037,6699939.99457049],[-6637.29105515998,6699951.74626005],[-6651.25051930546,6699960.64040717],[-6659.20986289718,6699948.17431614],[-6655.42500021021,6699945.76325489],[-6663.46226744548,6699933.17216882]]" 538 | }, 539 | { 540 | "points": "[[-6632.19262248165,6699925.47464918],[-6602.25881140734,6699909.82959684],[-6595.66869755238,6699922.43850654],[-6625.60250862669,6699938.08358305],[-6632.19262248165,6699925.47464918]]" 541 | }, 542 | { 543 | "points": "[[-6591.57214029119,6699893.89882096],[-6576.72212021936,6699888.68382037],[-6568.35089451171,6699912.50854203],[-6583.20091458353,6699917.72355785],[-6591.57214029119,6699893.89882096]]" 544 | }, 545 | { 546 | "points": "[[-6640.77535522181,6699971.67773576],[-6628.27417640573,6699964.49811255],[-6620.09219383242,6699978.71448703],[-6632.59337264851,6699985.91198254],[-6640.77535522181,6699971.67773576]]" 547 | }, 548 | { 549 | "points": "[[-6604.37388173241,6699978.58946855],[-6569.96502712821,6699960.03317593],[-6561.63832921688,6699975.48186704],[-6596.04718382108,6699994.0381948],[-6604.37388173241,6699978.58946855]]" 550 | }, 551 | { 552 | "points": "[[-6713.01057279757,6700047.67139872],[-6687.99708321632,6700032.54404909],[-6678.93567666575,6700047.52851926],[-6703.949166247,6700062.65589668],[-6713.01057279757,6700047.67139872]]" 553 | }, 554 | { 555 | "points": "[[-6701.29976236612,6699994.32395186],[-6686.36068670166,6699984.55463799],[-6655.06877783967,6700032.47260949],[-6670.01898545321,6700042.22412083],[-6701.29976236612,6699994.32395186]]" 556 | }, 557 | { 558 | "points": "[[-6627.71757895176,6699993.84173682],[-6613.86943429708,6699985.71552477],[-6606.33310477038,6699998.57458934],[-6620.17011747598,6700006.70081421],[-6627.71757895176,6699993.84173682]]" 559 | }, 560 | { 561 | "points": "[[-6600.27732447122,6700044.26015214],[-6577.1340023353,6700031.8653729],[-6569.63106865583,6700045.88540557],[-6579.11548927142,6700050.95762715],[-6571.90198626802,6700064.44189351],[-6585.57201973743,6700071.76448458],[-6600.27732447122,6700044.26015214]]" 562 | }, 563 | { 564 | "points": "[[-6564.52150402842,6699964.73028932],[-6551.57504724916,6699959.51524345],[-6545.20757237579,6699975.33898883],[-6558.16516110413,6699980.55404483],[-6564.52150402842,6699964.73028932]]" 565 | }, 566 | { 567 | "points": "[[-6555.69386840851,6699943.1735973],[-6520.31653423441,6699931.43977977],[-6510.87664141514,6699959.92601748],[-6530.79169831806,6699966.53412446],[-6529.54492002118,6699970.30253381],[-6545.20757237579,6699975.33898883],[-6555.69386840851,6699943.1735973]]" 568 | }, 569 | { 570 | "points": "[[-6503.2512562958,6699946.69195988],[-6495.68153092186,6699944.88812913],[-6496.72793413532,6699940.53036144],[-6489.94857714601,6699938.905129],[-6488.14520139516,6699946.49550305],[-6485.60711700507,6699957.12203857],[-6499.94506741924,6699960.55110845],[-6503.2512562958,6699946.69195988]]" 571 | }, 572 | { 573 | "points": "[[-6488.14520139516,6699946.49550305],[-6482.81299778616,6699945.20960389],[-6483.40299108736,6699941.85197926],[-6472.17085446632,6699938.70867235],[-6469.41013109465,6699953.26433668],[-6485.60711700507,6699957.12203857],[-6488.14520139516,6699946.49550305]]" 574 | }, 575 | { 576 | "points": "[[-6472.17085446632,6699938.70867235],[-6469.61050617808,6699938.905129],[-6470.03352024309,6699936.72624646],[-6459.09081429811,6699934.63666293],[-6456.0295283013,6699950.71039615],[-6469.41013109465,6699953.26433668],[-6472.17085446632,6699938.70867235]]" 577 | }, 578 | { 579 | "points": "[[-6567.52713027984,6700032.66906839],[-6545.81982957515,6700023.66768344],[-6539.15179207663,6700039.72373219],[-6560.85909278132,6700048.72513487],[-6567.52713027984,6700032.66906839]]" 580 | }, 581 | { 582 | "points": "[[-6521.70802786933,6700017.1488295],[-6505.7336809405,6700011.88017055],[-6501.35882495232,6700025.257213],[-6517.31090798299,6700030.47230091],[-6521.70802786933,6700017.1488295]]" 583 | }, 584 | { 585 | "points": "[[-6536.4801242976,6700021.54235788],[-6521.70802786933,6700017.1488295],[-6516.34242841309,6700035.18731477],[-6531.11452484136,6700039.58085287],[-6536.4801242976,6700021.54235788]]" 586 | }, 587 | { 588 | "points": "[[-6572.8259380416,6700080.3908625],[-6556.74027162197,6700070.40712574],[-6535.97918658903,6700103.87680306],[-6552.06485300865,6700113.86058079],[-6572.8259380416,6700080.3908625]]" 589 | }, 590 | { 591 | "points": "[[-6505.7336809405,6700011.88017055],[-6494.15645389799,6700007.7724049],[-6487.46615250132,6700026.86460275],[-6499.00998369658,6700030.91879832],[-6501.35882495232,6700025.257213],[-6505.7336809405,6700011.88017055]]" 592 | }, 593 | { 594 | "points": "[[-6494.15645389799,6700007.7724049],[-6480.25264949791,6700002.93238804],[-6473.96309826809,6700022.3103326],[-6487.46615250132,6700026.86460275],[-6494.15645389799,6700007.7724049]]" 595 | }, 596 | { 597 | "points": "[[-6544.50625958379,6700123.18354706],[-6528.08663469178,6700114.52140372],[-6489.57009087731,6700179.30017065],[-6504.79859721783,6700188.26600688],[-6544.50625958379,6700123.18354706]]" 598 | } 599 | ] -------------------------------------------------------------------------------- /src/Editor/main.js: -------------------------------------------------------------------------------- 1 | // react only editor here 2 | 3 | exports.editor = function() { 4 | console.log('I edit') 5 | } 6 | -------------------------------------------------------------------------------- /src/Main.purs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Prelude 4 | import Effect 5 | import Effect.Class.Console as Console 6 | 7 | main :: Effect Unit 8 | main = do 9 | Console.log "Hello sailor!" 10 | -------------------------------------------------------------------------------- /src/Projects/BaseProject/BaseProject.purs: -------------------------------------------------------------------------------- 1 | module Projects.BaseProject where 2 | 3 | import Prelude (Unit, bind, discard, pure, ($), (/), (<$>)) 4 | 5 | import Web.HTML (window) 6 | import Web.HTML.Window (document) 7 | 8 | import Web.HTML.HTMLDocument (body) 9 | import Web.HTML.HTMLElement (offsetHeight, offsetWidth) 10 | 11 | import Effect 12 | import Data.Maybe (Maybe(..)) 13 | import Data.Tuple (Tuple(..), fst, snd) 14 | import Pure3.Types (Point(..)) 15 | 16 | import Three as Three 17 | import Three.Types (Camera, Object3D, Object3D_, Renderer, Scene, Vector2, Vector3) 18 | import Three.Camera as Camera 19 | import Three.Object3D as Object3D 20 | import Three.OrbitControls as Controls 21 | import Three.Renderer as Renderer 22 | import Three.Scene as Scene 23 | 24 | newtype Project = Project 25 | { objects :: Array Object3D 26 | , vectors :: Array Vector3 } 27 | 28 | getProjectObjects :: Project -> Array Object3D 29 | getProjectObjects (Project r) = r.objects 30 | 31 | getProjectVectors :: Project -> Array Vector3 32 | getProjectVectors (Project r) = r.vectors 33 | 34 | exportProjectObjects :: Project -> Array Object3D_ 35 | exportProjectObjects (Project r) = Object3D.unwrap <$> r.objects 36 | 37 | createVector3FromPoint :: Point -> Effect Vector3 38 | createVector3FromPoint (Point {x, y, z}) = Three.createVector3 x y z 39 | 40 | createVector2FromPoint :: Point -> Effect Vector2 41 | createVector2FromPoint (Point {x, y}) = Three.createVector2 x y 42 | 43 | unsafeGetAspectRatio :: Effect Number 44 | unsafeGetAspectRatio = do 45 | bs <- unsafeGetBodySize 46 | pure ((fst bs) / (snd bs)) 47 | 48 | unsafeGetBodySize :: Effect (Tuple Number Number) 49 | unsafeGetBodySize = do 50 | w <- window 51 | d <- document w 52 | b <- body d 53 | case b of 54 | Just b' -> do 55 | bw <- offsetWidth b' 56 | bh <- offsetHeight b' 57 | pure $ Tuple bw bh 58 | -- TODO: On Nothing, cause exception 59 | Nothing -> do 60 | pure $ Tuple 0.0 0.0 61 | 62 | handleResize :: Camera -> Renderer -> Effect Unit 63 | handleResize c r = do 64 | ar <- unsafeGetAspectRatio 65 | bs <- unsafeGetBodySize 66 | Renderer.setSize (fst bs) (snd bs) r 67 | Camera.setAspect ar c 68 | Camera.updateProjectionMatrix c 69 | 70 | attachAxesHelper :: Scene -> Number -> Effect Unit 71 | attachAxesHelper scene size = do 72 | axesHelper <- Three.createAxesHelper size 73 | Scene.add scene axesHelper 74 | 75 | createRenderer :: Effect Renderer 76 | createRenderer = do 77 | bs <- unsafeGetBodySize 78 | r <- Renderer.createWebGLRenderer 79 | Renderer.setPixelRatio r 80 | Renderer.setSize (fst bs) (snd bs) r 81 | pure r 82 | 83 | createControls :: Camera -> Scene -> Effect Controls.OrbitControls 84 | createControls camera scene = do 85 | controls <- Controls.create camera 86 | Controls.toggle true controls 87 | pure controls 88 | -------------------------------------------------------------------------------- /src/Projects/CircleStuff/CircleStuff.purs: -------------------------------------------------------------------------------- 1 | module Projects.CircleStuff 2 | (create, update) 3 | where 4 | 5 | import Prelude 6 | import Effect 7 | import Data.Array as Array 8 | import Data.Int as Int 9 | import Data.List (List, (..)) 10 | import Data.List as List 11 | import Data.Traversable as Traversable 12 | import Math as Math 13 | 14 | import Pure3.Types (Circle, Point(..)) 15 | import Pure3.Circle as Circle 16 | import Pure3.Point as Point 17 | import Pure3.Interpolate as Interpolate 18 | 19 | import Three as Three 20 | import Three.Types (Object3D) 21 | import Three.Geometry.BoxGeometry as BoxGeometry 22 | import Three.Materials.MeshPhongMaterial as MeshPhongMaterial 23 | import Three.Object3D as Object3D 24 | import Three.Object3D.Light.AmbientLight as AmbientLight 25 | import Three.Object3D.Light.DirectionalLight as DirectionalLight 26 | import Three.Object3D.Mesh as Object3D.Mesh 27 | 28 | import Projects.BaseProject (Project) 29 | import Projects.BaseProject as BaseProject 30 | 31 | radius = 200.0 32 | steps = 80 33 | amplitude = 0.000025 34 | speed = 0.02 35 | distance = 75.0 36 | elements = 8 37 | size = 8.0 38 | boxColor = "#FFD9DC" 39 | directionalColor = "#ff0000" 40 | ambientColor = "#44d9e6" 41 | 42 | centers :: List Point 43 | centers = Point.create 0.0 0.0 <<< (*) distance <<< Int.toNumber <$> -elements..elements 44 | 45 | circles :: List Circle 46 | circles = flip Circle.create radius <$> centers 47 | 48 | points :: List Point 49 | points = List.concat $ Interpolate.interpolate steps <$> circles 50 | 51 | updateBox :: Number -> Point -> Object3D -> Effect Unit 52 | updateBox t (Point {x,y,z}) o = do 53 | let tLoop = Math.cos(t * speed) 54 | -- offset = Math.cos(t * speed) 55 | -- Initital position + Loop * modifier 56 | -- Try to get the inverse of pow z z or another fn that makes the center of the scene more interesting... 57 | waveOutX = x + ((x * tLoop) * ((z * z * amplitude))) 58 | waveOutY = y + ((y * tLoop) * ((z * z * amplitude))) 59 | rot = (x + y + z) * 0.01 + (t * speed) 60 | Object3D.setPosition waveOutX waveOutY z o 61 | -- Ideas, set rotation to one/two axis only 62 | Object3D.setRotation rot rot rot o 63 | 64 | update :: Project -> Number -> Effect Unit 65 | update p t = 66 | Traversable.sequence_ $ Array.zipWith (updateBox t) (Array.fromFoldable points) (BaseProject.getProjectObjects p) 67 | 68 | createBoxes :: List Point -> Effect (Array Object3D) 69 | createBoxes ps = do 70 | boxColor <- Three.createColor boxColor 71 | boxMat <- MeshPhongMaterial.create boxColor true 72 | boxGs <- Traversable.traverse (\_ -> BoxGeometry.create 20.0 80.0 20.0) ps 73 | boxMeshes <- Traversable.traverse (flip Object3D.Mesh.create boxMat) boxGs 74 | -- _ <- sequence_ $ zipWith setPositionByPoint points boxMeshes 75 | pure $ Array.fromFoldable boxMeshes 76 | 77 | setPositionByPoint :: Point -> Object3D -> Effect Unit 78 | -- Maybe make Object3D.setPosition accept a Point || Vector3 so we can avoid unwrapping points here? 79 | setPositionByPoint (Point {x, y, z}) o = Object3D.setPosition x y z o 80 | 81 | create :: Effect Project 82 | create = do 83 | boxes <- createBoxes points 84 | dColor <- Three.createColor directionalColor 85 | dlight <- DirectionalLight.create dColor 1.0 86 | aColor <- Three.createColor ambientColor 87 | alight <- AmbientLight.create aColor 0.75 88 | pure $ BaseProject.Project { objects: Array.concat [boxes <> [dlight, alight]], vectors: [] } 89 | -------------------------------------------------------------------------------- /src/Projects/CircleStuff/Main.purs: -------------------------------------------------------------------------------- 1 | module Projects.CircleStuff.Main where 2 | 3 | import Prelude 4 | import Data.Int as Int 5 | import Data.Traversable as Traversable 6 | import Effect 7 | 8 | import Three as Three 9 | import Three.Types (Camera, Renderer, Scene) 10 | import Three.Camera as Camera 11 | import Three.OrbitControls as Controls 12 | import Three.Renderer as Renderer 13 | import Three.Scene as Scene 14 | import Timeline as Timeline 15 | 16 | import Projects.BaseProject as BaseProject 17 | import Projects.CircleStuff as CircleStuff 18 | 19 | initScene :: Effect Scene 20 | initScene = do 21 | scene <- Scene.create 22 | bgColor <- Three.createColor "#A6FFD4" 23 | Scene.setBackground bgColor scene 24 | Scene.debug scene 25 | pure scene 26 | 27 | updateScene :: ∀ e. BaseProject.Project -> Camera -> Renderer -> Timeline.Frame -> Effect Unit 28 | updateScene s c r t = do 29 | CircleStuff.update s $ Int.toNumber t 30 | 31 | init :: Controls.OrbitControls -> Scene -> BaseProject.Project -> Camera -> Renderer -> Effect Unit 32 | init controls scene project camera renderer = 33 | Timeline.create behaviours 0 34 | where 35 | behaviours = 36 | [ updateScene project camera renderer 37 | -- , \_ -> Controls.update controls 38 | , \_ -> Renderer.render scene camera renderer ] 39 | 40 | initCamera :: Effect Camera 41 | initCamera = do 42 | -- Camera.lookAt doesn't work with controls enabled... 43 | ar <- BaseProject.unsafeGetAspectRatio 44 | camera <- Camera.create 30.0 ar 1.0 10000.0 45 | Camera.setPosition (-571.77) 1856.65 (-799.26) camera 46 | Camera.lookAt 0.0 0.0 0.0 camera 47 | Camera.debug camera 48 | pure camera 49 | 50 | main :: Effect Unit 51 | main = do 52 | scene <- initScene 53 | camera <- initCamera 54 | project <- CircleStuff.create 55 | renderer <- BaseProject.createRenderer 56 | controls <- BaseProject.createControls camera scene 57 | -- BaseProject.attachAxesHelper scene 1000.0 58 | -- This might be an effect on timeline 59 | -- If we pass a frame to scene, we can make it add elements to the scene only 60 | -- if within the frame constrains 61 | Traversable.traverse_ (Scene.add scene) (BaseProject.exportProjectObjects project) 62 | Renderer.mount renderer 63 | -- Event handling 64 | -- Three.onResize $ BaseProject.handleResize camera renderer 65 | init controls scene project camera renderer 66 | 67 | --- Pretty unsafe addEventListener... 68 | --- main :: Effect Unit 69 | --- main = Three.onDOMContentLoaded main' 70 | -------------------------------------------------------------------------------- /src/Projects/Foo/Foo.purs: -------------------------------------------------------------------------------- 1 | module Projects.Foo 2 | (create, update) 3 | where 4 | 5 | import Effect 6 | import Effect.Class.Console as Console 7 | import Prelude 8 | 9 | import Data.Array as Array 10 | import Data.Int as Int 11 | import Data.List (List, (..)) 12 | import Data.List as List 13 | import Data.Traversable as Traversable 14 | import Effect.Class.Console (log) 15 | import Math as Math 16 | import Projects.BaseProject (Project) 17 | import Projects.BaseProject as BaseProject 18 | import Pure3.Circle as Circle 19 | import Pure3.Interpolate as Interpolate 20 | import Pure3.Point as Point 21 | import Pure3.Types (Circle, Point(..)) 22 | import Three as Three 23 | import Three.Geometry.BoxGeometry as BoxGeometry 24 | import Three.Materials.MeshPhongMaterial as MeshPhongMaterial 25 | import Three.Object3D as Object3D 26 | import Three.Object3D.Light.AmbientLight as AmbientLight 27 | import Three.Object3D.Light.DirectionalLight as DirectionalLight 28 | import Three.Object3D.Mesh as Object3D.Mesh 29 | import Three.Types (Object3D) 30 | 31 | radius = 150.0 32 | steps = 120 33 | amplitude = 0.5 34 | speed = 0.015 35 | distance = 150.0 36 | elements = 1 37 | size = 600.0 38 | boxColor = "#FEEBA6" 39 | directionalColor = "#AEDDFF" 40 | ambientColor = "#AEFFD3" 41 | boxSize = 5.0 42 | 43 | -- Add normals 44 | -- helpers = scene.children.filter(isMesh).map(o => new THREE.FaceNormalsHelper( o, 80, 0x00ff00, 1 )); 45 | -- helpers.forEach(hj => scene.add(hj)) 46 | 47 | 48 | points :: List Point 49 | points = Interpolate.interpolate steps circle 50 | where circle = flip Circle.create radius center 51 | center = Point.create 0.0 0.0 0.0 52 | 53 | updateBox :: Number -> Point -> Object3D -> Effect Unit 54 | updateBox t (Point {x,y,z}) o = do 55 | let tLoop = Math.cos(t * speed) 56 | -- waveOutX = x + ((x * tLoop) * ((z * z * 0.1))) 57 | -- TODO Move rad <-> deg to library 58 | rot1 = (Math.atan2 y x) 59 | rot2 = rot1 + (t * speed) 60 | rot3 = Math.sin (y/x * 0.5) 61 | -- scale1 = (y/x) 62 | Object3D.setPosition x y z o 63 | Object3D.setRotation 0.0 0.0 rot1 o 64 | -- _ <- Console.log (show tLoop) 65 | -- Object3D.setScale rot0 rot0 rot0 o 66 | v3 <- Three.createVector3 0.0 1.0 0.0 67 | Object3D.rotateOnAxis v3 rot2 o 68 | 69 | update :: Project -> Number -> Effect Unit 70 | update p t = 71 | Traversable.sequence_ $ Array.zipWith (updateBox t) (Array.fromFoldable points) (BaseProject.getProjectObjects p) 72 | 73 | createBoxes :: List Point -> Effect (Array Object3D) 74 | createBoxes ps = do 75 | boxColor <- Three.createColor boxColor 76 | boxMat <- MeshPhongMaterial.create boxColor true 77 | boxGs <- Traversable.traverse (\_ -> BoxGeometry.create 40.0 boxSize 40.0) ps 78 | boxMeshes <- Traversable.traverse (flip Object3D.Mesh.create boxMat) boxGs 79 | -- _ <- sequence_ $ zipWith setPositionByPoint points boxMeshes 80 | pure $ Array.fromFoldable boxMeshes 81 | 82 | setPositionByPoint :: Point -> Object3D -> Effect Unit 83 | -- Maybe make Object3D.setPosition accept a Point || Vector3 so we can avoid unwrapping points here? 84 | setPositionByPoint (Point {x, y, z}) o = Object3D.setPosition x y z o 85 | 86 | create :: Effect Project 87 | create = do 88 | boxes <- createBoxes points 89 | dColor <- Three.createColor directionalColor 90 | dlight <- DirectionalLight.create dColor 1.0 91 | aColor <- Three.createColor ambientColor 92 | alight <- AmbientLight.create aColor 0.75 93 | pure $ BaseProject.Project { objects: Array.concat [boxes <> [dlight, alight]], vectors: [] } 94 | -------------------------------------------------------------------------------- /src/Projects/Foo/Main.purs: -------------------------------------------------------------------------------- 1 | module Projects.Foo.Main where 2 | 3 | import Prelude 4 | import Data.Int as Int 5 | import Data.Traversable as Traversable 6 | import Effect 7 | 8 | import Three as Three 9 | import Three.Types (Camera, Renderer, Scene) 10 | import Three.Camera as Camera 11 | import Three.OrbitControls as Controls 12 | import Three.Renderer as Renderer 13 | import Three.Scene as Scene 14 | import Timeline as Timeline 15 | 16 | import Projects.BaseProject as BaseProject 17 | import Projects.Foo as Foo 18 | 19 | initScene :: Effect Scene 20 | initScene = do 21 | scene <- Scene.create 22 | bgColor <- Three.createColor "#204066" 23 | Scene.setBackground bgColor scene 24 | Scene.debug scene 25 | pure scene 26 | 27 | updateScene :: ∀ e. BaseProject.Project -> Camera -> Renderer -> Timeline.Frame -> Effect Unit 28 | updateScene s c r t = do 29 | Foo.update s $ Int.toNumber t 30 | 31 | init :: Controls.OrbitControls -> Scene -> BaseProject.Project -> Camera -> Renderer -> Effect Unit 32 | init controls scene project camera renderer = 33 | Timeline.create behaviours 0 34 | where 35 | behaviours = 36 | [ updateScene project camera renderer 37 | -- , \_ -> Controls.update controls 38 | , \_ -> Renderer.render scene camera renderer ] 39 | 40 | initCamera :: Effect Camera 41 | initCamera = do 42 | -- Camera.lookAt doesn't work with controls enabled... 43 | ar <- BaseProject.unsafeGetAspectRatio 44 | camera <- Camera.create 30.0 ar 1.0 10000.0 45 | Camera.setPosition 0.0 0.0 (-800.00) camera 46 | Camera.lookAt 0.0 0.0 0.0 camera 47 | Camera.debug camera 48 | pure camera 49 | 50 | main :: Effect Unit 51 | main = do 52 | -- TODO we can move all this initializatio (camera, scene, renderer to a common file) 53 | scene <- initScene 54 | camera <- initCamera 55 | project <- Foo.create 56 | renderer <- BaseProject.createRenderer 57 | controls <- BaseProject.createControls camera scene 58 | -- BaseProject.attachAxesHelper scene 1000.0 59 | -- This might be an effect on timeline 60 | -- If we pass a frame to scene, we can make it add elements to the scene only 61 | -- if within the frame constrains 62 | Traversable.traverse_ (Scene.add scene) (BaseProject.exportProjectObjects project) 63 | Renderer.mount renderer 64 | -- Event handling 65 | -- Three.onResize $ BaseProject.handleResize camera renderer 66 | init controls scene project camera renderer 67 | 68 | --- Pretty unsafe addEventListener... 69 | --- main :: Effect Unit 70 | --- main = Three.onDOMContentLoaded main' 71 | -------------------------------------------------------------------------------- /src/Projects/FrameBound/FrameBound.purs: -------------------------------------------------------------------------------- 1 | module Projects.FrameBound where 2 | 3 | import Data.Either 4 | import Data.List.Types 5 | import Effect 6 | import Prelude 7 | import Projects.FrameBound.Types 8 | 9 | import Control.Extend ((<<=)) 10 | import Control.Monad.Except (runExcept) 11 | import Data.Array as Array 12 | import Data.Generic.Rep (class Generic) 13 | import Data.Generic.Rep.Show (genericShow) 14 | import Data.List (List, (..), zipWith, (:)) 15 | import Data.List as List 16 | import Data.Maybe (fromMaybe) 17 | import Data.Newtype (class Newtype, unwrap) 18 | import Data.Traversable (maximum, sequence_, traverse, traverse_) 19 | import Effect.Class.Console as Console 20 | import Foreign (ForeignError(..)) 21 | import Foreign.Class (class Decode, class Encode) 22 | import Foreign.Generic (decodeJSON, defaultOptions, genericDecode, genericDecodeJSON, genericEncode) 23 | import Math as Math 24 | import Projects.BaseProject (Project) 25 | import Projects.BaseProject as BaseProject 26 | import Projects.FrameBound.MapLoader as MapLoader 27 | import Projects.FrameBound.Projection as Projection 28 | import Pure3.Point (Point(..)) 29 | import Pure3.Point as Point 30 | import Three as Three 31 | import Three.Extras.Core.Shape as Shape 32 | import Three.Geometry as Geometry 33 | import Three.Geometry.BoxGeometry as BoxGeometry 34 | import Three.Geometry.ExtrudeGeometry as ExtrudeGeometry 35 | import Three.Geometry.PlaneGeometry as PlaneGeometry 36 | import Three.Materials.LineBasicMaterial as LineBasicMaterial 37 | import Three.Materials.MeshPhongMaterial as MeshPhongMaterial 38 | import Three.Math as Three.Math 39 | import Three.Math as ThreeMath 40 | import Three.Object3D (setPosition) 41 | import Three.Object3D as Object3D 42 | import Three.Object3D.Light.AmbientLight as AmbientLight 43 | import Three.Object3D.Light.DirectionalLight as DirectionalLight 44 | import Three.Object3D.Light.HemisphereLight as HemisphereLight 45 | import Three.Object3D.Line as Object3D.Line 46 | import Three.Object3D.Mesh as Object3D.Mesh 47 | import Three.Types (Object3D, Vector2, Vector3) 48 | 49 | scale = 3.0 50 | elements = 50 51 | area = 500.0 52 | boxColor = "#FCCA46" 53 | lineColor = "#666666" 54 | directionalColor = "#ffffff" 55 | dIntensity = 0.3 56 | skyColor = "#ffffff" 57 | groundColor = "#999999" 58 | floorColor = "#A1C181" 59 | 60 | update :: Project -> Number -> Effect Unit 61 | update p t = pure unit 62 | 63 | setPositionByPoint :: Point -> Object3D -> Effect Unit 64 | -- Maybe make Object3D.setPosition accept a Point || Vector3 so we can avoid unwrapping points here? 65 | setPositionByPoint (Point {x, y, z}) o = Object3D.setPosition x y z o 66 | 67 | buildingToMesh :: Array Point -> Effect Object3D 68 | buildingToMesh ps = do 69 | boxColor <- Three.createColor boxColor 70 | vs <- traverse (projectBuildingPoint scale) ps 71 | sh <- Shape.create vs 72 | -- Pass estrusion from config, eventually use LIDAR 73 | ex <- ExtrudeGeometry.create 2.0 sh 74 | mat <- MeshPhongMaterial.create boxColor true 75 | o3d <- Object3D.Mesh.create ex mat 76 | _ <- Object3D.setReceiveShadow true o3d 77 | _ <- Object3D.setCastShadow true o3d 78 | pure o3d 79 | 80 | streetToLine :: Array Point -> Effect Object3D 81 | streetToLine ps = do 82 | lineColor' <- Three.createColor lineColor 83 | vs <- traverse (projectStreetPoint scale) ps 84 | ex <- Geometry.create 85 | _ <- traverse_ (Three.pushVertices ex) vs 86 | mat <- LineBasicMaterial.create lineColor' 87 | o3d <- Object3D.Line.create ex mat 88 | pure o3d 89 | 90 | -- project to desired scale 91 | -- get example working in the js only playground and reproduce here 92 | -- Using 3d points, we do not need to do most of this stuff and just project those into the view 93 | projectBuildingPoint :: Number -> Point -> Effect Vector2 94 | projectBuildingPoint sc (Point {x, y, z}) = 95 | Three.createVector2 x' z' 96 | where x' = x * sc 97 | z' = z * sc 98 | 99 | -- Remove duplication and apply fn to fields (multiply point) 100 | projectStreetPoint :: Number -> Point -> Effect Vector3 101 | projectStreetPoint sc (Point {x, y, z}) = 102 | Three.createVector3 x' y z' 103 | where x' = x * sc 104 | z' = z * sc 105 | 106 | buildingCoordsToPoints :: Building -> Array Point 107 | buildingCoordsToPoints (Building b) = 108 | (\(Coords {x, y, z}) -> Point.create x y z) <$> _.coordinates b 109 | 110 | streetCoordsToPoints :: Street -> Array Point 111 | streetCoordsToPoints (Street s) = 112 | (\(Coords {x, y, z}) -> Point.create x y z) <$> _.coordinates s 113 | 114 | -- Maybe use a general function instead of a named one? 115 | translateToCenter :: Point -> Array Point -> Array Point 116 | translateToCenter center ps = (-) center <$> ps 117 | 118 | createBuildings :: Array Building -> Point -> Effect (Array Object3D) 119 | createBuildings bs center = do 120 | let ps = translateToCenter center <<< buildingCoordsToPoints <$> bs 121 | boxMeshes <- traverse buildingToMesh ps 122 | -- Do proper numbers here instead of magic 123 | sequence_ $ Object3D.setRotation (-90.0 * (Math.pi / 180.0)) 0.0 0.0 <$> boxMeshes 124 | pure $ Array.fromFoldable boxMeshes 125 | 126 | createLines :: Array Street -> Point -> Effect (Array Object3D) 127 | createLines sts center = do 128 | let ps = translateToCenter center <<< streetCoordsToPoints <$> sts 129 | lineMeshes <- traverse streetToLine ps 130 | sequence_ $ Object3D.setRotation 0.0 rot rot <$> lineMeshes 131 | pure $ Array.fromFoldable lineMeshes 132 | where rot = Three.Math.degToRad(180.0) 133 | 134 | createPlane :: Effect Object3D 135 | createPlane = do 136 | -- There is a pattner of doing this over and over again 137 | -- create a color, a geometry, a material, and then a mesh of all that 138 | -- maybe we should create a more abstract function for this 139 | -- like createMesh(MeshConfig) 140 | c <- Three.createColor floorColor 141 | g <- PlaneGeometry.create 25000.0 25000.0 1 1 142 | m <- MeshPhongMaterial.create c true 143 | p <- Object3D.Mesh.create g m 144 | _ <- Object3D.setReceiveShadow true p 145 | _ <- Object3D.setRotation (rx) 0.0 0.0 p 146 | pure p 147 | where rx = ThreeMath.degToRad(-90.0) 148 | 149 | create :: Effect Project 150 | create = do 151 | sColor <- Three.createColor skyColor 152 | gColor <- Three.createColor groundColor 153 | dColor <- Three.createColor directionalColor 154 | dlight <- DirectionalLight.create dColor dIntensity 155 | _ <- setPosition (-1.0) 1.75 1.0 dlight 156 | hlight <- HemisphereLight.create sColor gColor 0.75 157 | -- Json to Building types 158 | buildingsData <- loadBuildingsData 159 | let buildingsData' = doBuildings buildingsData 160 | center = Projection.calculate buildingsData' 161 | boxes <- createBuildings buildingsData' center 162 | 163 | -- Streets 164 | streetsData <- loadStreetsData 165 | let streetsData' = doStreets streetsData 166 | -- Using the center value from the buildings calculation 167 | -- center = Projection.calculate streetsData' 168 | lines <- createLines streetsData' center 169 | -- Plane 170 | plane <- createPlane 171 | pure $ BaseProject.Project { objects: Array.concat [boxes <> lines <> [plane] <> [dlight, hlight]], vectors: [] } 172 | 173 | -- Remove duplication by making these polymorphic and use funtor 174 | doBuildings 175 | :: (Either (NonEmptyList ForeignError) (Array Building)) 176 | -> Array Building 177 | 178 | doBuildings b = case b of 179 | Right f -> f 180 | -- Do not return a fake Building on error, handle upwards 181 | Left _ -> [Building { coordinates: [Coords {x: 0.0, y:0.0, z:0.0}]}] 182 | 183 | doStreets 184 | :: (Either (NonEmptyList ForeignError) (Array Street)) 185 | -> Array Street 186 | 187 | doStreets b = case b of 188 | Right f -> f 189 | -- Do not return a fake Building on error, handle upwards 190 | Left _ -> [Street { coordinates: [Coords {x: 0.0, y:0.0, z:0.0}]}] 191 | 192 | loadBuildingsData 193 | :: Effect 194 | (Either 195 | (NonEmptyList ForeignError) 196 | (Array Building)) 197 | -- 198 | loadBuildingsData = do 199 | buildingsData <- MapLoader.loadBuildings 200 | pure $ runExcept (decodeJSON buildingsData :: _ (Array Building)) 201 | 202 | loadStreetsData 203 | :: Effect 204 | (Either 205 | (NonEmptyList ForeignError) 206 | (Array Street)) 207 | -- 208 | loadStreetsData = do 209 | streetsData <- MapLoader.loadStreets 210 | pure $ runExcept (decodeJSON streetsData :: _ (Array Street)) 211 | -------------------------------------------------------------------------------- /src/Projects/FrameBound/Main.purs: -------------------------------------------------------------------------------- 1 | module Projects.FrameBound.Main where 2 | 3 | import Prelude 4 | 5 | import Effect 6 | import Effect.Class.Console as Console 7 | 8 | import Data.Int (toNumber) 9 | import Data.Traversable (traverse_) 10 | import Projects.BaseProject as BaseProject 11 | import Projects.FrameBound as FrameBound 12 | import Three as Three 13 | import Three.Camera as Camera 14 | import Three.OrbitControls as Controls 15 | import Three.Renderer as Renderer 16 | import Three.Scene as Scene 17 | import Three.Types (Camera, Renderer, Scene) 18 | import Timeline as Timeline 19 | 20 | doT :: Timeline.Frame -> Number 21 | doT n = toNumber n 22 | 23 | backgroundColor = "#e3e0db" 24 | 25 | initScene :: Effect Scene 26 | initScene = do 27 | scene <- Scene.create 28 | bgColor <- Three.createColor backgroundColor 29 | Scene.setBackground bgColor scene 30 | pure scene 31 | 32 | updateScene :: ∀ e. BaseProject.Project -> Camera -> Renderer -> Timeline.Frame -> Effect Unit 33 | updateScene s c r t = do 34 | FrameBound.update s $ toNumber t 35 | 36 | init :: Controls.OrbitControls -> Scene -> BaseProject.Project -> Camera -> Renderer -> Effect Unit 37 | init controls scene project camera renderer = 38 | Timeline.create behaviours 0 39 | where 40 | behaviours = 41 | [ updateScene project camera renderer 42 | , \_ -> Controls.update controls 43 | , \_ -> Renderer.render scene camera renderer ] 44 | 45 | main :: Effect Unit 46 | main = do 47 | ar <- BaseProject.unsafeGetAspectRatio 48 | scene <- initScene 49 | project <- FrameBound.create 50 | camera <- Camera.create 30.0 ar 1.0 1000000.0 51 | -- Renderer 52 | renderer <- BaseProject.createRenderer 53 | _ <- Renderer.setShadowMap true renderer 54 | -- EO Renderer 55 | controls <- BaseProject.createControls camera scene 56 | -- Controls.setAutoRotate true controls 57 | BaseProject.attachAxesHelper scene 10000.0 58 | -- Camera.lookAt 1000.0 0.0 1000.0 camera 59 | Camera.setPosition (-2773.91) 8905.60 (-10409.96) camera 60 | Scene.debug scene 61 | Camera.debug camera 62 | traverse_ (Scene.add scene) (BaseProject.exportProjectObjects project) 63 | Renderer.mount renderer 64 | -- Event handling 65 | -- Three.onResize $ BaseProject.handleResize camera renderer 66 | init controls scene project camera renderer 67 | 68 | --- Pretty unsafe addEventListener... 69 | --- main :: Effect Unit 70 | --- main = Three.onDOMContentLoaded main' 71 | -------------------------------------------------------------------------------- /src/Projects/FrameBound/MapLoader.purs: -------------------------------------------------------------------------------- 1 | module Projects.FrameBound.MapLoader where 2 | 3 | import Effect 4 | 5 | foreign import loadBuildings :: Effect String 6 | foreign import loadStreets :: Effect String 7 | -------------------------------------------------------------------------------- /src/Projects/FrameBound/Projection.purs: -------------------------------------------------------------------------------- 1 | module Projects.FrameBound.Projection where 2 | 3 | import Prelude 4 | 5 | import Effect 6 | import Control.Monad.Except (runExcept) 7 | import Data.Array (concat) 8 | import Data.Either (Either(..)) 9 | import Data.Foldable (maximum, minimum) 10 | import Foreign (ForeignError) 11 | import Foreign.Generic (decodeJSON) 12 | import Data.List.Types (NonEmptyList) 13 | import Data.Maybe (fromMaybe) 14 | import Data.Newtype (unwrap) 15 | import Projects.FrameBound.MapLoader as MapLoader 16 | import Projects.FrameBound.Types (Building(..), Coords(..), unBuilding) 17 | 18 | import Pure3.Point (Point(..)) 19 | import Pure3.Point as Point 20 | 21 | calculateProjection :: Array Building -> Point 22 | calculateProjection buildings = 23 | let buildings' = concat (unBuilding <$> buildings) 24 | xs = _.x <$> buildings' 25 | zs = _.z <$> buildings' 26 | maxX = fromMaybe 0.0 (maximum xs) 27 | maxZ = fromMaybe 0.0 (maximum zs) 28 | minX = fromMaybe 0.0 (minimum xs) 29 | minZ = fromMaybe 0.0 (minimum zs) 30 | center = Point {x: (maxX + minX) / 2.0, y: 0.0, z: (maxZ + minZ) / 2.0} 31 | -- scale = fromMaybe 0.0 $ maxX <> maxZ 32 | in center 33 | 34 | calculate :: ∀ e. Array Building -> Point 35 | calculate bs = calculateProjection bs -------------------------------------------------------------------------------- /src/Projects/FrameBound/Types.purs: -------------------------------------------------------------------------------- 1 | module Projects.FrameBound.Types where 2 | 3 | import Prelude 4 | 5 | import Foreign.Class (class Decode) 6 | import Foreign.Generic (defaultOptions, genericDecode) 7 | 8 | import Data.Generic.Rep (class Generic) 9 | import Data.Generic.Rep.Show (genericShow) 10 | import Data.Newtype (class Newtype) 11 | 12 | opts = defaultOptions { unwrapSingleConstructors = true } 13 | 14 | newtype Coords = Coords { x :: Number, y :: Number, z :: Number } 15 | derive instance newtypeCoords :: Newtype Coords _ 16 | derive instance genCoords :: Generic Coords _ 17 | instance decCoords :: Decode Coords where 18 | decode = genericDecode opts 19 | instance showCoords :: Show Coords where 20 | show = genericShow 21 | 22 | newtype Building = Building { coordinates :: Array Coords } 23 | derive instance newtypeBuilding :: Newtype Building _ 24 | derive instance genBuilding :: Generic Building _ 25 | instance decBuilding :: Decode Building where 26 | decode = genericDecode opts 27 | instance showBuilding :: Show Building where 28 | show = genericShow 29 | 30 | newtype Street = Street { coordinates :: Array Coords } 31 | derive instance newtypeStreet :: Newtype Street _ 32 | derive instance genStreet :: Generic Street _ 33 | instance decStreet :: Decode Street where 34 | decode = genericDecode opts 35 | instance showStreet :: Show Street where 36 | show = genericShow 37 | 38 | 39 | unBuilding :: Building -> Array { x :: Number, y :: Number, z :: Number } 40 | unBuilding (Building {coordinates}) = (\(Coords c) -> c) <$> coordinates -------------------------------------------------------------------------------- /src/Projects/Sealike/Main.purs: -------------------------------------------------------------------------------- 1 | module Projects.Sealike.Main where 2 | 3 | import Prelude 4 | import Effect 5 | import Effect.Class.Console as Console 6 | import Data.Int (toNumber) 7 | import Data.Traversable (traverse_) 8 | 9 | import Three as Three 10 | import Three.Camera as Camera 11 | import Three.OrbitControls as Controls 12 | import Three.Renderer as Renderer 13 | import Three.Scene as Scene 14 | import Three.Types (Camera, Renderer, Scene) 15 | import Timeline as Timeline 16 | 17 | import Projects.BaseProject as BaseProject 18 | import Projects.Sealike as Sealike 19 | 20 | initScene :: Effect Scene 21 | initScene = do 22 | scene <- Scene.create 23 | bgColor <- Three.createColor "#000000" 24 | Scene.setBackground bgColor scene 25 | pure scene 26 | 27 | updateScene :: BaseProject.Project -> Camera -> Renderer -> Timeline.Frame -> Effect Unit 28 | updateScene s c r t = do 29 | Sealike.update s $ toNumber t 30 | 31 | init :: Controls.OrbitControls -> Scene -> BaseProject.Project -> Camera -> Renderer -> Effect Unit 32 | init controls scene project camera renderer = 33 | Timeline.create behaviours 0 34 | where 35 | behaviours = 36 | [ updateScene project camera renderer 37 | , \_ -> Controls.update controls 38 | , \_ -> Renderer.render scene camera renderer ] 39 | 40 | main :: Effect Unit 41 | main = do 42 | ar <- BaseProject.unsafeGetAspectRatio 43 | scene <- initScene 44 | project <- Sealike.create 45 | camera <- Camera.create 30.0 ar 1.0 10000.0 46 | renderer <- BaseProject.createRenderer 47 | controls <- BaseProject.createControls camera scene 48 | -- BaseProject.attachAxesHelper scene 100.0 49 | Camera.setPosition (-1215.27) 285.24 (153.98) camera 50 | Scene.debug scene 51 | Camera.debug camera 52 | traverse_ (Scene.add scene) (BaseProject.exportProjectObjects project) 53 | Renderer.mount renderer 54 | -- Event handling 55 | -- Three.onResize $ BaseProject.handleResize camera renderer 56 | init controls scene project camera renderer 57 | -------------------------------------------------------------------------------- /src/Projects/Sealike/Materials/SeaMaterial.js: -------------------------------------------------------------------------------- 1 | var Vector2 = require("three").Vector2 2 | var ShaderMaterial = require("three").ShaderMaterial 3 | 4 | exports.createSeaMaterial = function(/*cfg*/) { 5 | 6 | var vertexShader = 7 | "varying vec4 vertexColor;" + 8 | "void main() {" + 9 | "gl_PointSize = 2.0;" + 10 | "gl_Position = projectionMatrix *" + 11 | " modelViewMatrix *" + 12 | " vec4(position,1.0);" + 13 | "vertexColor = vec4(position,1.0);" + 14 | " }" 15 | 16 | var fragmentShader = 17 | " varying lowp vec4 vertexColor;" + 18 | " uniform vec2 u_resolution;" + 19 | " uniform vec2 u_mouse;" + 20 | " uniform float u_time;" + 21 | " void main(){" + 22 | " gl_FragColor = " + 23 | " vec4( " + 24 | " ((1200.0 + vertexColor.z) * 0.0025 + 0.25) /* * 255.0 / 255.0 */, " + 25 | " ((1200.0 + vertexColor.z) * 0.0025 + 0.25) /* * 208.0 / 255.0 */, " + 26 | " ((1200.0 + vertexColor.z) * 0.0025 + 0.25) /* * 194.0 / 255.0 */, " + 27 | " 1);" + 28 | " }" 29 | 30 | var uniforms = { 31 | u_time: { type: 'f', value: 0 }, 32 | u_resolution: { type: 'v2', value: new Vector2() }, 33 | u_mouse: { type: 'v2', value: new Vector2() } 34 | } 35 | 36 | var shaderMaterial = new ShaderMaterial({ 37 | uniforms: uniforms, 38 | vertexShader: vertexShader, 39 | fragmentShader: fragmentShader 40 | }) 41 | 42 | return shaderMaterial 43 | } 44 | -------------------------------------------------------------------------------- /src/Projects/Sealike/Materials/SeaMaterial.purs: -------------------------------------------------------------------------------- 1 | module Projects.Sealike.SeaMaterial where 2 | 3 | import Effect 4 | import Three.Types (Material) 5 | 6 | foreign import createSeaMaterial :: Effect Material 7 | -------------------------------------------------------------------------------- /src/Projects/Sealike/Sealike.purs: -------------------------------------------------------------------------------- 1 | module Projects.Sealike 2 | (create, update) 3 | where 4 | 5 | import Prelude 6 | import Effect 7 | import Data.Array as Array 8 | import Data.List (List) 9 | import Data.Traversable (traverse, traverse_) 10 | import Math as Math 11 | import Projects.BaseProject as BaseProject 12 | import Projects.Sealike.SeaMaterial (createSeaMaterial) 13 | import Pure3.Interpolate as Interpolate 14 | import Pure3.Line as Line 15 | import Pure3.Point as Point 16 | import Pure3.Square as Square 17 | import Pure3.Transform as Transform 18 | import Pure3.Types (Point) 19 | import Three as Three 20 | import Three.Object3D as Object3D 21 | import Three.Object3D.Points as Object3D.Points 22 | import Three.Types (Vector3) 23 | 24 | size = 3000.0 25 | steps = 60 26 | freq = 0.003 27 | speed = 0.025 28 | amplitude = 40.0 29 | 30 | center :: Point 31 | center = Point.create (-size * 0.25) 0.0 (-size * 0.25) 32 | 33 | a = Point.create 0.0 0.0 0.0 34 | b = Point.create size 0.0 0.0 35 | c = Point.create 0.0 0.0 size 36 | d = Point.create size 0.0 size 37 | sq1 = Square.createFromLines (Line.create a b) (Line.create c d) 38 | sq1c = Transform.translateSquare sq1 center 39 | 40 | sq1Points :: List Point 41 | sq1Points = Interpolate.interpolate steps sq1c 42 | 43 | updateVector :: Number -> Vector3 -> Effect Unit 44 | updateVector t v = do 45 | vpos <- Three.getVector3Position v 46 | let delta = (vpos.x + vpos.z) * freq 47 | waveY = (Math.cos (delta + speed * t)) * amplitude 48 | wave2 = (Math.cos (vpos.z + speed * t)) * amplitude * 0.4 49 | Three.updateVector3Position vpos.x ( waveY + wave2) vpos.z v 50 | 51 | update :: BaseProject.Project -> Number -> Effect Unit 52 | update p t = 53 | let vs = BaseProject.getProjectVectors p 54 | g = BaseProject.getProjectObjects p 55 | in traverse_ (updateVector t) vs *> traverse_ Object3D.forceVerticesUpdate g 56 | 57 | create :: Effect BaseProject.Project 58 | create = do 59 | -- here we are mutating g in JS... then using the reference in create g 60 | -- should we express that effect somehow? 61 | g <- Three.createGeometry 62 | m <- createSeaMaterial 63 | vs <- traverse BaseProject.createVector3FromPoint sq1Points 64 | _ <- traverse_ (Three.pushVertices g) vs 65 | p <- Object3D.Points.create g m 66 | pure $ BaseProject.Project { objects: [p], vectors: Array.fromFoldable vs } 67 | -------------------------------------------------------------------------------- /src/Projects/Timeline/Timeline.js: -------------------------------------------------------------------------------- 1 | exports.setAnimationFrameBehaviour = function(fn) { 2 | return function() { 3 | window.requestAnimationFrame(fn) 4 | } 5 | } 6 | 7 | // TODO: This should always return an Int 8 | exports.unsafeGetGlobalValue = function(key) { 9 | return function() { 10 | return window[key] || 0; 11 | } 12 | } 13 | 14 | exports.unsafeSetGlobalValue = function(key) { 15 | return function(value) { 16 | return function() { 17 | return window[key] = 0; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Projects/Timeline/Timeline.purs: -------------------------------------------------------------------------------- 1 | module Timeline 2 | ( create 3 | , Frame 4 | ) where 5 | 6 | import Prelude 7 | 8 | import Effect 9 | import Effect.Class.Console as Console 10 | import Data.Traversable (traverse_) 11 | -- This doesn't scale, we cannot use it from the outside without passing the type 12 | -- Maybe we do this fully polymorphic on efects? 13 | 14 | foreign import setAnimationFrameBehaviour :: Effect Unit -> Effect Unit 15 | foreign import unsafeGetGlobalValue :: String -> Effect Int 16 | 17 | type Frame = Int 18 | 19 | runBehaviours :: Frame -> Array (Frame -> Effect Unit) -> Effect Unit 20 | runBehaviours fr bs = traverse_ (\b -> b fr) bs 21 | 22 | -- nextFrame :: ∀ e. Frame -> Eff (console :: CONSOLE | e) Frame 23 | -- nextFrame t = do 24 | -- val <- unsafeGetGlobalValue "cFrame" 25 | -- -- log $ "Current increment: " <> show val 26 | -- pure $ val 27 | 28 | nextFrame :: ∀ e. Frame -> Effect Frame 29 | nextFrame t = pure $ t + 1 30 | 31 | -- Lift an effect to a row of effects 32 | -- Export increment frame function to be used from the outside world 33 | create :: ∀ e 34 | . Array (Frame -> Effect Unit) 35 | -> Frame 36 | -> Effect Unit 37 | create bs fr = do 38 | nfr <- nextFrame fr 39 | -- log $ "Current frame : " <> show nfr 40 | -- unsafeCoerceEff forces a closed eff row into an open one 41 | -- Moving to Effect, not needed anymore 42 | runBehaviours nfr bs 43 | setAnimationFrameBehaviour $ create bs nfr 44 | -------------------------------------------------------------------------------- /test/Main.purs: -------------------------------------------------------------------------------- 1 | module Test.Main where 2 | 3 | import Prelude 4 | import Effect 5 | import Effect.Class.Console as Console 6 | 7 | main :: Effect Unit 8 | main = do 9 | Console.log "You should add some tests." 10 | --------------------------------------------------------------------------------