├── examples ├── raster │ ├── raster.pgw │ ├── raster.png │ ├── raster.tif │ ├── raster.prj │ └── readRaster.js ├── wms │ ├── static │ │ └── favicon.ico │ ├── README.md │ ├── main.js │ ├── templates │ │ └── index.html │ └── actions.js ├── geometry │ ├── voronoiDigram.js │ └── delaunayTriangle.js ├── README.md ├── style │ └── gradient.js ├── setup.js ├── update.js ├── centroids-layer.js └── process │ └── buffer.js ├── .travis.yml ├── .gitignore ├── lib ├── ringo-core.jar └── ringo-modules.jar ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── src ├── main │ ├── resources │ │ ├── Messages.properties │ │ └── org │ │ │ └── geoscript │ │ │ └── js │ │ │ └── lib │ │ │ ├── geoscript │ │ │ ├── io │ │ │ │ ├── json.js │ │ │ │ └── wkt.js │ │ │ ├── filter │ │ │ │ ├── util.js │ │ │ │ └── expression.js │ │ │ ├── workspace │ │ │ │ ├── util.js │ │ │ │ ├── memory.js │ │ │ │ ├── geobuf.js │ │ │ │ ├── flatgeobuf.js │ │ │ │ ├── geopackage.js │ │ │ │ ├── spatialite.js │ │ │ │ └── h2.js │ │ │ ├── factory.js │ │ │ ├── style │ │ │ │ ├── util.js │ │ │ │ └── brush.js │ │ │ ├── raster.js │ │ │ ├── index.js │ │ │ ├── object.js │ │ │ ├── proj.js │ │ │ ├── registry.js │ │ │ ├── process.js │ │ │ ├── workspace.js │ │ │ ├── filter.js │ │ │ └── geom │ │ │ │ └── io │ │ │ │ └── json.js │ │ │ └── geoscript.js │ ├── java │ │ └── org │ │ │ └── geoscript │ │ │ └── js │ │ │ ├── index │ │ │ ├── SpatialIndex.java │ │ │ ├── STRtree.java │ │ │ ├── Module.java │ │ │ └── Quadtree.java │ │ │ ├── GeoScriptModules.java │ │ │ ├── process │ │ │ ├── MetaProcess.java │ │ │ └── Module.java │ │ │ ├── proj │ │ │ └── Module.java │ │ │ ├── raster │ │ │ └── Module.java │ │ │ ├── filter │ │ │ └── Module.java │ │ │ ├── feature │ │ │ ├── Module.java │ │ │ └── Iterator.java │ │ │ └── geom │ │ │ ├── Module.java │ │ │ └── GeometryWrapper.java │ └── assembly │ │ └── all.xml └── test │ ├── resources │ └── org │ │ └── geoscript │ │ └── js │ │ └── tests │ │ ├── data │ │ ├── h2.zip │ │ ├── geopkg.zip │ │ ├── raster.tif │ │ └── states.shp.zip │ │ ├── geoscript │ │ ├── test_io.js │ │ ├── geom │ │ │ ├── test_io.js │ │ │ ├── test_collection.js │ │ │ ├── test_circularstring.js │ │ │ └── io │ │ │ │ ├── test_wkt.js │ │ │ │ └── test_json.js │ │ ├── test_raster.js │ │ ├── test_feature.js │ │ ├── test_style.js │ │ ├── workspace │ │ │ ├── test_memory.js │ │ │ ├── test_postgis.js │ │ │ ├── test_h2.js │ │ │ ├── test_geopackage.js │ │ │ ├── test_geobuf.js │ │ │ ├── test_flatgeobuf.js │ │ │ └── test_directory.js │ │ ├── layer │ │ │ ├── test_shapefile.js │ │ │ ├── test_h2.js │ │ │ └── test_memory.js │ │ ├── filter │ │ │ ├── test_expression.js │ │ │ └── test_filter.js │ │ ├── test_map.js │ │ ├── style │ │ │ ├── test_fill.js │ │ │ ├── test_stroke.js │ │ │ ├── test_symbolizer.js │ │ │ └── test_color.js │ │ ├── raster │ │ │ └── test_format.js │ │ ├── test_workspace.js │ │ ├── test_index.js │ │ ├── test_proj.js │ │ ├── test_filter.js │ │ └── test_layer.js │ │ ├── all.js │ │ ├── test_geoscript.js │ │ └── admin.js │ └── java │ └── org │ └── geoscript │ └── js │ └── RingoTest.java ├── doc ├── api │ ├── style │ │ ├── brush.rst │ │ ├── color.rst │ │ ├── symbolizer.rst │ │ ├── style.rst │ │ ├── icon.rst │ │ ├── fill.rst │ │ ├── stroke.rst │ │ └── label.rst │ ├── object.rst │ ├── filter.rst │ ├── filter │ │ ├── expression.rst │ │ └── filter.rst │ ├── proj.rst │ ├── feature.rst │ ├── index.rst │ ├── style.rst │ ├── workspace.rst │ ├── index │ │ ├── strtree.rst │ │ └── quadtree.rst │ ├── geom │ │ ├── geometrycollection.rst │ │ ├── polygon.rst │ │ ├── point.rst │ │ ├── multipoint.rst │ │ ├── multilinestring.rst │ │ ├── circularstring.rst │ │ ├── multipolygon.rst │ │ ├── compoundcurve.rst │ │ └── linestring.rst │ ├── geom.rst │ ├── io │ │ ├── wkt.rst │ │ └── json.rst │ ├── map.rst │ ├── proj │ │ └── projection.rst │ ├── workspace │ │ ├── memory.rst │ │ ├── workspace.rst │ │ ├── h2.rst │ │ ├── directory.rst │ │ ├── geobuf.rst │ │ ├── geopackage.rst │ │ ├── flatgeobuf.rst │ │ ├── mysql.rst │ │ └── postgis.rst │ ├── feature │ │ ├── schema.rst │ │ ├── field.rst │ │ └── feature.rst │ └── types.rst ├── index.rst ├── download.rst └── quickstart.rst ├── package.json ├── bin ├── geoscript-js.cmd ├── geoscript-js-dev └── geoscript-js ├── .github └── workflows │ └── build.yml ├── license.txt └── README.md /examples/raster/raster.pgw: -------------------------------------------------------------------------------- 1 | 0.4 2 | 0.0 3 | 0.0 4 | -0.4 5 | -179.8 6 | 89.8 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | 3 | language: java 4 | 5 | jdk: 6 | - oraclejdk8 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | .settings/ 4 | /target/ 5 | /data/ 6 | .idea 7 | *.iml -------------------------------------------------------------------------------- /lib/ringo-core.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoscript/geoscript-js/HEAD/lib/ringo-core.jar -------------------------------------------------------------------------------- /lib/ringo-modules.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoscript/geoscript-js/HEAD/lib/ringo-modules.jar -------------------------------------------------------------------------------- /examples/raster/raster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoscript/geoscript-js/HEAD/examples/raster/raster.png -------------------------------------------------------------------------------- /examples/raster/raster.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoscript/geoscript-js/HEAD/examples/raster/raster.tif -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoscript/geoscript-js/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /examples/wms/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoscript/geoscript-js/HEAD/examples/wms/static/favicon.ico -------------------------------------------------------------------------------- /src/main/resources/Messages.properties: -------------------------------------------------------------------------------- 1 | fileNotFound = File not found: {0} 2 | troubleReadingFile = Unable to read file: {0} 3 | -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/data/h2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoscript/geoscript-js/HEAD/src/test/resources/org/geoscript/js/tests/data/h2.zip -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/data/geopkg.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoscript/geoscript-js/HEAD/src/test/resources/org/geoscript/js/tests/data/geopkg.zip -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/data/raster.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoscript/geoscript-js/HEAD/src/test/resources/org/geoscript/js/tests/data/raster.tif -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/data/states.shp.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoscript/geoscript-js/HEAD/src/test/resources/org/geoscript/js/tests/data/states.shp.zip -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/test_io.js: -------------------------------------------------------------------------------- 1 | exports["test: JSON"] = require("./io/test_json"); 2 | 3 | if (require.main == module.id) { 4 | system.exit(require("test").run(exports)); 5 | } 6 | -------------------------------------------------------------------------------- /doc/api/style/brush.rst: -------------------------------------------------------------------------------- 1 | :class:`style.Brush` 2 | ==================== 3 | 4 | .. class:: style.Brush 5 | 6 | Instances of the brush base class are not created directly. 7 | See the constructor details for one of the brush subclasses. 8 | 9 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /src/main/resources/org/geoscript/js/lib/geoscript/io/json.js: -------------------------------------------------------------------------------- 1 | require("../geom"); // initialize Geometry prototypes before wrapping 2 | 3 | var json = Packages.org.geoscript.js.io.JSON.init(this); 4 | 5 | exports.read = json.read; 6 | exports.write = json.write; -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/all.js: -------------------------------------------------------------------------------- 1 | var system = require("system"); 2 | exports["test: geoscript"] = require("./test_geoscript"); 3 | 4 | if (require.main == module || require.main == module.id) { 5 | system.exit(require("test").run(exports)); 6 | } -------------------------------------------------------------------------------- /doc/api/object.rst: -------------------------------------------------------------------------------- 1 | :class:`GeoObject` 2 | ================== 3 | 4 | Properties 5 | ---------- 6 | 7 | .. attribute:: GeoObject.json 8 | 9 | ``String`` 10 | The JSON representation of the object. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "geoscript", 3 | "description": "Library for geospatial data access, manipulation, and rendering.", 4 | "author": "Tim Schaub", 5 | "dependencies": [], 6 | "contributors": [], 7 | "jars": "jars", 8 | "main": "lib/geoscript" 9 | } -------------------------------------------------------------------------------- /examples/geometry/voronoiDigram.js: -------------------------------------------------------------------------------- 1 | var geom = require('geoscript/geom'); 2 | var viewer = require('geoscript/viewer'); 3 | 4 | var polygon = geom.Point([1,1]).buffer(50); 5 | var points = polygon.randomPoints(20); 6 | var diagram = points.createVoronoiDiagram(); 7 | viewer.draw(diagram); -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/geom/test_io.js: -------------------------------------------------------------------------------- 1 | 2 | exports["test: json"] = require("./io/test_json"); 3 | 4 | exports["test: wkt"] = require("./io/test_wkt"); 5 | 6 | if (require.main == module.id) { 7 | system.exit(require("test").run(exports)); 8 | } 9 | -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/test_raster.js: -------------------------------------------------------------------------------- 1 | exports["test: Format"] = require("./raster/test_format"); 2 | exports["test: Raster"] = require("./raster/test_raster"); 3 | 4 | if (require.main == module.id) { 5 | system.exit(require("test").run(exports)); 6 | } 7 | -------------------------------------------------------------------------------- /examples/geometry/delaunayTriangle.js: -------------------------------------------------------------------------------- 1 | var geom = require('geoscript/geom'); 2 | var viewer = require('geoscript/viewer'); 3 | 4 | var polygon = geom.Point([1,1]).buffer(50); 5 | var points = polygon.randomPoints(100); 6 | var triangles = points.createDelaunayTriangles(true); 7 | viewer.draw(triangles); -------------------------------------------------------------------------------- /examples/raster/raster.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["WGS 84", 2 | DATUM["World Geodetic System 1984", 3 | SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], 4 | AUTHORITY["EPSG","6326"]], 5 | PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], 6 | UNIT["degree", 0.017453292519943295], 7 | AXIS["Geodetic longitude", EAST], 8 | AXIS["Geodetic latitude", NORTH], 9 | AUTHORITY["EPSG","4326"]] -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/test_feature.js: -------------------------------------------------------------------------------- 1 | exports["test: Feature"] = require("./feature/test_feature"); 2 | exports["test: Field"] = require("./feature/test_field"); 3 | exports["test: Schema"] = require("./feature/test_schema"); 4 | exports["test: Collection"] = require("./feature/test_collection"); 5 | 6 | if (require.main == module.id) { 7 | system.exit(require("test").run(exports)); 8 | } 9 | -------------------------------------------------------------------------------- /doc/api/filter.rst: -------------------------------------------------------------------------------- 1 | The filter module 2 | ================= 3 | 4 | The :doc:`filter ` module provides a constructor for Filter objects. 5 | 6 | .. code-block:: javascript 7 | 8 | >> var filter = require("geoscript/filter"); 9 | 10 | 11 | Constructors 12 | ------------ 13 | 14 | .. toctree:: 15 | :glob: 16 | :maxdepth: 1 17 | 18 | filter/* 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /doc/api/filter/expression.rst: -------------------------------------------------------------------------------- 1 | :class:`filter.Expression` 2 | ========================== 3 | 4 | .. class:: filter.Expression(cql) 5 | 6 | :arg text: ``String`` The expression text. 7 | 8 | Expression class for generating values from features. 9 | 10 | 11 | Properties 12 | ---------- 13 | 14 | .. attribute:: Expression.literal 15 | 16 | ``Boolean`` 17 | This expression is just a literal value. 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /doc/api/proj.rst: -------------------------------------------------------------------------------- 1 | The proj module 2 | =============== 3 | 4 | The :doc:`proj ` module exports a Projection constructor and methods for 5 | transforming geometries between coordinate reference systems. 6 | 7 | .. code-block:: javascript 8 | 9 | >> var proj = require("geoscript/proj"); 10 | 11 | 12 | Constructors 13 | ------------ 14 | 15 | .. toctree:: 16 | :glob: 17 | :maxdepth: 1 18 | 19 | proj/* 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/raster/readRaster.js: -------------------------------------------------------------------------------- 1 | var raster = require('geoscript/raster'); 2 | var proj = require('geoscript/proj'); 3 | 4 | var format = new raster.Format({source: 'raster.tif'}); 5 | print("Format names: " + format.names); 6 | var tif = format.read({}); 7 | print("Raster: " + tif); 8 | print("Name: " + tif.name); 9 | print("Projection: " + tif.proj); 10 | print("Size: " + tif.size); 11 | 12 | var pngFormat = new raster.Format({source: 'raster.png'}); 13 | pngFormat.write(tif, {}); -------------------------------------------------------------------------------- /src/main/resources/org/geoscript/js/lib/geoscript/filter/util.js: -------------------------------------------------------------------------------- 1 | var Registry = require("../registry").Registry; 2 | 3 | var registry = new Registry(); 4 | 5 | /** private: method[create] 6 | * :arg config: ``Object`` Configuration object. 7 | * :returns: :class:`filter.Filter` 8 | * 9 | * Create a filter given a configuration object. 10 | */ 11 | exports.create = registry.create; 12 | 13 | /** private: method[register] */ 14 | exports.register = registry.register; 15 | -------------------------------------------------------------------------------- /doc/api/feature.rst: -------------------------------------------------------------------------------- 1 | The feature module 2 | ================== 3 | 4 | The :doc:`feature ` module provides a provides constructors for 5 | features, feature collections, and feature schema. 6 | 7 | .. code-block:: javascript 8 | 9 | >> var feature = require("geoscript/feature"); 10 | 11 | 12 | Constructors 13 | ------------ 14 | 15 | .. toctree:: 16 | :glob: 17 | :maxdepth: 1 18 | 19 | feature/* 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /doc/api/index.rst: -------------------------------------------------------------------------------- 1 | .. _api: 2 | 3 | API Reference 4 | ============= 5 | 6 | Examples and reference documents for geoscript.js. 7 | 8 | Modules 9 | ------- 10 | 11 | .. toctree:: 12 | :glob: 13 | :maxdepth: 1 14 | 15 | geom 16 | feature 17 | filter 18 | proj 19 | index/* 20 | layer 21 | workspace 22 | raster 23 | style 24 | map 25 | process 26 | io/* 27 | 28 | 29 | .. toctree:: 30 | :hidden: 31 | 32 | object 33 | types -------------------------------------------------------------------------------- /doc/api/style/color.rst: -------------------------------------------------------------------------------- 1 | :class:`style.Color` 2 | ==================== 3 | 4 | .. class:: style.Color 5 | 6 | A brush that renders with a solid color. 7 | 8 | Properties 9 | ---------- 10 | 11 | .. attribute:: Color.value 12 | 13 | ``String`` 14 | The hex color value. When setting the value, a CSS color name may be 15 | used. See http://www.w3schools.com/css/css_colornames.asp for supported 16 | color names. 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /doc/api/style.rst: -------------------------------------------------------------------------------- 1 | The style module 2 | ================ 3 | 4 | The :doc:`style 14 | 15 | 16 |
17 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /doc/api/geom/multipolygon.rst: -------------------------------------------------------------------------------- 1 | :class:`geom.MultiPolygon` 2 | ========================== 3 | 4 | .. class:: geom.MultiPolygon(coords) 5 | 6 | :arg Array coords: Coordinates array. 7 | 8 | Create a new multipolygon geometry. The items in the coords array 9 | may be polygon coordinates or :class:`geom.Polygon` objects. 10 | 11 | 12 | Example Use 13 | ----------- 14 | 15 | Sample code to new multi-polygon: 16 | 17 | .. code-block:: javascript 18 | 19 | >> var {Polygon, MultiPolygon} = require("geoscript/geom"); 20 | >> var p1 = Polygon([ 21 | .. [[-180, -90], [-180, 90], [180, 90], [180, -90], [-180, -90]], 22 | .. [[-90, -45], [-90, 45], [90, 45], [90, -45], [-90, -45]] 23 | .. ]); 24 | >> var p2 = Polygon([ 25 | .. [[-60, -30], [-60, 30], [60, 30], [60, -30], [-60, -30]] 26 | .. ]); 27 | >> var mp = MultiPolygon([p1, p2]); 28 | 29 | Alternate method to create the same geometry as above: 30 | 31 | .. code-block:: javascript 32 | 33 | >> var mp = MultiPolygon([ 34 | .. [ 35 | .. [[-180, -90], [-180, 90], [180, 90], [180, -90], [-180, -90]], 36 | .. [[-90, -45], [-90, 45], [90, 45], [90, -45], [-90, -45]] 37 | .. ], [ 38 | .. [[-60, -30], [-60, 30], [60, 30], [60, -30], [-60, -30]] 39 | .. ] 40 | .. ]); 41 | 42 | 43 | Properties 44 | ---------- 45 | 46 | 47 | Multi-polygon geometries have the properties common to all 48 | :class:`geom.GeometryCollection` subclasses. 49 | 50 | 51 | Methods 52 | ------- 53 | 54 | Multi-polygon geometries have the methods common to all 55 | :class:`geom.GeometryCollection` subclasses. 56 | 57 | -------------------------------------------------------------------------------- /doc/api/proj/projection.rst: -------------------------------------------------------------------------------- 1 | :class:`proj.Projection` 2 | ======================== 3 | 4 | .. class:: proj.Projection(id) 5 | 6 | :arg id: ``String`` Coordinate reference system identifier or 7 | well-known text for the projection. 8 | 9 | Create a new projection object. 10 | 11 | Example Use 12 | ----------- 13 | 14 | Sample code to create a new projection object: 15 | 16 | .. code-block:: javascript 17 | 18 | >> var Projection = require("geoscript/proj").Projection; 19 | >> var wgs84 = Projection("EPSG:4326") 20 | >> wgs84 21 | 22 | 23 | >> wgs84.wkt 24 | GEOGCS["WGS 84", 25 | DATUM["World Geodetic System 1984", 26 | SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], 27 | AUTHORITY["EPSG","6326"]], 28 | PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], 29 | UNIT["degree", 0.017453292519943295], 30 | AXIS["Geodetic longitude", EAST], 31 | AXIS["Geodetic latitude", NORTH], 32 | AUTHORITY["EPSG","4326"]] 33 | 34 | 35 | Properties 36 | ---------- 37 | 38 | .. attribute:: Projection.id 39 | 40 | ``String`` 41 | The coordinate reference system identifier. 42 | 43 | .. attribute:: Projection.wkt 44 | 45 | ``String`` 46 | The well-known text representation of the coordinate reference system. 47 | 48 | 49 | Methods 50 | ------- 51 | 52 | .. function:: Projection.equals 53 | 54 | :arg projection: :class:`proj.Projection` 55 | :returns: ``Boolean`` The two projections are equivalent. 56 | 57 | Determine if this projection is equivalent to the given projection. 58 | -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/workspace/test_flatgeobuf.js: -------------------------------------------------------------------------------- 1 | var ASSERT = require("assert"); 2 | var WORKSPACE = require("geoscript/workspace"); 3 | var LAYER = require("geoscript/layer"); 4 | var GEOM = require("geoscript/geom"); 5 | var FS = require("fs"); 6 | 7 | exports["test: constructor"] = function() { 8 | 9 | var Files = Packages.java.nio.file.Files; 10 | var file = Files.createTempDirectory("flatgeobuf").toFile().getAbsolutePath(); 11 | var geobuf = new WORKSPACE.Flatgeobuf({file: file}); 12 | 13 | ASSERT.ok(geobuf instanceof WORKSPACE.Workspace, "instanceof Workspace"); 14 | ASSERT.ok(geobuf instanceof WORKSPACE.Flatgeobuf, "instanceof Flatgeobuf"); 15 | 16 | geobuf.close(); 17 | 18 | }; 19 | 20 | exports["test: create"] = function() { 21 | 22 | var Files = Packages.java.nio.file.Files; 23 | var file = Files.createTempDirectory("flatgeobuf").toFile().getAbsolutePath(); 24 | var geobuf = new WORKSPACE.Flatgeobuf({file: file}); 25 | 26 | var layer = new LAYER.Layer({ 27 | name: "places", 28 | fields: [{ 29 | name: "name", type: "String" 30 | }, { 31 | name: "geom", type: "Point" 32 | }] 33 | }); 34 | var geobufLayer = geobuf.add(layer); 35 | 36 | geobufLayer.add({name: "San Francisco", geom: new GEOM.Point([-122.42, 37.78])}); 37 | geobufLayer.add({name: "New York", geom: new GEOM.Point([-73.58, 40.47])}); 38 | ASSERT.ok(geobufLayer.count == 2); 39 | 40 | geobuf.close(); 41 | }; 42 | 43 | if (require.main == module.id) { 44 | system.exit(require("test").run(exports)); 45 | } 46 | -------------------------------------------------------------------------------- /doc/api/geom/compoundcurve.rst: -------------------------------------------------------------------------------- 1 | :class:`geom.CompoundCurve` 2 | =========================== 3 | 4 | .. class:: geom.CompoundCurve(lineStrings) 5 | 6 | :arg Array lineStrings: An array of LineStrings or CircularStrings. 7 | 8 | Create a new CompoundCurve. 9 | 10 | 11 | Example Use 12 | ----------- 13 | 14 | Sample code to new compoundcurve: 15 | 16 | .. code-block:: javascript 17 | 18 | >> var GEOM = require("geoscript/geom"); 19 | >> var cs = new GEOM.CircularString([[10.0, 10.0], [0.0, 20.0], [-10.0, 10.0]]); 20 | >> var line = new GEOM.LineString([[-10.0, 10.0], [-10.0, 0.0], [10.0, 0.0], [5.0, 5.0]]) 21 | >> var cc = new GEOM.CompoundCurve([cs, line]); 22 | >> cc.components.length 23 | 2 24 | >> cc.linear.getGeometryType() 25 | LineString 26 | >> cc.curvedWkt 27 | COMPOUNDCURVE (CIRCULARSTRING (10.0 10.0, 0.0 20.0, -10.0 10.0), (-10.0 10.0, -10.0 0.0, 10.0 0.0, 5.0 5.0)) 28 | 29 | 30 | Properties 31 | ---------- 32 | 33 | In addition to the properties common to all :class:`geom.LineString` subclasses, 34 | compoundcurve geometries have the properties documented below. 35 | 36 | 37 | .. attribute:: CompoundCurve.components 38 | 39 | :class:`geom.LineString` 40 | The original LineString or CircularStrings. 41 | 42 | .. attribute:: CircularString.curvedWkt 43 | 44 | :class:`String` 45 | The curved WKT as a string. 46 | 47 | .. attribute:: CircularString.linear 48 | 49 | :class:`geom.LineString` 50 | A linearized LineString. 51 | 52 | Methods 53 | ------- 54 | 55 | CompoundCurve geometries have the methods common to all :class:`geom.LineString` 56 | subclasses. 57 | -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/test_workspace.js: -------------------------------------------------------------------------------- 1 | var ASSERT = require("assert"); 2 | var WORKSPACE = require("geoscript/workspace"); 3 | 4 | exports["test: create(memory)"] = function() { 5 | 6 | var mem = WORKSPACE.create(); 7 | ASSERT.ok(mem instanceof WORKSPACE.Memory, "instanceof Memory"); 8 | mem.close(); 9 | 10 | }; 11 | 12 | exports["test: create(directory)"] = function() { 13 | 14 | var dir = WORKSPACE.create("."); 15 | ASSERT.ok(dir instanceof WORKSPACE.Directory, "instanceof Directory"); 16 | dir.close(); 17 | 18 | }; 19 | 20 | exports["test: Workspace.from_"] = function() { 21 | 22 | var ws, _store; 23 | 24 | var dir = WORKSPACE.create("."); 25 | ws = WORKSPACE.Workspace.from_(dir._store); 26 | ASSERT.ok(ws instanceof WORKSPACE.Directory, "round tripped Directory"); 27 | ws.close(); 28 | 29 | var bogus = {}; 30 | ws = WORKSPACE.Workspace.from_(bogus); 31 | ASSERT.ok(ws instanceof WORKSPACE.Workspace, "created generic Workspace from bogus store"); 32 | 33 | } 34 | 35 | exports["test: Directory"] = require("./workspace/test_directory"); 36 | exports["test: H2"] = require("./workspace/test_h2"); 37 | exports["test: GeoPackage"] = require("./workspace/test_geopackage"); 38 | exports["test: Geobuf"] = require("./workspace/test_geobuf"); 39 | exports["test: Flatgeobuf"] = require("./workspace/test_flatgeobuf"); 40 | exports["test: Memory"] = require("./workspace/test_memory"); 41 | // exports["test: PostGIS"] = require("./workspace/test_postgis"); 42 | 43 | if (require.main == module.id) { 44 | system.exit(require("test").run(exports)); 45 | } 46 | -------------------------------------------------------------------------------- /doc/api/workspace/memory.rst: -------------------------------------------------------------------------------- 1 | :class:`workspace.Memory` 2 | ========================= 3 | 4 | .. class:: workspace.Memory(config) 5 | 6 | Create a memory based workspace. 7 | 8 | 9 | Properties 10 | ---------- 11 | 12 | .. attribute:: Memory.layers 13 | 14 | ``Array`` 15 | The available layers in the workspace. 16 | 17 | .. attribute:: Memory.names 18 | 19 | ``Array`` 20 | The available layer names in the workspace. 21 | 22 | 23 | Methods 24 | ------- 25 | 26 | 27 | .. function:: Memory.add 28 | 29 | :arg layer: :class:`layer.Layer` The layer to be added. 30 | :arg options: ``Object`` Options for adding the layer. 31 | 32 | Options: 33 | 34 | * `name`: ``String`` Name for the new layer. 35 | * `filter`: :class:`filter.Filter` Filter to apply to features before adding. 36 | * `projection`: :class:`proj.Projection` Destination projection for the layer. 37 | 38 | :returns: :class:`layer.Layer` 39 | 40 | Create a new layer in this workspace with the features from an existing 41 | layer. If a layer with the same name already exists in this workspace, 42 | you must provide a new name for the layer. 43 | 44 | .. function:: Memory.close 45 | 46 | Close the workspace. This discards any existing connection to the 47 | underlying data store and discards the reference to the store. 48 | 49 | .. function:: Memory.get 50 | 51 | :arg name: ``String`` Layer name. 52 | :returns: :class:`layer.Layer` 53 | 54 | Get a layer by name. Returns ``undefined`` if name doesn't correspond 55 | to a layer source in the workspace. 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/test_index.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | var index = require("geoscript/index"); 3 | var geom = require("geoscript/geom"); 4 | 5 | exports["test: quadtree index"] = function() { 6 | 7 | var quadtree = new index.QuadTree(); 8 | quadtree.insert(new geom.Bounds([0,0,10,10]), new geom.Point([5,5])); 9 | quadtree.insert(new geom.Bounds([2,2,6,6]), new geom.Point([4,4])); 10 | quadtree.insert(new geom.Bounds([20,20,60,60]), new geom.Point([30,30])); 11 | quadtree.insert(new geom.Bounds([22,22,44,44]), new geom.Point([32,32])); 12 | assert.strictEqual(4, quadtree.size, "QuadTree index should have 4 entries"); 13 | 14 | var results = quadtree.query(new geom.Bounds([1,1,5,5])); 15 | assert.strictEqual(4, results.length); 16 | 17 | var allResults = quadtree.queryAll(); 18 | assert.strictEqual(4, allResults.length); 19 | 20 | var isRemoved = quadtree.remove(new geom.Bounds([22,22,44,44]), new geom.Point([32,32])); 21 | assert.ok(isRemoved) 22 | 23 | allResults = quadtree.queryAll() 24 | assert.strictEqual(3, allResults.length); 25 | 26 | }; 27 | 28 | exports["test: strtree index"] = function() { 29 | 30 | var strtree = new index.STRtree(); 31 | strtree.insert(new geom.Bounds([0,0,10,10]), new geom.Point([5,5])); 32 | strtree.insert(new geom.Bounds([2,2,6,6]), new geom.Point([4,4])); 33 | strtree.insert(new geom.Bounds([20,20,60,60]), new geom.Point([30,30])); 34 | strtree.insert(new geom.Bounds([22,22,44,44]), new geom.Point([32,32])); 35 | assert.strictEqual(4, strtree.size, "QuadTree index should have 4 entries"); 36 | 37 | }; -------------------------------------------------------------------------------- /src/main/java/org/geoscript/js/proj/Module.java: -------------------------------------------------------------------------------- 1 | package org.geoscript.js.proj; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.util.HashMap; 5 | 6 | import org.geoscript.js.GeoObject; 7 | import org.mozilla.javascript.Scriptable; 8 | import org.mozilla.javascript.ScriptableObject; 9 | 10 | public class Module { 11 | 12 | static HashMap prototypes; 13 | 14 | /** 15 | * Define all proj constructors in the given module scope. If the 16 | * provided scope is not a "top level" scope, constructors will be defined 17 | * in the top level scope for the given scope. 18 | * @param scope 19 | * @throws IllegalAccessException 20 | * @throws InstantiationException 21 | * @throws InvocationTargetException 22 | */ 23 | public static void init(Scriptable scope) throws IllegalAccessException, InstantiationException, InvocationTargetException { 24 | 25 | scope = ScriptableObject.getTopLevelScope(scope); 26 | 27 | String name = ScriptableObject.defineClass(scope, Projection.class, false, true); 28 | prototypes = new HashMap(); 29 | prototypes.put(name, ScriptableObject.getClassPrototype(scope, name)); 30 | } 31 | 32 | protected static Scriptable getClassPrototype(Class cls) { 33 | String name = cls.getName(); 34 | if (prototypes == null || !prototypes.containsKey(name)) { 35 | throw new RuntimeException( 36 | "Attempt to access prototype before requiring module: " + name); 37 | } 38 | return prototypes.get(name); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/test_proj.js: -------------------------------------------------------------------------------- 1 | var ASSERT = require("assert"); 2 | var GEOM = require("geoscript/geom"); 3 | var PROJ = require("geoscript/proj"); 4 | 5 | exports["test: Projection"] = function() { 6 | var p = new PROJ.Projection("EPSG:4326"); 7 | ASSERT.equal("EPSG:4326", p.id, "[srid] correct id"); 8 | 9 | var wkt = 10 | 'GEOGCS[' + 11 | '"GCS_WGS_1984",' + 12 | 'DATUM[' + 13 | '"D_WGS_1984",' + 14 | 'SPHEROID["WGS_1984",6378137,298.257223563]' + 15 | '],' + 16 | 'PRIMEM["Greenwich",0],' + 17 | 'UNIT["Degree",0.017453292519943295]' + 18 | ']'; 19 | var p2 = new PROJ.Projection(wkt); 20 | ASSERT.equal("EPSG:4326", p2.id, "[wkt] correct id"); 21 | 22 | }; 23 | 24 | exports["test: Projection.equals"] = function() { 25 | 26 | var p1 = new PROJ.Projection("EPSG:4326"); 27 | 28 | var wkt = 29 | 'GEOGCS[' + 30 | '"GCS_WGS_1984",' + 31 | 'DATUM[' + 32 | '"D_WGS_1984",' + 33 | 'SPHEROID["WGS_1984",6378137,298.257223563]' + 34 | '],' + 35 | 'PRIMEM["Greenwich",0],' + 36 | 'UNIT["Degree",0.017453292519943295]' + 37 | ']'; 38 | var p2 = new PROJ.Projection(wkt); 39 | 40 | ASSERT.ok(p1.equals(p2), "p1 equals p2"); 41 | ASSERT.ok(p2.equals(p1), "p2 equals p1"); 42 | 43 | var p3 = new PROJ.Projection("epsg:3005"); 44 | ASSERT.isFalse(p1.equals(p3), "p1 doesn't equal p3"); 45 | 46 | }; 47 | 48 | if (require.main == module.id) { 49 | system.exit(require("test").run(exports)); 50 | } -------------------------------------------------------------------------------- /src/main/java/org/geoscript/js/process/Module.java: -------------------------------------------------------------------------------- 1 | package org.geoscript.js.process; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.util.HashMap; 5 | 6 | import org.geoscript.js.GeoObject; 7 | import org.mozilla.javascript.Scriptable; 8 | import org.mozilla.javascript.ScriptableObject; 9 | 10 | public class Module { 11 | 12 | static HashMap prototypes; 13 | 14 | /** 15 | * Define all feature related constructors in the given module scope. If 16 | * the provided scope is not a "top level" scope, constructors will be 17 | * defined in the top level scope for the given scope. 18 | * @param scope 19 | * @throws IllegalAccessException 20 | * @throws InstantiationException 21 | * @throws InvocationTargetException 22 | */ 23 | public static void init(Scriptable scope) throws IllegalAccessException, InstantiationException, InvocationTargetException { 24 | scope = ScriptableObject.getTopLevelScope(scope); 25 | 26 | String name = ScriptableObject.defineClass(scope, Process.class, false, true); 27 | prototypes = new HashMap(); 28 | prototypes.put(name, ScriptableObject.getClassPrototype(scope, name)); 29 | 30 | } 31 | 32 | protected static Scriptable getClassPrototype(Class cls) { 33 | String name = cls.getName(); 34 | if (prototypes == null || !prototypes.containsKey(name)) { 35 | throw new RuntimeException( 36 | "Attempt to access prototype before requiring module: " + name); 37 | } 38 | return prototypes.get(name); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /bin/geoscript-js: -------------------------------------------------------------------------------- 1 | 2 | # parse options 3 | DEBUG= 4 | JARS= 5 | MODULES= 6 | while getopts 'dj:m:' OPTION; do 7 | case $OPTION in 8 | d) DEBUG=1;; 9 | j) JARS="$OPTARG";; 10 | m) MODULES="$OPTARG";; 11 | esac 12 | done 13 | shift $(($OPTIND -1)) 14 | 15 | # find home 16 | if [ -z "$0" ]; then 17 | # as a last recourse, use the present working directory 18 | GEOSCRIPT_HOME=$(pwd) 19 | else 20 | # get the absolute path of the executable 21 | SELF_PATH=$( 22 | cd -P -- "$(dirname -- "$0")" \ 23 | && pwd -P 24 | ) && SELF_PATH=$SELF_PATH/$(basename -- "$0") 25 | 26 | # resolve symlinks 27 | while [ -h "$SELF_PATH" ]; do 28 | DIR=$(dirname -- "$SELF_PATH") 29 | SYM=$(readlink -- "$SELF_PATH") 30 | SELF_PATH=$(cd -- "$DIR" && cd -- $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM") 31 | done 32 | 33 | GEOSCRIPT_HOME=$(dirname -- "$(dirname -- "$SELF_PATH")") 34 | fi 35 | 36 | if [ ! "$JARS" ]; then 37 | JARS=$GEOSCRIPT_HOME/jars 38 | fi 39 | 40 | # put GeoTools jars on the classpath 41 | CP="" 42 | for x in `ls $JARS/*.jar`; do 43 | CP=$CP:$x 44 | done 45 | 46 | if [ "$DEBUG" ]; then 47 | CLASS=org.mozilla.javascript.tools.debugger.Main 48 | else 49 | CLASS=org.geoscript.js.GeoScriptShell 50 | fi 51 | 52 | ARGS= 53 | if [ "$MODULES" ]; then 54 | ARGS="-Dgeoscript.modules=$MODULES" 55 | fi 56 | 57 | if [ $# -eq 1 ]; then 58 | # resolve absolute path to main module 59 | MAIN_PATH=$( 60 | cd -P -- "$(dirname -- "$1")" \ 61 | && pwd -P 62 | ) && MAIN_PATH=$MAIN_PATH/$(basename -- "$1") 63 | 64 | java -cp $CP $ARGS $CLASS $MAIN_PATH 65 | else 66 | java -cp $CP $ARGS $CLASS 67 | fi 68 | -------------------------------------------------------------------------------- /src/main/java/org/geoscript/js/index/STRtree.java: -------------------------------------------------------------------------------- 1 | package org.geoscript.js.index; 2 | 3 | import org.geoscript.js.geom.Bounds; 4 | import org.mozilla.javascript.Context; 5 | import org.mozilla.javascript.Function; 6 | import org.mozilla.javascript.Scriptable; 7 | import org.mozilla.javascript.annotations.JSConstructor; 8 | import org.mozilla.javascript.annotations.JSFunction; 9 | import org.mozilla.javascript.annotations.JSGetter; 10 | 11 | import java.util.List; 12 | 13 | public class STRtree extends SpatialIndex { 14 | 15 | public STRtree() { 16 | super(new org.locationtech.jts.index.strtree.STRtree()); 17 | } 18 | 19 | public STRtree(Scriptable scope) { 20 | this(); 21 | this.setParentScope(scope); 22 | this.setPrototype(Module.getClassPrototype(STRtree.class)); 23 | } 24 | 25 | @JSFunction 26 | public void insert(Bounds bounds, Object item) { 27 | this.index.insert(bounds.unwrap(), item); 28 | } 29 | 30 | @JSFunction 31 | public List query(Bounds bounds) { 32 | return this.index.query(bounds.unwrap()); 33 | } 34 | 35 | @JSGetter 36 | public int getSize() { 37 | return ((org.locationtech.jts.index.strtree.STRtree)this.index).size(); 38 | } 39 | 40 | /** 41 | * JavaScript constructor. 42 | * @param cx 43 | * @param args 44 | * @param ctorObj 45 | * @param isNewExpr 46 | * @return 47 | */ 48 | @JSConstructor 49 | public static Object constructor(Context cx, Object[] args, Function ctorObj, boolean isNewExpr) { 50 | if (isNewExpr) { 51 | return new STRtree(); 52 | } else { 53 | return new STRtree(ctorObj.getParentScope()); 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /doc/api/workspace/workspace.rst: -------------------------------------------------------------------------------- 1 | :class:`workspace.Workspace` 2 | ============================ 3 | 4 | .. class:: workspace.Workspace 5 | 6 | A Workspace instance should not be created directly. 7 | Create an instance of a Workspace subclass instead. 8 | 9 | 10 | Properties 11 | ---------- 12 | 13 | .. attribute:: Workspace.layers 14 | 15 | ``Array`` 16 | The available layers in the workspace. 17 | 18 | .. attribute:: Workspace.names 19 | 20 | ``Array`` 21 | The available layer names in the workspace. 22 | 23 | 24 | Methods 25 | ------- 26 | 27 | 28 | .. function:: Workspace.add 29 | 30 | :arg layer: :class:`layer.Layer` The layer to be added. 31 | :arg options: ``Object`` Options for adding the layer. 32 | 33 | Options: 34 | 35 | * `name`: ``String`` Name for the new layer. 36 | * `filter`: :class:`filter.Filter` Filter to apply to features before adding. 37 | * `projection`: :class:`proj.Projection` Destination projection for the layer. 38 | 39 | :returns: :class:`layer.Layer` 40 | 41 | Create a new layer in this workspace with the features from an existing 42 | layer. If a layer with the same name already exists in this workspace, 43 | you must provide a new name for the layer. 44 | 45 | .. function:: Workspace.close 46 | 47 | Close the workspace. This discards any existing connection to the 48 | underlying data store and discards the reference to the store. 49 | 50 | .. function:: Workspace.get 51 | 52 | :arg name: ``String`` Layer name. 53 | :returns: :class:`layer.Layer` 54 | 55 | Get a layer by name. Returns ``undefined`` if name doesn't correspond 56 | to a layer source in the workspace. 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/main/resources/org/geoscript/js/lib/geoscript/proj.js: -------------------------------------------------------------------------------- 1 | /** api: module = proj */ 2 | 3 | /** api: synopsis 4 | * Projection related functionality. 5 | */ 6 | 7 | /** api: summary 8 | * The :mod:`proj` module exports a Projection constructor and methods for 9 | * transforming geometries between coordinate reference systems. 10 | * 11 | * .. code-block:: javascript 12 | * 13 | * js> var PROJ = require("geoscript/proj"); 14 | */ 15 | 16 | /** api: classes[] = projection */ 17 | Packages.org.geoscript.js.proj.Module.init(this); 18 | var Projection = this["org.geoscript.js.proj.Projection"]; 19 | 20 | /** api: method[transform] 21 | * :arg geometry: :class:`geom.Geometry` 22 | * :arg from: :class:`proj.Projection` or ``String`` 23 | * :arg to: :class:`proj.Projection` or ``String`` 24 | * :returns: :class:`geom.Geometry` 25 | * 26 | * Tranform a geometry from one coordinate reference system to another. 27 | * Returns a new geometry. The ``from`` and ``to`` arguments can be 28 | * :class:`proj.Projection` instances or the string values used to construct 29 | * them. 30 | * 31 | * Example use: 32 | * 33 | * .. code-block:: javascript 34 | * 35 | * js> var GEOM = require("geoscript/geom"); 36 | * js> var p1 = new GEOM.Point([-111.0, 45.7]); 37 | * js> var p2 = PROJ.transform(p1, "epsg:4326", "epsg:26912"); 38 | * js> Math.floor(p2.x) 39 | * 499999 40 | * js> Math.floor(p2.y) 41 | * 5060716 42 | */ 43 | var transform = function(geometry, from, to) { 44 | if (!(from instanceof Projection)) { 45 | from = new Projection(from); 46 | } 47 | geometry.projection = from; 48 | return geometry.transform(to); 49 | }; 50 | 51 | exports.transform = transform; 52 | exports.Projection = Projection; 53 | 54 | -------------------------------------------------------------------------------- /src/main/resources/org/geoscript/js/lib/geoscript/registry.js: -------------------------------------------------------------------------------- 1 | var UTIL = require("./util"); 2 | 3 | var Registry = UTIL.extend(Object, { 4 | 5 | constructor: function Registry() { 6 | 7 | var factories = []; 8 | 9 | this.register = function(factory) { 10 | factories.push(factory); 11 | }; 12 | 13 | this.create = function(config) { 14 | if (!config) { 15 | config = {}; 16 | } 17 | var candidate, factory; 18 | for (var i=0, ii=factories.length; i 200") 22 | ) 23 | }] 24 | }); 25 | 26 | exports.index = function(req) { 27 | 28 | var template = getResource("./templates/index.html").content; 29 | return response.html( 30 | mustache.to_html(template, { 31 | host: req.host, port: req.port, layers: map.layers 32 | }) 33 | ); 34 | 35 | }; 36 | 37 | exports.wms = function(request) { 38 | 39 | var params = {}; 40 | request.queryString.split("&").forEach(function(pair) { 41 | var [key, value] = pair.split("="); 42 | params[decodeURIComponent(key)] = decodeURIComponent(value); 43 | }); 44 | 45 | var bbox = params["BBOX"].split(",").map(Number); 46 | var format = params["FORMAT"] 47 | 48 | var image = new ByteArray(map.render({ 49 | imageType: format.split("/").pop(), 50 | bounds: bbox 51 | })); 52 | 53 | return { 54 | status: 200, 55 | headers: {"Content-Type": format}, 56 | body: [image] 57 | }; 58 | 59 | }; 60 | -------------------------------------------------------------------------------- /src/main/resources/org/geoscript/js/lib/geoscript/process.js: -------------------------------------------------------------------------------- 1 | require("./feature"); // initialize all modules for values that may be wrapped 2 | 3 | Packages.org.geoscript.js.process.Module.init(this); 4 | 5 | /** api: module = process */ 6 | 7 | /** api: synopsis 8 | * Process related functionality. 9 | */ 10 | 11 | /** api: summary 12 | * The :mod:`process` module provides a constructor for Process objects. 13 | * 14 | * .. code-block:: javascript 15 | * 16 | * js> var PROCESS = require("geoscript/process"); 17 | */ 18 | 19 | 20 | /** api: class = Process */ 21 | var Process = exports.Process = this["org.geoscript.js.process.Process"]; 22 | 23 | 24 | /** api: config[title] 25 | * ``String`` 26 | * Title for the process. 27 | */ 28 | /** api: property[title] 29 | * ``String`` 30 | * Title for the process. 31 | */ 32 | 33 | /** api: config[description] 34 | * ``String`` 35 | * Full description of the process, including all input and output fields. 36 | */ 37 | /** api: property[description] 38 | * ``String`` 39 | * Full description of the process, including all input and output fields. 40 | */ 41 | 42 | 43 | /** api: config[inputs] 44 | * ``Object`` 45 | * Proces inputs. 46 | */ 47 | /** api: property[inputs] 48 | * ``Object`` 49 | * Proces inputs. 50 | */ 51 | 52 | 53 | /** api: config[outputs] 54 | * ``Object`` 55 | * Proces outputs. 56 | */ 57 | /** api: property[outputs] 58 | * ``Object`` 59 | * Proces outputs. 60 | */ 61 | 62 | /** api: config[run] 63 | * ``Function`` 64 | * The function to be executed when running the process. 65 | */ 66 | 67 | /** api: constructor 68 | * .. class:: Process 69 | * 70 | * :arg config: `Object` Process configuration. 71 | * 72 | */ 73 | 74 | -------------------------------------------------------------------------------- /doc/api/workspace/h2.rst: -------------------------------------------------------------------------------- 1 | :class:`workspace.H2` 2 | ===================== 3 | 4 | .. class:: workspace.H2(config) 5 | 6 | :arg config: ``Object`` Configuration object. 7 | 8 | Create a workspace from an H2 database. 9 | 10 | 11 | Config Properties 12 | ----------------- 13 | 14 | .. describe:: database 15 | 16 | ``String`` 17 | Path to the database (required). 18 | 19 | Properties 20 | ---------- 21 | 22 | .. attribute:: H2.layers 23 | 24 | ``Array`` 25 | The available layers in the workspace. 26 | 27 | .. attribute:: H2.names 28 | 29 | ``Array`` 30 | The available layer names in the workspace. 31 | 32 | 33 | Methods 34 | ------- 35 | 36 | 37 | .. function:: H2.add 38 | 39 | :arg layer: :class:`layer.Layer` The layer to be added. 40 | :arg options: ``Object`` Options for adding the layer. 41 | 42 | Options: 43 | * `name`: ``String`` Name for the new layer. 44 | * `filter`: :class:`filter.Filter` Filter to apply to features before adding. 45 | * `projection`: :class:`proj.Projection` Destination projection for the layer. 46 | 47 | :returns: :class:`layer.Layer` 48 | 49 | Create a new layer in this workspace with the features from an existing 50 | layer. If a layer with the same name already exists in this workspace, 51 | you must provide a new name for the layer. 52 | 53 | .. function:: H2.close 54 | 55 | Close the workspace. This discards any existing connection to the 56 | underlying data store and discards the reference to the store. 57 | 58 | .. function:: H2.get 59 | 60 | :arg name: ``String`` Layer name. 61 | :returns: :class:`layer.Layer` 62 | 63 | Get a layer by name. Returns ``undefined`` if name doesn't correspond 64 | to a layer source in the workspace. 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /src/main/resources/org/geoscript/js/lib/geoscript/workspace/memory.js: -------------------------------------------------------------------------------- 1 | var register = require("./util").register; 2 | var Factory = require("../factory").Factory; 3 | var Workspace = require("./workspace").Workspace; 4 | var UTIL = require("../util"); 5 | 6 | var MemoryDataStore = Packages.org.geotools.data.memory.MemoryDataStore; 7 | 8 | var prepConfig = function(config) { 9 | if (config === undefined) { 10 | config = {}; 11 | } 12 | return config; 13 | }; 14 | 15 | /** api: (define) 16 | * module = workspace 17 | * class = Memory 18 | */ 19 | 20 | /** api: (extends) 21 | * workspace/workspace.js 22 | */ 23 | var Memory = UTIL.extend(Workspace, { 24 | 25 | /** api: constructor 26 | * .. class:: Memory 27 | * 28 | * Create a memory based workspace. 29 | */ 30 | constructor: function Memory(config) { 31 | Workspace.prototype.constructor.apply(this, [prepConfig(config)]); 32 | }, 33 | 34 | /** private: method[_create] 35 | * :arg config: ``Object`` 36 | * :returns: ``org.geotools.data.memory.MemoryDataStore`` 37 | * 38 | * Create the underlying store for the workspace. 39 | */ 40 | _create: function(config) { 41 | return java.lang.Class.forName("org.geotools.data.memory.MemoryDataStore").newInstance(); 42 | } 43 | 44 | }); 45 | 46 | exports.Memory = Memory; 47 | 48 | // register a memory factory for the module 49 | register(new Factory(Memory, { 50 | handles: function(config) { 51 | config = prepConfig(config); 52 | var capable = false; 53 | if (typeof config === "object") { 54 | if (config.type) { 55 | if (config.type.toLowerCase() === "memory") { 56 | capable = true; 57 | } 58 | } else if (Object.keys(config).length === 0) { 59 | capable = true; 60 | } 61 | } 62 | return capable; 63 | } 64 | })); 65 | -------------------------------------------------------------------------------- /doc/api/workspace/directory.rst: -------------------------------------------------------------------------------- 1 | :class:`workspace.Directory` 2 | ============================ 3 | 4 | .. class:: workspace.Directory(config) 5 | 6 | :arg path: ``String`` Path to the directory. 7 | 8 | Create a workspace from a directory. 9 | 10 | 11 | Properties 12 | ---------- 13 | 14 | .. attribute:: Directory.layers 15 | 16 | ``Array`` 17 | The available layers in the workspace. 18 | 19 | .. attribute:: Directory.names 20 | 21 | ``Array`` 22 | The available layer names in the workspace. 23 | 24 | .. attribute:: Directory.path 25 | 26 | ``String`` 27 | The absolute directory path. 28 | 29 | 30 | 31 | 32 | Methods 33 | ------- 34 | 35 | 36 | .. function:: Directory.add 37 | 38 | :arg layer: :class:`layer.Layer` The layer to be added. 39 | :arg options: ``Object`` Options for adding the layer. 40 | 41 | Options: 42 | 43 | * `name`: ``String`` Name for the new layer. 44 | * `filter`: :class:`filter.Filter` Filter to apply to features before adding. 45 | * `projection`: :class:`proj.Projection` Destination projection for the layer. 46 | 47 | :returns: :class:`layer.Layer` 48 | 49 | Create a new layer in this workspace with the features from an existing 50 | layer. If a layer with the same name already exists in this workspace, 51 | you must provide a new name for the layer. 52 | 53 | .. function:: Directory.close 54 | 55 | Close the workspace. This discards any existing connection to the 56 | underlying data store and discards the reference to the store. 57 | 58 | .. function:: Directory.get 59 | 60 | :arg name: ``String`` Layer name. 61 | :returns: :class:`layer.Layer` 62 | 63 | Get a layer by name. Returns ``undefined`` if name doesn't correspond 64 | to a layer source in the workspace. 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /doc/api/workspace/geobuf.rst: -------------------------------------------------------------------------------- 1 | :class:`workspace.Geobuf` 2 | ===================== 3 | 4 | .. class:: workspace.Geobuf(config) 5 | 6 | :arg config: ``Object`` Configuration object. 7 | 8 | Create a workspace from an Geobuf directory. 9 | 10 | 11 | Config Properties 12 | ----------------- 13 | 14 | .. describe:: file 15 | 16 | ``String`` 17 | Directory path to the Geobuf files (required). 18 | 19 | Properties 20 | ---------- 21 | 22 | .. attribute:: Geobuf.layers 23 | 24 | ``Array`` 25 | The available layers in the workspace. 26 | 27 | .. attribute:: Geobuf.names 28 | 29 | ``Array`` 30 | The available layer names in the workspace. 31 | 32 | 33 | Methods 34 | ------- 35 | 36 | 37 | .. function:: Geobuf.add 38 | 39 | :arg layer: :class:`layer.Layer` The layer to be added. 40 | :arg options: ``Object`` Options for adding the layer. 41 | 42 | Options: 43 | * `name`: ``String`` Name for the new layer. 44 | * `filter`: :class:`filter.Filter` Filter to apply to features before adding. 45 | * `projection`: :class:`proj.Projection` Destination projection for the layer. 46 | 47 | :returns: :class:`layer.Layer` 48 | 49 | Create a new layer in this workspace with the features from an existing 50 | layer. If a layer with the same name already exists in this workspace, 51 | you must provide a new name for the layer. 52 | 53 | .. function:: Geobuf.close 54 | 55 | Close the workspace. This discards any existing connection to the 56 | underlying data store and discards the reference to the store. 57 | 58 | .. function:: Geobuf.get 59 | 60 | :arg name: ``String`` Layer name. 61 | :returns: :class:`layer.Layer` 62 | 63 | Get a layer by name. Returns ``undefined`` if name doesn't correspond 64 | to a layer source in the workspace. 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /doc/api/workspace/geopackage.rst: -------------------------------------------------------------------------------- 1 | :class:`workspace.GeoPackage` 2 | ===================== 3 | 4 | .. class:: workspace.GeoPackage(config) 5 | 6 | :arg config: ``Object`` Configuration object. 7 | 8 | Create a workspace from an GeoPackage database. 9 | 10 | 11 | Config Properties 12 | ----------------- 13 | 14 | .. describe:: database 15 | 16 | ``String`` 17 | Path to the database (required). 18 | 19 | Properties 20 | ---------- 21 | 22 | .. attribute:: GeoPackage.layers 23 | 24 | ``Array`` 25 | The available layers in the workspace. 26 | 27 | .. attribute:: GeoPackage.names 28 | 29 | ``Array`` 30 | The available layer names in the workspace. 31 | 32 | 33 | Methods 34 | ------- 35 | 36 | 37 | .. function:: GeoPackage.add 38 | 39 | :arg layer: :class:`layer.Layer` The layer to be added. 40 | :arg options: ``Object`` Options for adding the layer. 41 | 42 | Options: 43 | * `name`: ``String`` Name for the new layer. 44 | * `filter`: :class:`filter.Filter` Filter to apply to features before adding. 45 | * `projection`: :class:`proj.Projection` Destination projection for the layer. 46 | 47 | :returns: :class:`layer.Layer` 48 | 49 | Create a new layer in this workspace with the features from an existing 50 | layer. If a layer with the same name already exists in this workspace, 51 | you must provide a new name for the layer. 52 | 53 | .. function:: GeoPackage.close 54 | 55 | Close the workspace. This discards any existing connection to the 56 | underlying data store and discards the reference to the store. 57 | 58 | .. function:: GeoPackage.get 59 | 60 | :arg name: ``String`` Layer name. 61 | :returns: :class:`layer.Layer` 62 | 63 | Get a layer by name. Returns ``undefined`` if name doesn't correspond 64 | to a layer source in the workspace. 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /doc/api/workspace/flatgeobuf.rst: -------------------------------------------------------------------------------- 1 | :class:`workspace.Flatgeobuf` 2 | ===================== 3 | 4 | .. class:: workspace.Flatgeobuf(config) 5 | 6 | :arg config: ``Object`` Configuration object. 7 | 8 | Create a workspace from an Flatgeobuf directory. 9 | 10 | 11 | Config Properties 12 | ----------------- 13 | 14 | .. describe:: file 15 | 16 | ``String`` 17 | Directory path to the Flatgeobuf files (required). 18 | 19 | Properties 20 | ---------- 21 | 22 | .. attribute:: Flatgeobuf.layers 23 | 24 | ``Array`` 25 | The available layers in the workspace. 26 | 27 | .. attribute:: Flatgeobuf.names 28 | 29 | ``Array`` 30 | The available layer names in the workspace. 31 | 32 | 33 | Methods 34 | ------- 35 | 36 | 37 | .. function:: Flatgeobuf.add 38 | 39 | :arg layer: :class:`layer.Layer` The layer to be added. 40 | :arg options: ``Object`` Options for adding the layer. 41 | 42 | Options: 43 | * `name`: ``String`` Name for the new layer. 44 | * `filter`: :class:`filter.Filter` Filter to apply to features before adding. 45 | * `projection`: :class:`proj.Projection` Destination projection for the layer. 46 | 47 | :returns: :class:`layer.Layer` 48 | 49 | Create a new layer in this workspace with the features from an existing 50 | layer. If a layer with the same name already exists in this workspace, 51 | you must provide a new name for the layer. 52 | 53 | .. function:: Flatgeobuf.close 54 | 55 | Close the workspace. This discards any existing connection to the 56 | underlying data store and discards the reference to the store. 57 | 58 | .. function:: Flatgeobuf.get 59 | 60 | :arg name: ``String`` Layer name. 61 | :returns: :class:`layer.Layer` 62 | 63 | Get a layer by name. Returns ``undefined`` if name doesn't correspond 64 | to a layer source in the workspace. 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /src/main/resources/org/geoscript/js/lib/geoscript/workspace.js: -------------------------------------------------------------------------------- 1 | /** api: module = workspace */ 2 | 3 | /** api: synopsis 4 | * A collection of workspace types. 5 | */ 6 | 7 | /** api: summary 8 | * The :mod:`workspace` module provides a provides constructors for different 9 | * workspace types. 10 | * 11 | * .. code-block:: javascript 12 | * 13 | * js> var WORKSPACE = require("geoscript/workspace"); 14 | */ 15 | 16 | /** private: method[create] 17 | * :arg config: ``Object`` Configuration object. 18 | * :returns: :class:`Workspace` 19 | * 20 | * Create a workspace given a configuration object. 21 | */ 22 | exports.create = require("./workspace/util").create; 23 | 24 | /** private: classes[] = workspace */ 25 | exports.Workspace = require("./workspace/workspace").Workspace; 26 | 27 | /** api: classes[] = memory */ 28 | exports.Memory = require("./workspace/memory").Memory; 29 | 30 | /** api: classes[] = directory */ 31 | exports.Directory = require("./workspace/directory").Directory; 32 | 33 | /** api: classes[] = postgis */ 34 | exports.PostGIS = require("./workspace/postgis").PostGIS; 35 | 36 | /** api: classes[] = h2 */ 37 | exports.H2 = require("./workspace/h2").H2; 38 | 39 | /** api: classes[] = mysql */ 40 | exports.MySQL = require("./workspace/mysql").MySQL; 41 | 42 | /** api: classes[] = geopackage */ 43 | exports.GeoPackage = require("./workspace/geopackage").GeoPackage; 44 | 45 | /** api: classes[] = geobuf */ 46 | exports.Geobuf = require("./workspace/geobuf").Geobuf; 47 | 48 | /** api: classes[] = flatgeobuf */ 49 | exports.Flatgeobuf = require("./workspace/flatgeobuf").Flatgeobuf; 50 | 51 | /** private: classes[] = spatialite */ 52 | exports.SpatiaLite = require("./workspace/spatialite").SpatiaLite; 53 | 54 | /** api: property[memory] 55 | * :class:`Memory` 56 | * A memory workspace that will be used to collect all temporary layers 57 | * created without a specific workspace. 58 | */ 59 | exports.memory = new exports.Memory(); 60 | -------------------------------------------------------------------------------- /src/main/java/org/geoscript/js/raster/Module.java: -------------------------------------------------------------------------------- 1 | package org.geoscript.js.raster; 2 | 3 | import org.geoscript.js.GeoObject; 4 | import org.mozilla.javascript.Scriptable; 5 | import org.mozilla.javascript.ScriptableObject; 6 | 7 | import java.lang.reflect.InvocationTargetException; 8 | import java.util.Arrays; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | 12 | public class Module { 13 | 14 | static HashMap prototypes; 15 | 16 | /** 17 | * Define all geometry constructors in the given module scope. If the 18 | * provided scope is not a "top level" scope, constructors will be defined 19 | * in the top level scope for the given scope. 20 | * @param scope 21 | * @throws IllegalAccessException 22 | * @throws InstantiationException 23 | * @throws InvocationTargetException 24 | */ 25 | public static void init(Scriptable scope) throws IllegalAccessException, InstantiationException, InvocationTargetException { 26 | 27 | scope = ScriptableObject.getTopLevelScope(scope); 28 | 29 | @SuppressWarnings("unchecked") 30 | List> classes = Arrays.asList(Band.class, Raster.class, Format.class); 31 | 32 | prototypes = new HashMap(); 33 | for (Class cls : classes) { 34 | String name = ScriptableObject.defineClass(scope, cls, false, true); 35 | Scriptable prototype = ScriptableObject.getClassPrototype(scope, name); 36 | prototypes.put(name, prototype); 37 | } 38 | 39 | } 40 | 41 | protected static Scriptable getClassPrototype(Class cls) { 42 | String name = cls.getName(); 43 | if (prototypes == null || !prototypes.containsKey(name)) { 44 | throw new RuntimeException( 45 | "Attempt to access prototype before requiring module: " + name); 46 | } 47 | return prototypes.get(name); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/org/geoscript/js/filter/Module.java: -------------------------------------------------------------------------------- 1 | package org.geoscript.js.filter; 2 | 3 | import org.geoscript.js.GeoObject; 4 | import org.mozilla.javascript.Scriptable; 5 | import org.mozilla.javascript.ScriptableObject; 6 | 7 | import java.lang.reflect.InvocationTargetException; 8 | import java.util.Arrays; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | 12 | public class Module { 13 | 14 | static HashMap prototypes; 15 | 16 | /** 17 | * Define all filter constructors in the given module scope. If the 18 | * provided scope is not a "top level" scope, constructors will be defined 19 | * in the top level scope for the given scope. 20 | * @param scope 21 | * @throws IllegalAccessException 22 | * @throws InstantiationException 23 | * @throws java.lang.reflect.InvocationTargetException 24 | */ 25 | public static void init(Scriptable scope) throws IllegalAccessException, InstantiationException, InvocationTargetException { 26 | 27 | scope = ScriptableObject.getTopLevelScope(scope); 28 | 29 | @SuppressWarnings("unchecked") 30 | List> classes = Arrays.asList(Filter.class, Expression.class); 31 | 32 | prototypes = new HashMap(); 33 | for (Class cls : classes) { 34 | String name = ScriptableObject.defineClass(scope, cls, false, true); 35 | Scriptable prototype = ScriptableObject.getClassPrototype(scope, name); 36 | prototypes.put(name, prototype); 37 | } 38 | 39 | } 40 | 41 | protected static Scriptable getClassPrototype(Class cls) { 42 | String name = cls.getName(); 43 | if (prototypes == null || !prototypes.containsKey(name)) { 44 | throw new RuntimeException( 45 | "Attempt to access prototype before requiring module: " + name); 46 | } 47 | return prototypes.get(name); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/style/test_symbolizer.js: -------------------------------------------------------------------------------- 1 | var ASSERT = require("assert"); 2 | var STYLE = require("geoscript/style"); 3 | var Filter = require("geoscript/filter").Filter; 4 | 5 | exports["test: constructor"] = function() { 6 | 7 | var symbolizer = new STYLE.Symbolizer({}); 8 | 9 | ASSERT.ok(symbolizer instanceof STYLE.Symbolizer, "is Symbolizer"); 10 | 11 | }; 12 | 13 | exports["test: where"] = function() { 14 | 15 | var symbolizer = new STYLE.Symbolizer({}); 16 | 17 | ASSERT.ok(!symbolizer.filter, "no filter before where"); 18 | 19 | var o = symbolizer.where("foo='bar'"); 20 | 21 | ASSERT.ok(o === symbolizer, "where returns self"); 22 | ASSERT.ok(symbolizer.filter instanceof Filter, "where sets filter"); 23 | 24 | ASSERT.strictEqual(symbolizer.filter.cql, "foo = 'bar'", "correct filter"); 25 | 26 | }; 27 | 28 | exports["test: range"] = function() { 29 | 30 | var symbolizer = new STYLE.Symbolizer({}); 31 | 32 | ASSERT.ok(!symbolizer.minScaleDenominator, "no min before range"); 33 | ASSERT.ok(!symbolizer.maxScaleDenominator, "no max before range"); 34 | 35 | var o = symbolizer.range({min: 10, max: 20}); 36 | 37 | ASSERT.ok(o === symbolizer, "range returns self"); 38 | 39 | ASSERT.strictEqual(symbolizer.minScaleDenominator, 10, "correct min"); 40 | ASSERT.strictEqual(symbolizer.maxScaleDenominator, 20, "correct max"); 41 | 42 | }; 43 | 44 | exports["test: and"] = function() { 45 | 46 | var s1 = new STYLE.Symbolizer({}); 47 | var s2 = new STYLE.Symbolizer({}); 48 | 49 | var style = s1.and(s2); 50 | ASSERT.ok(style instanceof STYLE.Style, "is Style"); 51 | 52 | ASSERT.strictEqual(style.parts.length, 2, "composite has two parts"); 53 | ASSERT.ok(style.parts[0] === s1, "first part"); 54 | ASSERT.ok(style.parts[1] === s2, "second part"); 55 | 56 | }; 57 | 58 | if (require.main == module.id) { 59 | system.exit(require("test").run(exports)); 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/org/geoscript/js/index/Module.java: -------------------------------------------------------------------------------- 1 | package org.geoscript.js.index; 2 | 3 | import org.geoscript.js.GeoObject; 4 | import org.geoscript.js.index.*; 5 | import org.mozilla.javascript.Scriptable; 6 | import org.mozilla.javascript.ScriptableObject; 7 | 8 | import java.lang.reflect.InvocationTargetException; 9 | import java.util.Arrays; 10 | import java.util.HashMap; 11 | import java.util.List; 12 | 13 | public class Module { 14 | 15 | static HashMap prototypes; 16 | 17 | /** 18 | * Define all geometry constructors in the given module scope. If the 19 | * provided scope is not a "top level" scope, constructors will be defined 20 | * in the top level scope for the given scope. 21 | * @param scope 22 | * @throws IllegalAccessException 23 | * @throws InstantiationException 24 | * @throws InvocationTargetException 25 | */ 26 | public static void init(Scriptable scope) throws IllegalAccessException, InstantiationException, InvocationTargetException { 27 | 28 | scope = ScriptableObject.getTopLevelScope(scope); 29 | 30 | @SuppressWarnings("unchecked") 31 | List> classes = Arrays.asList(Quadtree.class, STRtree.class); 32 | 33 | prototypes = new HashMap(); 34 | for (Class cls : classes) { 35 | String name = ScriptableObject.defineClass(scope, cls, false, true); 36 | Scriptable prototype = ScriptableObject.getClassPrototype(scope, name); 37 | prototypes.put(name, prototype); 38 | } 39 | 40 | } 41 | 42 | protected static Scriptable getClassPrototype(Class cls) { 43 | String name = cls.getName(); 44 | if (prototypes == null || !prototypes.containsKey(name)) { 45 | throw new RuntimeException( 46 | "Attempt to access prototype before requiring module: " + name); 47 | } 48 | return prototypes.get(name); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/org/geoscript/js/feature/Module.java: -------------------------------------------------------------------------------- 1 | package org.geoscript.js.feature; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.util.Arrays; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | 8 | import org.geoscript.js.GeoObject; 9 | import org.mozilla.javascript.Scriptable; 10 | import org.mozilla.javascript.ScriptableObject; 11 | 12 | public class Module { 13 | 14 | static HashMap prototypes; 15 | 16 | /** 17 | * Define all feature related constructors in the given module scope. If 18 | * the provided scope is not a "top level" scope, constructors will be 19 | * defined in the top level scope for the given scope. 20 | * @param scope 21 | * @throws IllegalAccessException 22 | * @throws InstantiationException 23 | * @throws InvocationTargetException 24 | */ 25 | public static void init(Scriptable scope) throws IllegalAccessException, InstantiationException, InvocationTargetException { 26 | scope = ScriptableObject.getTopLevelScope(scope); 27 | 28 | @SuppressWarnings("unchecked") 29 | List> classes = Arrays.asList( 30 | Field.class, Schema.class, Feature.class, FeatureCollection.class, Iterator.class); 31 | 32 | prototypes = new HashMap(); 33 | for (Class cls : classes) { 34 | String name = ScriptableObject.defineClass(scope, cls, false, true); 35 | Scriptable prototype = ScriptableObject.getClassPrototype(scope, name); 36 | prototypes.put(name, prototype); 37 | } 38 | } 39 | 40 | protected static Scriptable getClassPrototype(Class cls) { 41 | String name = cls.getName(); 42 | if (prototypes == null || !prototypes.containsKey(name)) { 43 | throw new RuntimeException( 44 | "Attempt to access prototype before requiring module: " + name); 45 | } 46 | return prototypes.get(name); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/style/test_color.js: -------------------------------------------------------------------------------- 1 | var ASSERT = require("assert"); 2 | var STYLE = require("geoscript/style"); 3 | var Expression = require("geoscript/filter").Expression; 4 | 5 | exports["test: constructor"] = function() { 6 | 7 | var color = new STYLE.Color(); 8 | 9 | ASSERT.ok(color instanceof STYLE.Brush, "is Brush"); 10 | ASSERT.ok(color instanceof STYLE.Color, "is Color"); 11 | 12 | }; 13 | 14 | exports["test: value"] = function() { 15 | 16 | var color; 17 | 18 | // named color as config 19 | color = new STYLE.Color("blue"); 20 | ASSERT.strictEqual(color.value.text, "'#0000ff'", "string config with named color"); 21 | 22 | // hex value as config 23 | color = new STYLE.Color("#bada55"); 24 | ASSERT.strictEqual(color.value.text, "'#bada55'", "string config with hex value"); 25 | 26 | // rgb array as config 27 | color = new STYLE.Color([255, 0, 0]); 28 | ASSERT.strictEqual(color.value.text, "'#ff0000'", "rgb array config"); 29 | 30 | // config with named color 31 | color = new STYLE.Color({value: "lime"}); 32 | ASSERT.strictEqual(color.value.text, "'#00ff00'", "named color value"); 33 | 34 | // config with hex value 35 | color = new STYLE.Color({value: "#abcabc"}); 36 | ASSERT.strictEqual(color.value.text, "'#abcabc'", "hex value"); 37 | 38 | // config with hex value 39 | color = new STYLE.Color({value: [0, 255, 0]}); 40 | ASSERT.strictEqual(color.value.text, "'#00ff00'", "rgb array value"); 41 | 42 | color = new STYLE.Color(); 43 | 44 | // set value with named color 45 | color.value = "yellow"; 46 | ASSERT.strictEqual(color.value.text, "'#ffff00'", "named color"); 47 | 48 | color.value = "#bada55"; 49 | ASSERT.strictEqual(color.value.text, "'#bada55'", "hex value"); 50 | 51 | color.value = [0, 255, 187]; 52 | ASSERT.strictEqual(color.value.text, "'#00ffbb'", "rgb array"); 53 | 54 | }; 55 | 56 | if (require.main == module.id) { 57 | system.exit(require("test").run(exports)); 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/org/geoscript/js/index/Quadtree.java: -------------------------------------------------------------------------------- 1 | package org.geoscript.js.index; 2 | 3 | import org.geoscript.js.geom.Bounds; 4 | import org.mozilla.javascript.Context; 5 | import org.mozilla.javascript.Function; 6 | import org.mozilla.javascript.Scriptable; 7 | import org.mozilla.javascript.annotations.JSConstructor; 8 | import org.mozilla.javascript.annotations.JSFunction; 9 | import org.mozilla.javascript.annotations.JSGetter; 10 | 11 | public class Quadtree extends SpatialIndex { 12 | 13 | public Quadtree() { 14 | super(new org.locationtech.jts.index.quadtree.Quadtree()); 15 | } 16 | 17 | public Quadtree(Scriptable scope) { 18 | this(); 19 | this.setParentScope(scope); 20 | this.setPrototype(Module.getClassPrototype(Quadtree.class)); 21 | } 22 | 23 | 24 | @JSFunction 25 | public void insert(Bounds bounds, Object item) { 26 | this.index.insert(bounds.unwrap(), item); 27 | } 28 | 29 | @JSFunction 30 | public Object query(Bounds bounds) { 31 | return javaToJS(this.index.query(bounds.unwrap()), getParentScope()); 32 | } 33 | 34 | @JSGetter 35 | public int getSize() { 36 | return ((org.locationtech.jts.index.quadtree.Quadtree)this.index).size(); 37 | } 38 | 39 | @JSFunction 40 | public Object queryAll() { 41 | return javaToJS(((org.locationtech.jts.index.quadtree.Quadtree)this.index).queryAll(), getParentScope()); 42 | } 43 | 44 | @JSFunction 45 | public boolean remove(Bounds bounds, Object item) { 46 | return this.index.remove(bounds.unwrap(), item); 47 | } 48 | 49 | /** 50 | * JavaScript constructor. 51 | * @param cx 52 | * @param args 53 | * @param ctorObj 54 | * @param isNewExpr 55 | * @return 56 | */ 57 | @JSConstructor 58 | public static Object constructor(Context cx, Object[] args, Function ctorObj, boolean isNewExpr) { 59 | if (isNewExpr) { 60 | return new Quadtree(); 61 | } else { 62 | return new Quadtree(ctorObj.getParentScope()); 63 | } 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/resources/org/geoscript/js/lib/geoscript/filter.js: -------------------------------------------------------------------------------- 1 | var FILTER_UTIL = require("./filter/util"); 2 | 3 | /** api: module = filter */ 4 | 5 | /** api: synopsis 6 | * Filter related functionality. 7 | */ 8 | 9 | /** api: summary 10 | * The :mod:`filter` module provides a constructor for Filter objects. 11 | * 12 | * .. code-block:: javascript 13 | * 14 | * js> var FILTER = require("geoscript/filter"); 15 | */ 16 | 17 | /** api: classes[] = filter */ 18 | var Filter = exports.Filter = require("./filter/filter").Filter; 19 | /** api: classes[] = expression */ 20 | exports.Expression = require("./filter/expression").Expression; 21 | exports.and = Filter.and; 22 | exports.or = Filter.or; 23 | exports.not = Filter.not; 24 | exports.fids = Filter.fids; 25 | 26 | /** private: method[where] 27 | * Convenience method for creating filters. May be called in one of three 28 | * forms: 29 | * 30 | * 1. where(cql) - This is equivalent to new Filter(cql). 31 | * 32 | * 2. where(fn, arg1, arg2, ...) - Constructs cql from string arguments 33 | * assuming the first argument is a function name. E.g. 34 | * where("WITHIN", "the_geom", "POINT(1 1)"). 35 | * 36 | * 3. where(args) - Constructs a cql string from an array of strings assuming 37 | * the first item in the array is a function name. E.g. 38 | * where(["WITHIN", "the_geom", "POINT(1 1)"]). 39 | */ 40 | var where = exports.where = function() { 41 | var cql; 42 | if (arguments.length === 1 && typeof arguments[0] === "string") { 43 | cql = arguments[0]; 44 | } else { 45 | var args; 46 | if (arguments.length > 1) { 47 | args = Array.slice(arguments); 48 | } else { 49 | // assume an array is given for first arg 50 | args = arguments[0]; 51 | } 52 | cql = args[0] + "(" + args.slice(1).join(",") + ")"; 53 | } 54 | return new Filter(cql); 55 | }; 56 | 57 | /** private: method[create] 58 | * :arg config: ``Object`` Configuration object. 59 | * :returns: :class:`filter.Filter` 60 | * 61 | * Create a filter given a configuration object. 62 | */ 63 | exports.create = FILTER_UTIL.create; 64 | -------------------------------------------------------------------------------- /doc/api/style/style.rst: -------------------------------------------------------------------------------- 1 | :class:`style.Style` 2 | ==================== 3 | 4 | .. class:: style.Style 5 | 6 | Instances of the symbolizer base class are not created directly. 7 | See the constructor details for one of the symbolizer subclasses. 8 | 9 | Config Properties 10 | ----------------- 11 | 12 | .. describe:: zIndex 13 | 14 | ``Number`` The zIndex determines draw order of symbolizers. Symbolizers 15 | with higher zIndex values will be drawn over symbolizers with lower 16 | values. By default, symbolizers have a zIndex of ``0``. 17 | 18 | Properties 19 | ---------- 20 | 21 | .. attribute:: Style.filter 22 | 23 | :class:`filter.Filter` 24 | Filter that determines where this symbolizer applies. 25 | 26 | .. attribute:: Style.maxScaleDenominator 27 | 28 | ``Number`` 29 | Optional maximum scale denominator at which this symbolizer applies. 30 | 31 | .. attribute:: Style.minScaleDenominator 32 | 33 | ``Number`` 34 | Optional minimum scale denominator at which this symbolizer applies. 35 | 36 | .. attribute:: Style.zIndex 37 | 38 | ``Number`` 39 | The zIndex determines draw order of symbolizers. Symbolizers 40 | with higher zIndex values will be drawn over symbolizers with lower 41 | values. By default, symbolizers have a zIndex of ``0``. 42 | 43 | 44 | 45 | 46 | Methods 47 | ------- 48 | 49 | 50 | .. function:: Style.and 51 | 52 | :arg symbolizer: :class:`style.Symbolizer` 53 | :returns: :class:`style.Style` 54 | 55 | Generate a composite symbolizer from this symbolizer and the provided 56 | symbolizer. 57 | 58 | .. function:: Style.range 59 | 60 | :arg config: ``Object`` An object with optional ``min`` and ``max`` 61 | properties specifying the minimum and maximum scale denominators 62 | for applying this symbolizer. 63 | :returns: :class:`style.Symbolizer` This symbolizer. 64 | 65 | .. function:: Style.where 66 | 67 | :arg filter: :class:`filter.Filter` or ``String`` A filter or CQL string that 68 | limits where this symbolizer applies. 69 | :returns: :class:`style.Symbolizer` This symbolizer. 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /doc/api/io/json.rst: -------------------------------------------------------------------------------- 1 | The io/json module 2 | ================== 3 | 4 | .. code-block:: javascript 5 | 6 | >> var parser = require("geoscript/io/json"); 7 | 8 | Methods 9 | ------- 10 | 11 | 12 | .. function:: read 13 | 14 | :arg wkt: ``String`` The GeoJSON representation of a geometry or feature. 15 | :returns: :class:`Object` The deserialized version of the input string (one 16 | of :class:`geom.Geometry`, :class:`geom.GeometryCollection`, 17 | :class:`feature.Feature`, or :class:`feature.FeatureCollection`). 18 | 19 | Create a geometry, a feature, or a collection of either from a JSON string. 20 | 21 | Example of deserializing a geometry: 22 | 23 | .. code-block:: javascript 24 | 25 | >> var LineString = require("geoscript/geom").LineString; 26 | >> var line = parser.read('{"type": "LineString", "coordinates": [[1,2], [3,4]]}'); 27 | >> line instanceof LineString 28 | true 29 | >> line 30 | 31 | 32 | Example of deserializing a feature: 33 | 34 | .. code-block:: javascript 35 | 36 | >> var Feature = require("geoscript/feature").Feature; 37 | >> var str = '{"type": "Feature", "properties": {"foo": "bar"}, "geometry": {"type": "Point", "coordinates": [1, 2]}}' 38 | >> var feature = parser.read(str) 39 | >> feature instanceof Feature 40 | true 41 | >> feature 42 | > 43 | 44 | 45 | .. function:: write 46 | 47 | :arg obj: :class:`Object` Input object (one of :class:`geom.Geometry`, 48 | :class:`geom.GeometryCollection`, :class:`feature.Feature`, 49 | or :class:`feature.FeatureCollection`). 50 | :returns: ``String`` The GeoJSON representation of the input object. 51 | 52 | Generate a GeoJSON string from a geometry, a feature, or a collection of 53 | either. 54 | 55 | Example of serializing a geometry: 56 | 57 | .. code-block:: javascript 58 | 59 | >> var Point = require("geoscript/geom").Point; 60 | >> var str = parser.write(Point([1, 2])); 61 | >> str 62 | {"type":"Point","coordinates":[1,2]} 63 | 64 | -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/test_filter.js: -------------------------------------------------------------------------------- 1 | var ASSERT = require("assert"); 2 | var Feature = require("geoscript/feature").Feature; 3 | var FILTER = require("geoscript/filter"); 4 | 5 | exports["test and"] = function() { 6 | 7 | var f = FILTER.and(["name = 'foo'", "type = 'bar'"]); 8 | ASSERT.strictEqual(f.cql, "name = 'foo' AND type = 'bar'", "correct cql"); 9 | 10 | }; 11 | 12 | exports["test or"] = function() { 13 | 14 | var f = FILTER.or(["name = 'foo'", "type = 'bar'"]); 15 | ASSERT.strictEqual(f.cql, "name = 'foo' OR type = 'bar'", "correct cql"); 16 | 17 | }; 18 | 19 | exports["test not"] = function() { 20 | 21 | var f = FILTER.not("name = 'foo'"); 22 | ASSERT.strictEqual(f.cql, "NOT (name = 'foo')", "correct cql"); 23 | 24 | }; 25 | 26 | 27 | exports["test where"] = function() { 28 | 29 | var f = FILTER.where("name = 'foo'"); 30 | ASSERT.ok(f instanceof FILTER.Filter); 31 | 32 | var bar = new Feature({properties: {name: "foo"}}); 33 | ASSERT.isTrue(f.evaluate(bar), "bar passed"); 34 | 35 | f = FILTER.where("WITHIN", "the_geom", "POINT(1 1)"); 36 | ASSERT.strictEqual(f.cql, "WITHIN(the_geom, POINT (1 1))", "correct cql"); 37 | 38 | f = FILTER.where(["WITHIN", "the_geom", "POINT(1 1)"]); 39 | ASSERT.strictEqual(f.cql, "WITHIN(the_geom, POINT (1 1))", "correct cql"); 40 | 41 | } 42 | 43 | exports["test create"] = function() { 44 | 45 | var f = FILTER.create("name = 'foo'"); 46 | ASSERT.ok(f instanceof FILTER.Filter); 47 | 48 | var bar = new Feature({properties: {name: "foo"}}); 49 | ASSERT.isTrue(f.evaluate(bar), "bar passed"); 50 | 51 | var baz = new Feature({properties: {name: "baz"}}); 52 | ASSERT.isFalse(f.evaluate(baz), "baz didn't pass"); 53 | 54 | ASSERT.throws(function() { 55 | FILTER.create("bogus"); 56 | }, Error, "create throws with bogus CQL"); 57 | 58 | } 59 | 60 | exports["test Filter"] = require("./filter/test_filter"); 61 | exports["test Expression"] = require("./filter/test_expression"); 62 | 63 | if (require.main == module.id) { 64 | system.exit(require("test").run(exports)); 65 | } 66 | -------------------------------------------------------------------------------- /doc/api/style/icon.rst: -------------------------------------------------------------------------------- 1 | :class:`style.Icon` 2 | =================== 3 | 4 | .. class:: style.Icon 5 | 6 | A symbolizer that renders points using a graphic image. 7 | 8 | 9 | Config Properties 10 | ----------------- 11 | 12 | .. describe:: rotation 13 | 14 | ``Number`` 15 | Rotation angle in degrees clockwise about the center point of the 16 | shape. 17 | 18 | .. describe:: size 19 | 20 | ``Number`` 21 | The shape pixel size. Default is 6. 22 | 23 | .. describe:: url 24 | 25 | ``String`` 26 | The icon url. 27 | 28 | .. describe:: zIndex 29 | 30 | ``Number`` The zIndex determines draw order of symbolizers. Symbolizers 31 | with higher zIndex values will be drawn over symbolizers with lower 32 | values. By default, symbolizers have a zIndex of ``0``. 33 | 34 | 35 | Properties 36 | ---------- 37 | 38 | .. attribute:: Icon.filter 39 | 40 | :class:`filter.Filter` 41 | Optional filter that determines where this symbolizer applies. 42 | 43 | .. attribute:: Icon.opacity 44 | 45 | ``Number`` 46 | The opacity value (0 - 1). Default is ``1``. 47 | 48 | .. attribute:: Icon.rotation 49 | 50 | ``Number`` 51 | Rotation angle in degrees clockwise about the center point of the 52 | shape. 53 | 54 | .. attribute:: Icon.size 55 | 56 | :class:`filter.Expression` 57 | The shape pixel size. 58 | 59 | .. attribute:: Icon.url 60 | 61 | ``String`` 62 | The icon url. 63 | 64 | 65 | Methods 66 | ------- 67 | 68 | .. function:: Icon.and 69 | 70 | :arg symbolizer: :class:`style.Symbolizer` 71 | :returns: :class:`style.Style` 72 | 73 | Generate a composite style from this symbolizer and the provided 74 | symbolizer. 75 | 76 | .. function:: Icon.range 77 | 78 | :arg config: ``Object`` An object with optional ``min`` and ``max`` 79 | properties specifying the minimum and maximum scale denominators 80 | for applying this symbolizer. 81 | :returns: :class:`style.Symbolizer` This symbolizer. 82 | 83 | .. function:: Icon.where 84 | 85 | :arg filter: :class:`filter.Filter` or ``String`` A filter or CQL string that 86 | limits where this symbolizer applies. 87 | :returns: :class:`style.Symbolizer` This symbolizer. 88 | 89 | 90 | -------------------------------------------------------------------------------- /src/main/java/org/geoscript/js/geom/Module.java: -------------------------------------------------------------------------------- 1 | package org.geoscript.js.geom; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.util.Arrays; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | 8 | import org.geoscript.js.GeoObject; 9 | import org.mozilla.javascript.Scriptable; 10 | import org.mozilla.javascript.ScriptableObject; 11 | 12 | public class Module { 13 | 14 | static HashMap prototypes; 15 | 16 | /** 17 | * Define all geometry constructors in the given module scope. If the 18 | * provided scope is not a "top level" scope, constructors will be defined 19 | * in the top level scope for the given scope. 20 | * @param scope 21 | * @throws IllegalAccessException 22 | * @throws InstantiationException 23 | * @throws InvocationTargetException 24 | */ 25 | public static void init(Scriptable scope) throws IllegalAccessException, InstantiationException, InvocationTargetException { 26 | 27 | scope = ScriptableObject.getTopLevelScope(scope); 28 | 29 | @SuppressWarnings("unchecked") 30 | List> classes = Arrays.asList( 31 | Geometry.class, Point.class, LineString.class, 32 | Polygon.class, GeometryCollection.class, MultiPoint.class, 33 | MultiLineString.class, MultiPolygon.class, Bounds.class, 34 | CircularString.class, CompoundCurve.class); 35 | 36 | prototypes = new HashMap(); 37 | for (Class cls : classes) { 38 | String name = ScriptableObject.defineClass(scope, cls, false, true); 39 | Scriptable prototype = ScriptableObject.getClassPrototype(scope, name); 40 | prototypes.put(name, prototype); 41 | } 42 | 43 | } 44 | 45 | protected static Scriptable getClassPrototype(Class cls) { 46 | String name = cls.getName(); 47 | if (prototypes == null || !prototypes.containsKey(name)) { 48 | throw new RuntimeException( 49 | "Attempt to access prototype before requiring module: " + name); 50 | } 51 | return prototypes.get(name); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /doc/api/style/fill.rst: -------------------------------------------------------------------------------- 1 | :class:`style.Fill` 2 | =================== 3 | 4 | .. class:: style.Fill 5 | 6 | A symbolizer for filling polygon geometries. 7 | 8 | Example Use 9 | ----------- 10 | 11 | Sample code to create a fill: 12 | 13 | .. code-block:: javascript 14 | 15 | >> var Fill = require("geoscript/style").Fill; 16 | >> var fill = Fill({ 17 | .. brush: "red", 18 | .. opacity: 0.5 19 | .. }); 20 | 21 | 22 | Config Properties 23 | ----------------- 24 | 25 | .. describe:: brush 26 | 27 | :class:`style.Brush` 28 | The brush used to create this fill. This will typically be a 29 | :class:`Color` and can be given by the string hex value. 30 | 31 | .. describe:: opacity 32 | 33 | ``Number`` 34 | The opacity value (``0`` - ``1``). Default is ``1``. 35 | 36 | .. describe:: zIndex 37 | 38 | ``Number`` The zIndex determines draw order of symbolizers. Symbolizers 39 | with higher zIndex values will be drawn over symbolizers with lower 40 | values. By default, symbolizers have a zIndex of ``0``. 41 | 42 | 43 | 44 | 45 | Properties 46 | ---------- 47 | 48 | 49 | .. attribute:: Fill.brush 50 | 51 | :class:`style.Brush` 52 | The brush used to create this fill. 53 | 54 | .. attribute:: Fill.filter 55 | 56 | :class:`filter.Filter` 57 | Optional filter that determines where this symbolizer applies. 58 | 59 | .. attribute:: Fill.opacity 60 | 61 | ``Number`` 62 | The opacity value. 63 | 64 | 65 | Methods 66 | ------- 67 | 68 | .. function:: Fill.and 69 | 70 | :arg symbolizer: :class:`style.Symbolizer` 71 | :returns: :class:`style.Style` 72 | 73 | Generate a composite style from this symbolizer and the provided 74 | symbolizer. 75 | 76 | .. function:: Fill.range 77 | 78 | :arg config: ``Object`` An object with optional ``min`` and ``max`` 79 | properties specifying the minimum and maximum scale denominators 80 | for applying this symbolizer. 81 | :returns: :class:`style.Symbolizer` This symbolizer. 82 | 83 | .. function:: Fill.where 84 | 85 | :arg filter: :class:`filter.Filter` or ``String`` A filter or CQL string that 86 | limits where this symbolizer applies. 87 | :returns: :class:`style.Symbolizer` This symbolizer. 88 | 89 | -------------------------------------------------------------------------------- /doc/api/style/stroke.rst: -------------------------------------------------------------------------------- 1 | :class:`style.Stroke` 2 | ===================== 3 | 4 | .. class:: style.Stroke 5 | 6 | A symbolizer for stroking geometries. 7 | 8 | Config Properties 9 | ----------------- 10 | 11 | 12 | .. describe:: brush 13 | 14 | :class:`style.Brush` 15 | The brush used to create this stroke. This will typically be a 16 | :class:`Color` and can be given by the string hex value. 17 | 18 | .. describe:: opacity 19 | 20 | ``Number`` 21 | The opacity value (``0`` - ``1``). Default is ``1``. 22 | 23 | .. describe:: width 24 | 25 | ``Number`` 26 | The pixel width of the stroke. Default is ``1``. 27 | 28 | .. describe:: zIndex 29 | 30 | ``Number`` The zIndex determines draw order of symbolizers. Symbolizers 31 | with higher zIndex values will be drawn over symbolizers with lower 32 | values. By default, symbolizers have a zIndex of ``0``. 33 | 34 | 35 | 36 | 37 | Properties 38 | ---------- 39 | 40 | 41 | .. attribute:: Stroke.brush 42 | 43 | :class:`style.Brush` 44 | The brush used to create this stroke. 45 | 46 | .. attribute:: Stroke.filter 47 | 48 | :class:`filter.Filter` 49 | Optional filter that determines where this symbolizer applies. 50 | 51 | .. attribute:: Stroke.opacity 52 | 53 | ``Number`` 54 | The opacity value. 55 | 56 | .. attribute:: Stroke.width 57 | 58 | ``Number`` 59 | The pixel width of the stroke. 60 | 61 | 62 | 63 | 64 | Methods 65 | ------- 66 | 67 | 68 | .. function:: Stroke.and 69 | 70 | :arg symbolizer: :class:`style.Symbolizer` 71 | :returns: :class:`style.Style` 72 | 73 | Generate a composite style from this symbolizer and the provided 74 | symbolizer. 75 | 76 | .. function:: Stroke.range 77 | 78 | :arg config: ``Object`` An object with optional ``min`` and ``max`` 79 | properties specifying the minimum and maximum scale denominators 80 | for applying this symbolizer. 81 | :returns: :class:`style.Symbolizer` This symbolizer. 82 | 83 | .. function:: Stroke.where 84 | 85 | :arg filter: :class:`filter.Filter` or ``String`` A filter or CQL string that 86 | limits where this symbolizer applies. 87 | :returns: :class:`style.Symbolizer` This symbolizer. 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /examples/centroids-layer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This example demonstrates the creation of a new layer with features 3 | * representing the centroids of geometries in another layer. The new layer 4 | * has a similar schema to the original, with the exception of the default 5 | * geometry type. 6 | */ 7 | 8 | // import Directory and Layer constructors 9 | var Directory = require("geoscript/workspace").Directory; 10 | var Layer = require("geoscript/layer").Layer; 11 | 12 | // create a directory workspace from an existing directory on disk 13 | var dir = new Directory("examples/data/shapefiles"); 14 | 15 | // create a layer based on an existing shapefile in the directory 16 | var states = dir.get("states"); 17 | 18 | // create a new schema with a Point geometry type instead of MultiPolygon 19 | var schema = states.schema.clone({ 20 | // give the schema a new name 21 | name: "centroids", 22 | fields: [ 23 | // overwrite existing field named "the_geom" 24 | {name: "the_geom", type: "Point", projection: "EPSG:4326"} 25 | ] 26 | }); 27 | 28 | // create a new temporary layer with the new schema 29 | var centroids = new Layer({ 30 | schema: schema 31 | }); 32 | 33 | // add the layer to existing workspace (this creates a new shapefile on disk) 34 | dir.add(centroids); 35 | 36 | // iterate through the state features to create features with state centroids 37 | states.features.forEach(function(state) { 38 | var centroid = state.clone({ 39 | schema: schema, 40 | values: { 41 | // overwrite the geometry value with the state centroid 42 | the_geom: state.geometry.centroid 43 | } 44 | }); 45 | // add the new feature to the layer (this writes to the shapefile) 46 | centroids.add(centroid); 47 | }); 48 | 49 | // you can use the viewer module to draw collections of features or geometries 50 | var draw = require("geoscript/viewer").draw; 51 | var geometries = []; 52 | // add all state geometries to the array 53 | states.features.forEach(function(state) { 54 | geometries.push(state.geometry); 55 | }); 56 | // add buffered centroids so they will be visible 57 | centroids.features.forEach(function(centroid) { 58 | geometries.push(centroid.geometry.buffer(0.5)); 59 | }); 60 | // draw all geometries 61 | draw(geometries); 62 | -------------------------------------------------------------------------------- /src/main/java/org/geoscript/js/geom/GeometryWrapper.java: -------------------------------------------------------------------------------- 1 | package org.geoscript.js.geom; 2 | 3 | import org.mozilla.javascript.Scriptable; 4 | import org.mozilla.javascript.ScriptableObject; 5 | 6 | public class GeometryWrapper { 7 | 8 | public static ScriptableObject wrap(Scriptable scope, org.locationtech.jts.geom.Geometry geometry) { 9 | ScriptableObject wrapped = null; 10 | try { 11 | if (geometry instanceof org.locationtech.jts.geom.Point) { 12 | wrapped = new Point(scope, (org.locationtech.jts.geom.Point) geometry); 13 | } else if (geometry instanceof org.geotools.geometry.jts.CompoundCurve) { 14 | wrapped = new CompoundCurve(scope, (org.geotools.geometry.jts.CompoundCurve) geometry); 15 | } else if (geometry instanceof org.geotools.geometry.jts.CircularString) { 16 | wrapped = new CircularString(scope, (org.geotools.geometry.jts.CircularString) geometry); 17 | } else if (geometry instanceof org.locationtech.jts.geom.LineString) { 18 | wrapped = new LineString(scope, (org.locationtech.jts.geom.LineString) geometry); 19 | } else if (geometry instanceof org.locationtech.jts.geom.Polygon) { 20 | wrapped = new Polygon(scope, (org.locationtech.jts.geom.Polygon) geometry); 21 | } else if (geometry instanceof org.locationtech.jts.geom.MultiPoint) { 22 | wrapped = new MultiPoint(scope, (org.locationtech.jts.geom.MultiPoint) geometry); 23 | } else if (geometry instanceof org.locationtech.jts.geom.MultiLineString) { 24 | wrapped = new MultiLineString(scope, (org.locationtech.jts.geom.MultiLineString) geometry); 25 | } else if (geometry instanceof org.locationtech.jts.geom.MultiPolygon) { 26 | wrapped = new MultiPolygon(scope, (org.locationtech.jts.geom.MultiPolygon) geometry); 27 | } else if (geometry instanceof org.locationtech.jts.geom.GeometryCollection) { 28 | wrapped = new GeometryCollection(scope, (org.locationtech.jts.geom.GeometryCollection) geometry); 29 | } 30 | } catch (Exception e) { 31 | throw new RuntimeException("Trouble wrapping geometry", e); 32 | } 33 | return wrapped; 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/geom/test_circularstring.js: -------------------------------------------------------------------------------- 1 | var ASSERT = require("assert"); 2 | var GEOM = require("geoscript/geom"); 3 | var PROJ = require("geoscript/proj"); 4 | var WKT = require("geoscript/io/wkt"); 5 | 6 | exports["test: constructor"] = function() { 7 | 8 | var checkPoint = function(i, pt, x, y) { 9 | ASSERT.ok(pt instanceof GEOM.Point, "cr control point #" + i + " is a point"); 10 | ASSERT.strictEqual(pt.x, x, "cr control point #" + i + " x is " + x); 11 | ASSERT.strictEqual(pt.y, y, "cr control point #" + i + " y is " + y); 12 | }; 13 | 14 | var cs = new GEOM.CircularString([[6.12, 10.0], [7.07, 7.07], [10.0, 0.0]]); 15 | 16 | ASSERT.ok(cs instanceof GEOM.Geometry, "cs is a geometry"); 17 | ASSERT.ok(cs instanceof GEOM.CircularString, "cs is a circularstring"); 18 | ASSERT.strictEqual(cs.controlPoints.length, 3, "cs has three control points"); 19 | checkPoint(0, cs.controlPoints[0], 6.12, 10.0); 20 | checkPoint(1, cs.controlPoints[1], 7.07, 7.07); 21 | checkPoint(2, cs.controlPoints[2], 10.0, 0.0); 22 | ASSERT.ok(cs.linear instanceof GEOM.LineString,"cs linear is a linestring"); 23 | ASSERT.strictEqual("CIRCULARSTRING (6.12 10.0, 7.07 7.07, 10.0 0.0)", cs.curvedWkt, "cs curved wkt is CIRCULARSTRING (6.12 10.0, 7.07 7.07, 10.0 0.0)"); 24 | var csFromWkt = WKT.read("CIRCULARSTRING (6.12 10.0, 7.07 7.07, 10.0 0.0)"); 25 | ASSERT.deepEqual(cs, csFromWkt); 26 | 27 | var p0 = new GEOM.Point([6.12, 10.0]); 28 | var p1 = new GEOM.Point([7.07, 7.07]); 29 | var p2 = new GEOM.Point([10.0, 0.0]); 30 | var cs2 = new GEOM.CircularString([p0, p1, p2]); 31 | 32 | ASSERT.ok(cs2 instanceof GEOM.Geometry, "cs2 is a geometry"); 33 | ASSERT.ok(cs2 instanceof GEOM.CircularString, "cs2 is a circularstring"); 34 | ASSERT.strictEqual(cs2.controlPoints.length, 3, "cs2 has three control points"); 35 | checkPoint(0, cs.controlPoints[0], 6.12, 10.0); 36 | checkPoint(1, cs.controlPoints[1], 7.07, 7.07); 37 | checkPoint(2, cs.controlPoints[2], 10.0, 0.0); 38 | ASSERT.ok(cs2.linear instanceof GEOM.LineString,"cs2 linear is a linestring"); 39 | ASSERT.strictEqual("CIRCULARSTRING (6.12 10.0, 7.07 7.07, 10.0 0.0)", cs2.curvedWkt, "cs2 curved wkt is CIRCULARSTRING (6.12 10.0, 7.07 7.07, 10.0 0.0)"); 40 | 41 | }; -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/test_layer.js: -------------------------------------------------------------------------------- 1 | var ASSERT = require("assert"); 2 | var LAYER = require("geoscript/layer"); 3 | var GEOM = require("geoscript/geom"); 4 | var ADMIN = require("../admin"); 5 | var Directory = require("geoscript/workspace").Directory; 6 | 7 | var shpDir = ADMIN.shp.dest; 8 | exports.setUp = ADMIN.shp.setUp; 9 | exports.tearDown = ADMIN.shp.tearDown; 10 | 11 | exports["test: Layer.constructor"] = function() { 12 | 13 | var l = new LAYER.Layer(); 14 | ASSERT.ok(l instanceof LAYER.Layer, "instanceof LAYER.Layer"); 15 | 16 | }; 17 | 18 | exports["test: Layer.clone"] = function() { 19 | 20 | var clone; 21 | var temp = new LAYER.Layer({ 22 | name: "foo", 23 | fields: [{name: "bar", type: "String"}] 24 | }); 25 | 26 | // create a clone without providing a name 27 | clone = temp.clone(); 28 | ASSERT.ok(clone instanceof LAYER.Layer, "clone is a LAYER.Layer"); 29 | ASSERT.ok(typeof clone.name === "string", "clone has a name"); 30 | ASSERT.ok(clone.name !== temp.name, "clone gets a new name"); 31 | 32 | // create a clone with a new name 33 | clone = temp.clone("bar"); 34 | ASSERT.strictEqual(clone.name, "bar", "clone can be given a new name"); 35 | 36 | // clone an existing layer with features 37 | var shp = Directory(shpDir).get("states"); 38 | 39 | clone = shp.clone(); 40 | ASSERT.ok(clone.temporary, "clone is a temporary layer"); 41 | ASSERT.strictEqual(clone.count, shp.count, "clone has same count as original"); 42 | 43 | }; 44 | 45 | exports["test: create(memory)"] = function() { 46 | 47 | var mem = LAYER.create({fields: [{name: "foo", type: "String"}]}); 48 | 49 | ASSERT.ok(mem instanceof LAYER.Layer, "instanceof LAYER.Layer"); 50 | ASSERT.ok(mem.temporary, "temporary layer"); 51 | 52 | }; 53 | 54 | exports["test: (Shapefile)"] = require("./layer/test_shapefile"); 55 | // TODO: determine why layer.update test is failing for H2 56 | // exports["test: (H2)"] = require("./layer/test_h2"); 57 | // TODO: add test setup to create temp db 58 | // exports["test: (PostGIS)"] = require("./layer/test_postgis"); 59 | exports["test: (Memory)"] = require("./layer/test_memory"); 60 | 61 | if (require.main == module.id) { 62 | system.exit(require("test").run(exports)); 63 | } 64 | -------------------------------------------------------------------------------- /doc/api/workspace/mysql.rst: -------------------------------------------------------------------------------- 1 | :class:`workspace.MySQL` 2 | ======================== 3 | 4 | .. class:: workspace.MySQL(config) 5 | 6 | :arg config: ``Object`` Configuration object. 7 | 8 | Create a workspace from a MySQL database. 9 | 10 | Config Properties 11 | ----------------- 12 | 13 | 14 | .. describe:: database 15 | 16 | ``String`` 17 | Database name (required). 18 | 19 | .. describe:: host 20 | 21 | ``String`` 22 | Hostname for database connection. Default is ``"localhost"``. 23 | 24 | .. describe:: password 25 | 26 | ``String`` 27 | Password for database connection. Default is ``"mysql"``. 28 | 29 | .. describe:: port 30 | 31 | ``Number`` 32 | Port for database connection. Default is ``3306``. 33 | 34 | .. describe:: user 35 | 36 | ``String`` 37 | Username for database connection. Default is ``"root"``. 38 | 39 | 40 | Properties 41 | ---------- 42 | 43 | 44 | .. attribute:: MySQL.layers 45 | 46 | ``Array`` 47 | The available layers in the workspace. 48 | 49 | .. attribute:: MySQL.names 50 | 51 | ``Array`` 52 | The available layer names in the workspace. 53 | 54 | 55 | Methods 56 | ------- 57 | 58 | 59 | .. function:: MySQL.add 60 | 61 | :arg layer: :class:`layer.Layer` The layer to be added. 62 | :arg options: ``Object`` Options for adding the layer. 63 | 64 | Options: 65 | 66 | * `name`: ``String`` Name for the new layer. 67 | * `filter`: :class:`filter.Filter` Filter to apply to features before adding. 68 | * `projection`: :class:`proj.Projection` Destination projection for the layer. 69 | 70 | :returns: :class:`layer.Layer` 71 | 72 | Create a new layer in this workspace with the features from an existing 73 | layer. If a layer with the same name already exists in this workspace, 74 | you must provide a new name for the layer. 75 | 76 | .. function:: MySQL.close 77 | 78 | Close the workspace. This discards any existing connection to the 79 | underlying data store and discards the reference to the store. 80 | 81 | .. function:: MySQL.get 82 | 83 | :arg name: ``String`` Layer name. 84 | :returns: :class:`layer.Layer` 85 | 86 | Get a layer by name. Returns ``undefined`` if name doesn't correspond 87 | to a layer source in the workspace. 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /doc/api/geom/linestring.rst: -------------------------------------------------------------------------------- 1 | :class:`geom.LineString` 2 | ======================== 3 | 4 | .. class:: geom.LineString(coords) 5 | 6 | :arg Array coords: Coordinates array. 7 | 8 | Create a new linestring. 9 | 10 | 11 | Example Use 12 | ----------- 13 | 14 | Sample code to new linestring: 15 | 16 | .. code-block:: javascript 17 | 18 | >> var LineString = require("geoscript/geom").LineString; 19 | >> var line = LineString([[-180, -90], [0, 0], [180, 90]]); 20 | >> line.coordinates.length 21 | 3 22 | >> line.length 23 | 402.49223594996215 24 | 25 | 26 | Properties 27 | ---------- 28 | 29 | In addition to the properties common to all :class:`geom.Geometry` subclasses, 30 | linestring geometries have the properties documented below. 31 | 32 | 33 | .. attribute:: LineString.endPoint 34 | 35 | :class:`geom.Point` 36 | The last point in the linestring. 37 | 38 | .. attribute:: LineString.endPoints 39 | 40 | ``Array`` 41 | List of start point and end point. 42 | 43 | 44 | .. attribute:: LineString.startPoint 45 | 46 | :class:`geom.Point` 47 | The first point in the linestring. 48 | 49 | 50 | 51 | Methods 52 | ------- 53 | 54 | Linestring geometries have the methods common to all :class:`geom.Geometry` 55 | subclasses. 56 | 57 | .. function:: LineString.interpolatePoint 58 | 59 | :arg position: ``Number`` The position between 0 and 1. 60 | :returns: :class:`geom.Point` 61 | 62 | Returns a Point placed on the LineString at the given percentage along 63 | the LineString. 64 | 65 | .. function:: LineString.locatePoint 66 | 67 | :arg point: :class:`geom.Point` The Point 68 | :returns: ``Number`` The position (0-1) or percentage of the Point along the LineString. 69 | 70 | Returns a position or percentage between 0 and 1 of the Point along the LineString. 71 | 72 | .. function:: LineString.placePoint 73 | 74 | :arg point: :class:`geom.Point` The Point. 75 | :returns: :class:`geom.Point` The Point on the LineString. 76 | 77 | Places or snaps the Point to the LineString. 78 | 79 | .. function:: LineString.subLine 80 | 81 | :arg start: ``Number`` The start position between 0 and 1. 82 | :arg end: ``Number`` The end position between 0 and 1. 83 | :returns: :class:`geom.LineString` The sub LineString 84 | 85 | Returns a position or percentage between 0 and 1 of the Point along the LineString. -------------------------------------------------------------------------------- /src/main/resources/org/geoscript/js/lib/geoscript/workspace/geobuf.js: -------------------------------------------------------------------------------- 1 | var register = require("./util").register; 2 | var Factory = require("../factory").Factory; 3 | var Workspace = require("./workspace").Workspace; 4 | var UTIL = require("../util"); 5 | 6 | var GeobufDataStoreFactory = Packages.org.geotools.data.geobuf.GeobufDataStoreFactory; 7 | 8 | /** private: (define) 9 | * module = workspace 10 | * class = Geobuf 11 | */ 12 | 13 | var prepConfig = function(config) { 14 | if (config) { 15 | if (typeof config === "string") { 16 | config = {file: config}; 17 | } 18 | if (!(typeof config.file === "string")) { 19 | throw "Geobuf config must include file path."; 20 | } 21 | config = { 22 | file: String(config.file) 23 | }; 24 | } 25 | return config; 26 | }; 27 | 28 | /** private: (extends) 29 | * workspace/workspace.js 30 | */ 31 | var Geobuf = UTIL.extend(Workspace, { 32 | 33 | /** private: config[file] 34 | * ``String`` 35 | * Path to the directory (required). 36 | */ 37 | 38 | /** private: constructor 39 | * .. class:: Geobuf 40 | * 41 | * :arg config: ``Object`` Configuration object. 42 | * 43 | * Create a workspace from a Geobuf directory. 44 | */ 45 | constructor: function Geobuf(config) { 46 | Workspace.prototype.constructor.apply(this, [prepConfig(config)]); 47 | }, 48 | 49 | /** private: method[_create] 50 | * :arg config: ``Object`` 51 | * :returns: ``org.geotools.data.geobuf.GeobufDataStore`` 52 | * 53 | * Create the underlying store for the workspace. 54 | */ 55 | _create: function(config) { 56 | var factory = new GeobufDataStoreFactory(); 57 | return factory.createDataStore(config); 58 | }, 59 | 60 | /** private: property[config] 61 | */ 62 | get config() { 63 | return { 64 | type: this.constructor.name, 65 | file: this.file 66 | }; 67 | } 68 | 69 | }); 70 | 71 | exports.Geobuf = Geobuf; 72 | 73 | // register a Geobuf factory for the module 74 | register(new Factory(Geobuf, { 75 | handles: function(config) { 76 | var capable = false; 77 | if (typeof config.type === "string" && config.type.toLowerCase() === "Geobuf") { 78 | try { 79 | config = prepConfig(config); 80 | capable = true; 81 | } catch (err) { 82 | // pass 83 | } 84 | } 85 | return capable; 86 | } 87 | })); 88 | -------------------------------------------------------------------------------- /doc/api/style/label.rst: -------------------------------------------------------------------------------- 1 | :class:`style.Label` 2 | ==================== 3 | 4 | .. class:: style.Label 5 | 6 | A symbolizer for labeling features. 7 | 8 | Example Use 9 | ----------- 10 | 11 | Sample code to create a fill: 12 | 13 | .. code-block:: javascript 14 | 15 | >> var Label = require("geoscript/style").Label; 16 | >> var label = Label({ 17 | .. expression: "property" 18 | .. }); 19 | 20 | Config Properties 21 | ----------------- 22 | 23 | .. describe:: expression 24 | 25 | :class:`filter.Expression` 26 | 27 | .. describe:: fontFamily 28 | 29 | ``String`` 30 | 31 | .. describe:: fontSize 32 | 33 | ``Number`` 34 | 35 | .. describe:: fontStyle 36 | 37 | ``String`` 38 | 39 | .. describe:: fontWeight 40 | 41 | ``String`` 42 | 43 | .. describe:: zIndex 44 | 45 | ``Number`` The zIndex determines draw order of symbolizers. Symbolizers 46 | with higher zIndex values will be drawn over symbolizers with lower 47 | values. By default, symbolizers have a zIndex of ``0``. 48 | 49 | 50 | 51 | 52 | Properties 53 | ---------- 54 | 55 | 56 | .. attribute:: Label.expression 57 | 58 | :class:`filter.Expression` 59 | 60 | .. attribute:: Label.filter 61 | 62 | :class:`filter.Filter` 63 | Optional filter that determines where this symbolizer applies. 64 | 65 | .. attribute:: Label.fontFamily 66 | 67 | ``String`` 68 | 69 | .. attribute:: Label.fontSize 70 | 71 | ``Number`` 72 | 73 | .. attribute:: Label.fontStyle 74 | 75 | ``String`` 76 | 77 | .. attribute:: Label.fontWeight 78 | 79 | ``String`` 80 | 81 | 82 | Methods 83 | ------- 84 | 85 | .. function:: Label.and 86 | 87 | :arg symbolizer: :class:`style.Symbolizer` 88 | :returns: :class:`style.Style` 89 | 90 | Generate a composite style from this symbolizer and the provided 91 | symbolizer. 92 | 93 | .. function:: Label.range 94 | 95 | :arg config: ``Object`` An object with optional ``min`` and ``max`` 96 | properties specifying the minimum and maximum scale denominators 97 | for applying this symbolizer. 98 | :returns: :class:`style.Symbolizer` This symbolizer. 99 | 100 | .. function:: Label.where 101 | 102 | :arg filter: :class:`filter.Filter` or ``String`` A filter or CQL string that 103 | limits where this symbolizer applies. 104 | :returns: :class:`style.Symbolizer` This symbolizer. 105 | 106 | -------------------------------------------------------------------------------- /src/main/resources/org/geoscript/js/lib/geoscript/workspace/flatgeobuf.js: -------------------------------------------------------------------------------- 1 | var register = require("./util").register; 2 | var Factory = require("../factory").Factory; 3 | var Workspace = require("./workspace").Workspace; 4 | var UTIL = require("../util"); 5 | 6 | var URLs = Packages.org.geotools.util.URLs; 7 | var FlatGeobufDataStoreFactory = Packages.org.geotools.data.flatgeobuf.FlatGeobufDataStoreFactory; 8 | 9 | /** private: (define) 10 | * module = workspace 11 | * class = Flatgeobuf 12 | */ 13 | 14 | var prepConfig = function(config) { 15 | if (config) { 16 | if (typeof config === "string") { 17 | config = {'url': config}; 18 | } 19 | if (!(typeof config.file === "string")) { 20 | throw "Flatgeobuf config must include file path."; 21 | } 22 | config = { 23 | 'url': String(URLs.fileToUrl(UTIL.toFile(config.file))) 24 | }; 25 | } 26 | return config; 27 | }; 28 | 29 | /** private: (extends) 30 | * workspace/workspace.js 31 | */ 32 | var Flatgeobuf = UTIL.extend(Workspace, { 33 | 34 | /** private: config[file] 35 | * ``String`` 36 | * Path to the file (required). 37 | */ 38 | 39 | /** private: constructor 40 | * .. class:: Flatgeobuf 41 | * 42 | * :arg config: ``Object`` Configuration object. 43 | * 44 | * Create a workspace from a Flatgeobuf directory. 45 | */ 46 | constructor: function Flatgeobuf(config) { 47 | Workspace.prototype.constructor.apply(this, [prepConfig(config)]); 48 | }, 49 | 50 | /** private: method[_create] 51 | * :arg config: ``Object`` 52 | * :returns: ``org.geotools.data.flatgeobuf.FlatgeobufDataStore`` 53 | * 54 | * Create the underlying store for the workspace. 55 | */ 56 | _create: function(config) { 57 | var factory = new FlatGeobufDataStoreFactory(); 58 | return factory.createDataStore(config); 59 | }, 60 | 61 | /** private: property[config] 62 | */ 63 | get config() { 64 | return { 65 | type: this.constructor.name, 66 | file: this.file 67 | }; 68 | } 69 | 70 | }); 71 | 72 | exports.Flatgeobuf = Flatgeobuf; 73 | 74 | // register a Flatgeobuf factory for the module 75 | register(new Factory(Flatgeobuf, { 76 | handles: function(config) { 77 | var capable = false; 78 | if (typeof config.type === "string" && config.type.toLowerCase() === "Flatgeobuf") { 79 | try { 80 | config = prepConfig(config); 81 | capable = true; 82 | } catch (err) { 83 | // pass 84 | } 85 | } 86 | return capable; 87 | } 88 | })); 89 | -------------------------------------------------------------------------------- /src/main/resources/org/geoscript/js/lib/geoscript/workspace/geopackage.js: -------------------------------------------------------------------------------- 1 | var register = require("./util").register; 2 | var Factory = require("../factory").Factory; 3 | var Workspace = require("./workspace").Workspace; 4 | var UTIL = require("../util"); 5 | 6 | var GeoPkgDataStoreFactory = Packages.org.geotools.geopkg.GeoPkgDataStoreFactory; 7 | 8 | /** private: (define) 9 | * module = workspace 10 | * class = GeoPackage 11 | */ 12 | 13 | var prepConfig = function(config) { 14 | if (config) { 15 | if (typeof config === "string") { 16 | config = {database: config}; 17 | } 18 | if (!(typeof config.database === "string" || config.database instanceof file.Path)) { 19 | throw "GeoPackage config must include database path."; 20 | } 21 | config = { 22 | database: String(config.database) 23 | }; 24 | } 25 | return config; 26 | }; 27 | 28 | /** private: (extends) 29 | * workspace/workspace.js 30 | */ 31 | var GeoPackage = UTIL.extend(Workspace, { 32 | 33 | /** private: config[database] 34 | * ``String`` 35 | * Path to the database (required). 36 | */ 37 | 38 | /** private: constructor 39 | * .. class:: GeoPackage 40 | * 41 | * :arg config: ``Object`` Configuration object. 42 | * 43 | * Create a workspace from a GeoPackage enabled database. 44 | */ 45 | constructor: function GeoPackage(config) { 46 | Workspace.prototype.constructor.apply(this, [prepConfig(config)]); 47 | }, 48 | 49 | /** private: method[_create] 50 | * :arg config: ``Object`` 51 | * :returns: ``org.geotools.jdbc.JDBCDataStore`` 52 | * 53 | * Create the underlying store for the workspace. 54 | */ 55 | _create: function(config) { 56 | config.dbtype = "geopkg"; 57 | var factory = new GeoPkgDataStoreFactory(); 58 | return factory.createDataStore(config); 59 | }, 60 | 61 | /** private: property[config] 62 | */ 63 | get config() { 64 | return { 65 | type: this.constructor.name, 66 | database: this.database 67 | }; 68 | } 69 | 70 | }); 71 | 72 | exports.GeoPackage = GeoPackage; 73 | 74 | // register a geopackage factory for the module 75 | register(new Factory(GeoPackage, { 76 | handles: function(config) { 77 | var capable = false; 78 | if (typeof config.type === "string" && config.type.toLowerCase() === "geopackage") { 79 | try { 80 | config = prepConfig(config); 81 | capable = true; 82 | } catch (err) { 83 | // pass 84 | } 85 | } 86 | return capable; 87 | } 88 | })); 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Current Status](https://secure.travis-ci.org/geoscript/geoscript-js.png?branch=master)](https://travis-ci.org/geoscript/geoscript-js) 2 | 3 | [![Build Status](https://github.com/geoscript/geoscript-js/workflows/Maven%20Build/badge.svg)](https://github.com/geoscript/geoscript-js/actions) 4 | 5 | # geoscript.js 6 | 7 | ## GeoScript in JavaScript 8 | 9 | Copyright (c) 2009-2013 Tim Schaub 10 | 11 | Released under the MIT license. Please see the license.txt for full detail. 12 | 13 | ### Download and Installation 14 | 15 | The latest release of GeoScript JS can be found on the [downloads page](http://geoscript.net/js/download.html). To install, extract the zip archive somewhere onto your filesystem. In the `bin` folder you'll find a `geoscript` executable. Adding this `bin` folder to your path makes for easy launching of GeoScript from anywhere. 16 | 17 | ### Running GeoScript JS 18 | 19 | Change into the directory where you extracted the GeoScript JS download. From there, you can launch the GeoScript JS shell. 20 | 21 | ./bin/geoscript-js 22 | 23 | Once running the shell, you can pull in GeoScript modules with `require`. 24 | 25 | js> var geom = require("geoscript/geom") 26 | js> var p = new geom.Point([1, 2]) 27 | js> p.buffer(10) 28 | 29 | 30 | When you're done in the shell, exit with `quit()`. 31 | 32 | js> quit() 33 | 34 | To run a script that uses the GeoScript JS modules, include the path to your script. 35 | 36 | ./bin/geoscript-js yourscript.js 37 | 38 | ### Learning GeoScript JS 39 | 40 | See the [GeoScript JS website](http://geoscript.net/js/) for details on getting started using GeoScript JS. 41 | 42 | ### Getting set up for development 43 | 44 | If you'd like to contribute to GeoScript JS development, clone the repository and then use Maven to pull in dependencies and run tests. 45 | 46 | git clone git://github.com/tschaub/geoscript-js.git 47 | cd geoscript-js 48 | mvn install 49 | 50 | After pulling down the dependencies, you can launch the shell and use GeoScript JS modules as described above - with one exception: use the `geoscript-dev` script in the `bin` directory. 51 | 52 | ### Generating a release 53 | 54 | Update version numbers in the main pom.xml file. Generate an archive with all dependencies included: 55 | 56 | mvn assembly:single 57 | 58 | Deploy both the stand-alone archive and a jar with just the GeoScript JS modules (that depends on GeoTools): 59 | 60 | mvn deploy 61 | 62 | -------------------------------------------------------------------------------- /src/main/java/org/geoscript/js/feature/Iterator.java: -------------------------------------------------------------------------------- 1 | package org.geoscript.js.feature; 2 | 3 | import org.geoscript.js.GeoObject; 4 | import org.geotools.data.simple.SimpleFeatureIterator; 5 | import org.mozilla.javascript.Context; 6 | import org.mozilla.javascript.Function; 7 | import org.mozilla.javascript.JavaScriptException; 8 | import org.mozilla.javascript.NativeIterator; 9 | import org.mozilla.javascript.ScriptRuntime; 10 | import org.mozilla.javascript.Scriptable; 11 | import org.mozilla.javascript.annotations.JSConstructor; 12 | import org.mozilla.javascript.annotations.JSFunction; 13 | import org.opengis.feature.simple.SimpleFeature; 14 | 15 | public class Iterator extends GeoObject { 16 | 17 | /** serialVersionUID */ 18 | private static final long serialVersionUID = 123388411616403866L; 19 | 20 | SimpleFeatureIterator iterator; 21 | Scriptable layer; 22 | 23 | /** 24 | * Prototype constructor. 25 | */ 26 | public Iterator() { 27 | } 28 | 29 | public Iterator(Scriptable scope, SimpleFeatureIterator iterator) { 30 | this.iterator = iterator; 31 | setParentScope(scope); 32 | this.setPrototype(Module.getClassPrototype(Iterator.class)); 33 | } 34 | 35 | @JSConstructor 36 | public static Object constructor(Context cx, Object[] args, Function ctorObj, boolean inNewExpr) { 37 | throw ScriptRuntime.constructError("Error", "Iterators are for internal use only"); 38 | } 39 | 40 | public void setLayer(Scriptable layer) { 41 | this.layer = layer; 42 | } 43 | 44 | @JSFunction 45 | public Boolean hasNext() { 46 | boolean has = iterator.hasNext(); 47 | if (!has) { 48 | close(); 49 | } 50 | return has; 51 | } 52 | 53 | @JSFunction 54 | public Feature next() { 55 | Feature feature = null; 56 | if (hasNext()) { 57 | SimpleFeature simpleFeature = iterator.next(); 58 | feature = new Feature(getParentScope(), simpleFeature); 59 | if (layer != null) { 60 | feature.setLayer(layer); 61 | } 62 | } else { 63 | throw new JavaScriptException( 64 | NativeIterator.getStopIterationObject(getParentScope()), null, 0); 65 | } 66 | return feature; 67 | } 68 | 69 | public void close() { 70 | try { 71 | iterator.close(); 72 | } catch (Exception e) { 73 | // pass 74 | } 75 | } 76 | 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/main/resources/org/geoscript/js/lib/geoscript/workspace/spatialite.js: -------------------------------------------------------------------------------- 1 | var register = require("./util").register; 2 | var Factory = require("../factory").Factory; 3 | var Workspace = require("./workspace").Workspace; 4 | var UTIL = require("../util"); 5 | 6 | var SpatiaLiteDataStoreFactory = Packages.org.geotools.data.spatialite.SpatiaLiteDataStoreFactory; 7 | 8 | /** private: (define) 9 | * module = workspace 10 | * class = SpatiaLite 11 | */ 12 | 13 | var prepConfig = function(config) { 14 | if (config) { 15 | if (typeof config === "string") { 16 | config = {database: config}; 17 | } 18 | if (!(typeof config.database === "string" || config.database instanceof file.Path)) { 19 | throw "SpatiaLite config must include database path."; 20 | } 21 | config = { 22 | database: String(config.database) 23 | }; 24 | } 25 | return config; 26 | }; 27 | 28 | /** private: (extends) 29 | * workspace/workspace.js 30 | */ 31 | var SpatiaLite = UTIL.extend(Workspace, { 32 | 33 | /** private: config[database] 34 | * ``String`` 35 | * Path to the database (required). 36 | */ 37 | 38 | /** private: constructor 39 | * .. class:: SpatiaLite 40 | * 41 | * :arg config: ``Object`` Configuration object. 42 | * 43 | * Create a workspace from a SpatiaLite enabled database. 44 | */ 45 | constructor: function SpatiaLite(config) { 46 | Workspace.prototype.constructor.apply(this, [prepConfig(config)]); 47 | }, 48 | 49 | /** private: method[_create] 50 | * :arg config: ``Object`` 51 | * :returns: ``org.geotools.jdbc.JDBCDataStore`` 52 | * 53 | * Create the underlying store for the workspace. 54 | */ 55 | _create: function(config) { 56 | config.dbtype = "spatialite"; 57 | var factory = new SpatiaLiteDataStoreFactory(); 58 | return factory.createDataStore(config); 59 | }, 60 | 61 | /** private: property[config] 62 | */ 63 | get config() { 64 | return { 65 | type: this.constructor.name, 66 | database: this.database 67 | }; 68 | } 69 | 70 | }); 71 | 72 | exports.SpatiaLite = SpatiaLite; 73 | 74 | // register a spatialite factory for the module 75 | register(new Factory(SpatiaLite, { 76 | handles: function(config) { 77 | var capable = false; 78 | if (typeof config.type === "string" && config.type.toLowerCase() === "spatialite") { 79 | try { 80 | config = prepConfig(config); 81 | capable = true; 82 | } catch (err) { 83 | // pass 84 | } 85 | } 86 | return capable; 87 | } 88 | })); 89 | -------------------------------------------------------------------------------- /doc/api/filter/filter.rst: -------------------------------------------------------------------------------- 1 | :class:`filter.Filter` 2 | ====================== 3 | 4 | .. class:: filter.Filter 5 | 6 | :arg cql: `String` A CQL string representing filter constraints. 7 | 8 | Create a new filter to express constraints. Filters are typically 9 | used when querying features from a layer. A feature will be 10 | returned in a query if the filter's :func:`~Filter.evaluate` method returns 11 | `true` for the given feature. 12 | 13 | Filters are created using Common Query Language (CQL). 14 | 15 | Example Use 16 | ----------- 17 | 18 | Get the exported constructor: 19 | 20 | .. code-block:: javascript 21 | 22 | >> var Filter = require("geoscript/filter").Filter; 23 | 24 | Various simple constraints: 25 | 26 | .. code-block:: javascript 27 | 28 | >> var namedFoo = Filter("name = 'foo'"); 29 | >> var oneThing = Filter("thing = 1"); 30 | >> var few = Filter("count < 4"); 31 | >> var many = Filter("count > 36"); 32 | >> var teens = Filter("age BETWEEN 13 AND 19"); 33 | 34 | Spatial constraints: 35 | 36 | .. code-block:: javascript 37 | 38 | >> var box = Filter("BBOX(the_geom, -10, -10, 10, 10)"); 39 | >> var close = Filter("DWITHIN(the_geom, POINT(1 0), 3, kilometers)"); 40 | >> var has = Filter("CONTAINS(the_geom, POINT(1 0))"); 41 | >> var hit = Filter("INTERSECTS(the_geom, LINESTRING(0 0, 1 1))"); 42 | 43 | 44 | Properties 45 | ---------- 46 | 47 | 48 | .. attribute:: Filter.cql 49 | 50 | ``String`` 51 | The CQL string that represents constraints in this filter. 52 | 53 | .. attribute:: Filter.not 54 | 55 | :class:`filter.Filter` 56 | A filter that represents the negation of the constraints in this filter. 57 | 58 | 59 | 60 | Methods 61 | ------- 62 | 63 | .. function:: Filter.and 64 | 65 | :arg filter: :class:`filter.Filter` Input filter. 66 | :returns: :class:`filter.Filter` 67 | 68 | Returns a new filter that is the logical AND of this filter and the 69 | input filter. Provide multiple arguments to AND multiple filters. 70 | 71 | .. function:: Filter.evaluate 72 | 73 | :arg feature: :class:`feature.Feature` A feature. 74 | :returns: ``Boolean`` The feature matches the filter. 75 | 76 | Determine whether a feature matches the constraints of the filter. 77 | 78 | .. function:: Filter.or 79 | 80 | :arg filter: :class:`filter.Filter` Input filter. 81 | :returns: :class:`filter.Filter` 82 | 83 | Returns a new filter that is the logical OR of this filter and the 84 | input filter. Provide multiple arguments to OR multiple filters. 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/geom/io/test_wkt.js: -------------------------------------------------------------------------------- 1 | var ASSERT = require("assert"); 2 | var GEOM = require("geoscript/geom"); 3 | var read = require("geoscript/geom/io/wkt").read; 4 | var write = require("geoscript/geom/io/wkt").write; 5 | 6 | exports["test: read(point)"] = function() { 7 | var g1 = new GEOM.Point([1, 2]); 8 | var g2 = read("POINT (1 2)"); 9 | ASSERT.ok(g2 instanceof GEOM.Geometry, "point from wkt is a geometry"); 10 | ASSERT.ok(g2 instanceof GEOM.Point, "point from wkt is a point"); 11 | ASSERT.ok(g2.equals(g1), "g2 equals g1"); 12 | }; 13 | 14 | exports["test: read(linestring)"] = function() { 15 | var g1 = new GEOM.LineString([[-180, -90], [0, 0], [180, 90]]); 16 | var g2 = read("LINESTRING (-180 -90, 0 0, 180 90)"); 17 | ASSERT.ok(g2 instanceof GEOM.Geometry, "linestring from wkt is a geometry"); 18 | ASSERT.ok(g2 instanceof GEOM.LineString, "linestring from wkt is a linestring"); 19 | ASSERT.ok(g2.equals(g1), "g2 equals g1"); 20 | }; 21 | 22 | exports["test: read(polygon)"] = function() { 23 | var g1 = new GEOM.Polygon([ 24 | [ [-180, -90], [-180, 90], [180, 90], [180, -90], [-180, -90] ], 25 | [ [-90, -45], [-90, 45], [90, 45], [90, -45], [-90, -45] ] 26 | ]); 27 | var g2 = read("POLYGON ((-180 -90, -180 90, 180 90, 180 -90, -180 -90), (-90 -45, -90 45, 90 45, 90 -45, -90 -45))"); 28 | ASSERT.ok(g2 instanceof GEOM.Geometry, "polygon from wkt is a geometry"); 29 | ASSERT.ok(g2 instanceof GEOM.Polygon, "polygon from wkt is a polygon"); 30 | ASSERT.ok(g2.equals(g1), "g2 equals g1"); 31 | }; 32 | 33 | 34 | exports["test: write(point)"] = function() { 35 | 36 | var p = new GEOM.Point([1, 2]); 37 | var wkt = write(p); 38 | ASSERT.strictEqual(wkt, "POINT (1 2)", "correct wkt"); 39 | 40 | }; 41 | 42 | exports["test: write(linestring)"] = function() { 43 | 44 | var l = new GEOM.LineString([[-180, -90], [0, 0], [180, 90]]); 45 | var wkt = write(l); 46 | ASSERT.strictEqual(wkt, "LINESTRING (-180 -90, 0 0, 180 90)", "correct wkt"); 47 | 48 | }; 49 | 50 | exports["test: write(polygon)"] = function() { 51 | 52 | var p = new GEOM.Polygon([ 53 | [ [-180, -90], [-180, 90], [180, 90], [180, -90], [-180, -90] ], 54 | [ [-90, -45], [-90, 45], [90, 45], [90, -45], [-90, -45] ] 55 | ]); 56 | var wkt = write(p); 57 | ASSERT.strictEqual(wkt, "POLYGON ((-180 -90, -180 90, 180 90, 180 -90, -180 -90), (-90 -45, -90 45, 90 45, 90 -45, -90 -45))", "correct wkt"); 58 | 59 | }; 60 | 61 | 62 | if (require.main == module.id) { 63 | system.exit(require("test").run(exports)); 64 | } 65 | -------------------------------------------------------------------------------- /doc/api/workspace/postgis.rst: -------------------------------------------------------------------------------- 1 | :class:`workspace.PostGIS` 2 | ========================== 3 | 4 | .. class:: workspace.PostGIS(config) 5 | 6 | :arg config: ``Object`` Configuration object. 7 | 8 | Create a workspace from a PostGIS enabled database. 9 | 10 | 11 | Config Properties 12 | ----------------- 13 | 14 | 15 | .. describe:: database 16 | 17 | ``String`` 18 | Database name (required). 19 | 20 | .. describe:: host 21 | 22 | ``String`` 23 | Hostname for database connection. Default is ``"localhost"``. 24 | 25 | .. describe:: password 26 | 27 | ``String`` 28 | Password for database connection. Default is ``"postgres"``. 29 | 30 | .. describe:: port 31 | 32 | ``Number`` 33 | Port for database connection. Default is ``5432``. 34 | 35 | .. describe:: schema 36 | 37 | ``String`` 38 | The named database schema containing the tables to be accessed. 39 | Default is ``"public"``. 40 | 41 | .. describe:: user 42 | 43 | ``String`` 44 | Username for database connection. Default is ``"postgres"``. 45 | 46 | 47 | 48 | 49 | Properties 50 | ---------- 51 | 52 | 53 | .. attribute:: PostGIS.layers 54 | 55 | ``Array`` 56 | The available layers in the workspace. 57 | 58 | .. attribute:: PostGIS.names 59 | 60 | ``Array`` 61 | The available layer names in the workspace. 62 | 63 | 64 | 65 | 66 | Methods 67 | ------- 68 | 69 | 70 | .. function:: PostGIS.add 71 | 72 | :arg layer: :class:`layer.Layer` The layer to be added. 73 | :arg options: ``Object`` Options for adding the layer. 74 | 75 | Options: 76 | 77 | * `name`: ``String`` Name for the new layer. 78 | * `filter`: :class:`filter.Filter` Filter to apply to features before adding. 79 | * `projection`: :class:`proj.Projection` Destination projection for the layer. 80 | 81 | :returns: :class:`layer.Layer` 82 | 83 | Create a new layer in this workspace with the features from an existing 84 | layer. If a layer with the same name already exists in this workspace, 85 | you must provide a new name for the layer. 86 | 87 | .. function:: PostGIS.close 88 | 89 | Close the workspace. This discards any existing connection to the 90 | underlying data store and discards the reference to the store. 91 | 92 | .. function:: PostGIS.get 93 | 94 | :arg name: ``String`` Layer name. 95 | :returns: :class:`layer.Layer` 96 | 97 | Get a layer by name. Returns ``undefined`` if name doesn't correspond 98 | to a layer source in the workspace. 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /src/main/resources/org/geoscript/js/lib/geoscript/workspace/h2.js: -------------------------------------------------------------------------------- 1 | var register = require("./util").register; 2 | var Factory = require("../factory").Factory; 3 | var Workspace = require("./workspace").Workspace; 4 | var UTIL = require("../util"); 5 | var H2DataStoreFactory = Packages.org.geotools.data.h2.H2DataStoreFactory; 6 | 7 | /** api: (define) 8 | * module = workspace 9 | * class = H2 10 | */ 11 | 12 | var prepConfig = function(config) { 13 | if (config) { 14 | if (typeof config === "string") { 15 | config = {database: config}; 16 | } 17 | if (typeof config.database !== "string") { 18 | throw "H2 config must include database path."; 19 | } 20 | config = {database: String(config.database)}; 21 | } 22 | return config; 23 | }; 24 | 25 | /** api: (extends) 26 | * workspace/workspace.js 27 | */ 28 | var H2 = UTIL.extend(Workspace, { 29 | 30 | /** api: config[database] 31 | * ``String`` 32 | * Path to the database (required). 33 | */ 34 | 35 | /** api: constructor 36 | * .. class:: H2 37 | * 38 | * :arg config: ``Object`` Configuration object. 39 | * 40 | * Create a workspace from an H2 database. 41 | */ 42 | constructor: function H2(config) { 43 | Workspace.prototype.constructor.apply(this, [prepConfig(config)]); 44 | }, 45 | 46 | /** private: method[_create] 47 | * :arg config: ``Object`` 48 | * :returns: ``org.geotools.jdbc.JDBCDataStore`` 49 | * 50 | * Create the underlying store for the workspace. 51 | */ 52 | _create: function(config) { 53 | config.dbtype = "h2"; 54 | var factory = new H2DataStoreFactory(); 55 | return factory.createDataStore(config); 56 | }, 57 | 58 | /** private: property[config] 59 | */ 60 | get config() { 61 | return { 62 | type: this.constructor.name, 63 | database: this.database 64 | }; 65 | } 66 | 67 | }); 68 | 69 | /** api: example 70 | * Sample code create a new workspace for accessing data in a H2 database: 71 | * 72 | * .. code-block:: javascript 73 | * 74 | * js> var h2 = new WORKSPACE.H2({database: "data/h2/geoscript"}); 75 | * js> h2 76 | *

77 | * js> var states = h2.get("states"); 78 | * js> states 79 | * 80 | */ 81 | 82 | exports.H2 = H2; 83 | 84 | // register an H2 factory for the module 85 | register(new Factory(H2, { 86 | handles: function(config) { 87 | var capable = false; 88 | if (config && typeof config.type === "string" && config.type.toLowerCase() === "h2") { 89 | try { 90 | config = prepConfig(config); 91 | capable = true; 92 | } catch (err) { 93 | // pass 94 | } 95 | } 96 | return capable; 97 | } 98 | })); 99 | -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/workspace/test_directory.js: -------------------------------------------------------------------------------- 1 | var ASSERT = require("assert"); 2 | var WORKSPACE = require("geoscript/workspace"); 3 | var LAYER = require("geoscript/layer"); 4 | 5 | var ADMIN = require("../../admin"); 6 | 7 | var dataDir = ADMIN.shp.dest; 8 | exports.setUp = ADMIN.shp.setUp; 9 | exports.tearDown = ADMIN.shp.tearDown; 10 | 11 | exports["test: constructor"] = function() { 12 | 13 | var dir = new WORKSPACE.Directory(); 14 | 15 | ASSERT.ok(dir instanceof WORKSPACE.Workspace, "instanceof Workspace"); 16 | ASSERT.ok(dir instanceof WORKSPACE.Directory, "instanceof Directory"); 17 | 18 | dir.close(); 19 | 20 | }; 21 | 22 | exports["test: names"] = function() { 23 | 24 | var dir = new WORKSPACE.Directory(dataDir); 25 | 26 | ASSERT.deepEqual(dir.names, ["states"], "dir.names is array of string names"); 27 | 28 | dir.close(); 29 | 30 | }; 31 | 32 | exports["test: layers"] = function() { 33 | 34 | var dir = new WORKSPACE.Directory(dataDir); 35 | var layers = dir.layers; 36 | ASSERT.ok(layers instanceof Array, "got layers array"); 37 | ASSERT.equal(layers.length, 1, "one layer in workspace"); 38 | ASSERT.ok(layers[0] instanceof LAYER.Layer, "first element is layer"); 39 | 40 | dir.close(); 41 | 42 | }; 43 | 44 | exports["test: get"] = function() { 45 | 46 | var dir = new WORKSPACE.Directory(dataDir); 47 | var l = dir.get(dir.names[0]); 48 | 49 | ASSERT.ok(l instanceof LAYER.Layer, "get returns a layer instance"); 50 | 51 | ASSERT.equal(dir.get("foo"), undefined, "getting invalid name returns undefined"); 52 | 53 | dir.close(); 54 | 55 | }; 56 | 57 | exports["test: add"] = function() { 58 | 59 | var dir = new WORKSPACE.Directory(dataDir); 60 | var states = dir.get("states"); 61 | 62 | ASSERT.throws(function() { 63 | dir.add(states); 64 | }, Error, "add with same name"); 65 | 66 | var states2 = dir.add(states, {name: "states2"}); 67 | ASSERT.equal(dir.names.length, 2, "two layers"); 68 | ASSERT.equal(states2.count, 49, "two count"); 69 | 70 | var states3 = dir.add(states, {name: "states3", filter: "STATE_ABBR like 'M%'"}); 71 | ASSERT.equal(dir.names.length, 3, "three layers"); 72 | ASSERT.equal(states3.count, 8, "three count"); 73 | 74 | var states4 = dir.add(states, {name: "states4", projection: "epsg:32002"}); 75 | ASSERT.equal(dir.names.length, 4, "four layers"); 76 | ASSERT.equal(states4.count, 49, "four count"); 77 | ASSERT.equal(states4.projection.id, "EPSG:32002", "four projection"); 78 | 79 | }; 80 | 81 | 82 | 83 | if (require.main == module.id) { 84 | system.exit(require("test").run(exports)); 85 | } 86 | 87 | -------------------------------------------------------------------------------- /doc/api/feature/schema.rst: -------------------------------------------------------------------------------- 1 | :class:`feature.Schema` 2 | ======================= 3 | 4 | .. class:: feature.Schema(config) 5 | 6 | :arg Object config: Configuration object. 7 | 8 | Create a new schema. 9 | 10 | 11 | Example Use 12 | ----------- 13 | 14 | Sample code to create a new schema: 15 | 16 | .. code-block:: javascript 17 | 18 | >> var Schema = require("geoscript/feature").Schema; 19 | >> var cities = Schema({ 20 | .. name: "cities", 21 | .. fields: [{ 22 | .. name: "the_geom", 23 | .. type: "Point", 24 | .. projection: "EPSG:4326" 25 | .. }, { 26 | .. name: "name", 27 | .. type: "String" 28 | .. }] 29 | .. }); 30 | 31 | >> cities.fields.length 32 | 2 33 | >> cities.geometry.name 34 | the_geom 35 | >> cities.get("the_geom").type 36 | Point 37 | >> cities.get("the_geom").projection 38 | 39 | 40 | Config Properties 41 | ----------------- 42 | 43 | .. describe:: fields 44 | 45 | ``Array`` 46 | Field definitions. Each item in the array must be a 47 | :class:`feature.Field` object or a valid field config. 48 | 49 | .. describe:: name 50 | 51 | ``String`` 52 | The schema name. Default is ``"feature"``. The schema name typically 53 | matches the layer name within a workspace. 54 | 55 | 56 | Properties 57 | ---------- 58 | 59 | 60 | .. attribute:: Schema.fieldNames 61 | 62 | ``Array`` 63 | Array of field names. 64 | 65 | .. attribute:: Schema.fields 66 | 67 | ``Array`` 68 | Field definitions. Field definitions are objects with at least ``name`` 69 | and ``type`` properties. Geometry field definitions may have a 70 | ``projection`` property. See the :class:`feature.Field` documentation 71 | for more detail. 72 | 73 | .. attribute:: Schema.geometry 74 | 75 | ``Object`` 76 | Default geometry field definition. Will be ``undefined`` if the schema 77 | doesn't include a geometry field. 78 | 79 | .. attribute:: Schema.name 80 | 81 | ``String`` 82 | The schema name. 83 | 84 | 85 | Methods 86 | ------- 87 | 88 | .. function:: Schema.clone 89 | 90 | :arg config: ``Object`` 91 | :returns: :class:`feature.Schema` 92 | 93 | Create a complete copy of this schema. 94 | 95 | .. function:: Schema.get 96 | 97 | :arg name: ``String`` A field name. 98 | :returns: :class:`feature.Field` A field definition. 99 | 100 | Get the definition for a named field. Field definitions have at least 101 | ``name`` and ``type`` properties. Geometry field definitions may have 102 | a ``projection`` property. Returns ``undefined`` if no field is found 103 | with the given name. 104 | 105 | 106 | -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/admin.js: -------------------------------------------------------------------------------- 1 | var ZIP = require("ringo/zip"); 2 | var FS = require("fs"); 3 | 4 | var unzip = function(source, dest) { 5 | var zip = new ZIP.ZipFile(source); 6 | for (var i=0, ii=zip.entries.length; i -1) { 20 | FS.touch(path, entry.time); 21 | } 22 | } 23 | } 24 | 25 | var path = function(rel) { 26 | return FS.absolute(FS.resolve(module.path, rel)); 27 | } 28 | 29 | var meta = { 30 | shp: { 31 | source: path("data/states.shp.zip"), 32 | dest: path("tmp"), 33 | setUp: function() { 34 | meta.shp.tearDown(); 35 | unzip(meta.shp.source, meta.shp.dest); 36 | }, 37 | tearDown: function() { 38 | if (FS.exists(meta.shp.dest)) { 39 | FS.removeTree(meta.shp.dest); 40 | } 41 | } 42 | }, 43 | h2: { 44 | source: path("data/h2.zip"), 45 | dest: path("tmp"), 46 | setUp: function() { 47 | meta.h2.tearDown(); 48 | unzip(meta.h2.source, meta.h2.dest); 49 | }, 50 | tearDown: function() { 51 | if (FS.exists(meta.h2.dest)) { 52 | Packages.org.h2.tools.DeleteDbFiles.execute(meta.h2.dest, "geoscript", true); 53 | FS.removeTree(meta.h2.dest); 54 | } 55 | } 56 | }, 57 | geopkg: { 58 | source: path("data/geopkg.zip"), 59 | dest: path("tmp"), 60 | setUp: function() { 61 | meta.geopkg.tearDown(); 62 | unzip(meta.geopkg.source, meta.geopkg.dest); 63 | }, 64 | tearDown: function() { 65 | if (FS.exists(meta.geopkg.dest)) { 66 | FS.removeTree(meta.geopkg.dest); 67 | } 68 | } 69 | }, 70 | pg: { 71 | driver: new Packages.org.postgresql.Driver, 72 | setUp: function() { 73 | var uri = "jdbc:postgresql:geoscript"; 74 | var params = new java.util.Properties(); 75 | params.setProperty("user", "postgres"); 76 | params.setProperty("password", "postgres"); 77 | var connection = meta.pg.driver.getConnection(uri, params); 78 | } 79 | }, 80 | raster: { 81 | source: path("data/raster.tif"), 82 | writePng: path("raster.png") 83 | } 84 | }; 85 | 86 | for (var key in meta) { 87 | exports[key] = meta[key]; 88 | } 89 | -------------------------------------------------------------------------------- /src/main/resources/org/geoscript/js/lib/geoscript/geom/io/json.js: -------------------------------------------------------------------------------- 1 | /** api: module = geom/io/json */ 2 | 3 | /** api: synopsis 4 | * Reading and writing JSON. 5 | */ 6 | 7 | /** api: summary 8 | * The :mod:`geom/io/json` module exports functions to read and write 9 | * geometries. 10 | * 11 | * .. code-block:: javascript 12 | * 13 | * js> var json = require("geoscript/geom/io/json"); 14 | */ 15 | 16 | var UTIL = require("../../util"); 17 | var GEOM = require("../../geom"); 18 | 19 | /** api: method[read] 20 | * :arg str: ``String`` 21 | * :returns: :class:`geom.Geometry` 22 | * 23 | * Creates a geometry from a JSON string. See http://geojson.org/ for details 24 | * on the format. 25 | * 26 | * Example use: 27 | * 28 | * .. code-block:: javascript 29 | * 30 | * js> var json = require("geoscript/geom/io/json"); 31 | * js> var str = '{"type": "Point", "coordinates": [0, 1]}'; 32 | * js> var point = json.read(str); 33 | * js> point.x 34 | * 0 35 | * js> point.y 36 | * 1 37 | */ 38 | var read = function(str) { 39 | 40 | var obj = JSON.parse(str); 41 | if (!obj.type) { 42 | throw new Error("Invalid GeoJSON, no type member."); 43 | } 44 | 45 | var collection = obj.type === "GeometryCollection"; 46 | var configs; 47 | if (collection) { 48 | configs = obj.geometries; 49 | // TODO: deal with crs 50 | } else { 51 | configs = [obj]; 52 | } 53 | 54 | var num = configs.length; 55 | var geometries = new Array(num); 56 | for (var i=0; i var json = require("geoscript/geom/io/json"); 75 | * js> var Point = require("geoscript/geom").Point; 76 | * js> var point = new Point([0, 1]); 77 | * js> var str = json.write(point); 78 | * js> str 79 | * {"type": "Point", "coordinates": [0, 1]} 80 | */ 81 | var write = function(geometries) { 82 | 83 | var collection = true; 84 | if (!(UTIL.isArray(config))) { 85 | collection = false; 86 | geometries = [geometries]; 87 | } 88 | 89 | var num = geometries.length; 90 | var configs = new Array(num); 91 | for (var i=0; i> var Field = require("geoscript/feature").Field; 18 | >> var field = Field({ 19 | .. name: "age", 20 | .. type: "Double" 21 | .. }); 22 | 23 | >> var field = Field({ 24 | .. name: "location", 25 | .. type: "Point", 26 | .. projection: "EPSG:4326" 27 | .. }); 28 | 29 | For detail on the supported ``type`` values, see the section on 30 | :ref:`type_mapping`. 31 | 32 | Config Properties 33 | ----------------- 34 | 35 | .. describe:: description 36 | 37 | ``String`` 38 | The field description (optional). 39 | 40 | .. describe:: isNillable 41 | 42 | ``Boolean`` 43 | The field is nillable (optional). Default is ``true``. 44 | 45 | .. describe:: minOccurs 46 | 47 | ``Number`` 48 | The minimum occurences for field values (optional). Default is ``0``. 49 | 50 | .. describe:: name 51 | 52 | ``String`` 53 | The field name (required). 54 | 55 | .. describe:: projection 56 | 57 | :class:`proj.Projection` 58 | Geometry projection (optional). Relevant for geometry type fields only. 59 | 60 | .. describe:: title 61 | 62 | ``String`` 63 | The field title (optional). 64 | 65 | .. describe:: type 66 | 67 | ``String`` 68 | The field type (required). For detail on the supported ``type`` values, see 69 | the section on :ref:`type_mapping`. 70 | 71 | 72 | 73 | Properties 74 | ---------- 75 | 76 | .. attribute:: Field.description 77 | 78 | ``String`` 79 | The field description (read-only). 80 | 81 | .. attribute:: Field.isNillable 82 | 83 | ``Boolean`` 84 | The field is nillable (read-only). 85 | 86 | .. attribute:: Field.maxOccurs 87 | 88 | ``Number`` 89 | The maximum occurences for field values (read-only). 90 | 91 | .. attribute:: Field.minOccurs 92 | 93 | ``Number`` 94 | The minimum occurences for field values (read-only). 95 | 96 | .. attribute:: Field.name 97 | 98 | ``String`` 99 | The field name (read-only). 100 | 101 | .. attribute:: Field.projection 102 | 103 | :class:`proj.Projection` 104 | Geometry type fields can have an optional projection (read-only). 105 | 106 | .. attribute:: Field.title 107 | 108 | ``String`` 109 | The field title (read-only). 110 | 111 | .. attribute:: Field.type 112 | 113 | ``String`` 114 | The field type (read-only). For detail on the supported ``type`` values, 115 | see the section on :ref:`type_mapping`. 116 | 117 | 118 | 119 | Methods 120 | ------- 121 | 122 | .. function:: Field.equals 123 | 124 | :arg field: :class:`feature.Field` 125 | :returns: ``Boolean`` The two fields are equivalent. 126 | 127 | Determine if another field is equivalent to this one. 128 | 129 | -------------------------------------------------------------------------------- /doc/api/feature/feature.rst: -------------------------------------------------------------------------------- 1 | :class:`feature.Feature` 2 | ======================== 3 | 4 | .. class:: feature.Feature(config) 5 | 6 | :arg Object config: Configuration object. 7 | 8 | Create a new feature. 9 | 10 | 11 | Example Use 12 | ----------- 13 | 14 | Sample code to create a new feature: 15 | 16 | .. code-block:: javascript 17 | 18 | >> var Feature = require("geoscript/feature").Feature; 19 | >> var Point = require("geoscript/geom").Point; 20 | >> var city = Feature({ 21 | .. properties: { 22 | .. location: Point([-110, 45]), 23 | .. name: "Metropolis" 24 | .. } 25 | .. }); 26 | 27 | >> city.get("name"); 28 | Metropolis 29 | >> city.get("location"); 30 | 31 | 32 | 33 | Config Properties 34 | ----------------- 35 | 36 | .. describe:: schema 37 | 38 | :class:`feature.Schema` 39 | The feature schema. If not provided, a schema will be derived from 40 | the provided ``properties`` in the configuration. 41 | 42 | .. describe:: properties 43 | 44 | ``Object`` 45 | An object with all the feature property names and values. 46 | 47 | 48 | 49 | Properties 50 | ---------- 51 | 52 | 53 | .. attribute:: Feature.bounds 54 | 55 | :class:`geom.Bounds` 56 | The bounds of the default geometry (if any) for this feature. Will be 57 | ``undefined`` if the feature has no geometry. 58 | 59 | .. attribute:: Feature.geometry 60 | 61 | :class:`geom.Geometry` 62 | The default geometry (if any) for the feature. Will be ``undefined`` 63 | if the feature does not have a geometry. 64 | 65 | .. attribute:: Feature.geometryName 66 | 67 | ``String`` 68 | Field name for the default geoemtry, or ``undefined`` if the feature 69 | has no geometry. 70 | 71 | .. attribute:: Feature.id 72 | 73 | ``String`` 74 | The feature identifier. Read only. 75 | 76 | .. attribute:: Feature.json 77 | 78 | ``String`` 79 | The JSON representation of the feature (see http://geojson.org). 80 | 81 | .. attribute:: Feature.projection 82 | 83 | :class:`proj.Projection` 84 | Optional projection for the feature. This corresponds to the projection 85 | of the default geometry for the feature. 86 | 87 | .. attribute:: Feature.schema 88 | 89 | :class:`feature.Schema` 90 | The feature schema (read-only). 91 | 92 | .. attribute:: Feature.properties 93 | 94 | ``Object`` 95 | An object with all the feature property names and values. Used for 96 | property access only. Use :func:`~Feature.set` to set property values. 97 | 98 | 99 | 100 | 101 | Methods 102 | ------- 103 | 104 | 105 | .. function:: Feature.clone 106 | 107 | :returns: :class:`feature.Feature` 108 | 109 | Create a clone of this feature. 110 | 111 | .. function:: Feature.get 112 | 113 | :arg name: ``String`` Attribute name. 114 | 115 | Get an attribute value. 116 | 117 | .. function:: Feature.set 118 | 119 | :arg name: ``String`` Attribute name. 120 | :arg value: ``String`` Attribute value. 121 | 122 | Set a feature attribute. 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /examples/process/buffer.js: -------------------------------------------------------------------------------- 1 | var Process = require("geoscript/process").Process; 2 | 3 | var buffer = exports.buffer = new Process({ 4 | title: "Buffer", 5 | description: "Buffer geometries for features. The features input can be an array, a cursor, or any object with a forEach method. It is assumed that all features share the same schema and that the schema has a default geometry field. The distance input is expected to be in the same units as the geometry coordinates.", 6 | run: function(config) { 7 | var args = config.args; 8 | var callback = config.callback; 9 | var errback = config.errback; 10 | if (args.length !== 2) { 11 | errback && errback("Buffer must be run with two arguments."); 12 | } 13 | var features = args[0]; 14 | if (!features.forEach || typeof features.forEach !== "function") { 15 | errback && errback("Buffer features input must have a forEach method."); 16 | } 17 | var distance = Number(args[1]); 18 | // pass back a forEach-able that creates clones with buffered geometries 19 | callback({ 20 | forEach: function(fn) { 21 | var schema, name; 22 | features.forEach(function(feature) { 23 | if (!schema) { 24 | var field = feature.schema.geometry; 25 | if (!field) { 26 | errback("Buffer only works on features with a default geometry."); 27 | } 28 | var type; 29 | if (field.type.indexOf("Multi") === 0) { 30 | type = "MultiPolygon"; 31 | } else if (field.type === "Geometry") { 32 | type = "Geometry"; 33 | } else { 34 | type = "Polygon"; 35 | } 36 | name = field.name; 37 | schema = feature.schema.clone({ 38 | fields: [{ 39 | name: name, 40 | type: type 41 | }] 42 | }); 43 | } 44 | var values = {}; 45 | values[name] = feature.geometry.buffer(distance); 46 | fn(feature.clone({ 47 | schema: schema, 48 | values: values 49 | })); 50 | }); 51 | } 52 | }); 53 | } 54 | }); 55 | 56 | 57 | if (require.main == module.id) { 58 | var fs = require("fs"); 59 | var Directory = require("geoscript/workspace").Directory; 60 | var path = fs.resolve(module.path, "../data/shapefiles"); 61 | var dir = new Directory(path); 62 | var states = dir.get("states"); 63 | buffer.run({ 64 | args: [states.features, 1], 65 | callback: function(cursor) { 66 | var features = []; 67 | cursor.forEach(function(feature) { 68 | features.push(feature); 69 | }); 70 | require("geoscript/viewer").draw(features); 71 | } 72 | }); 73 | } 74 | -------------------------------------------------------------------------------- /src/test/resources/org/geoscript/js/tests/geoscript/geom/io/test_json.js: -------------------------------------------------------------------------------- 1 | var ASSERT = require("assert"); 2 | var GEOM = require("geoscript/geom"); 3 | var read = require("geoscript/geom/io/json").read; 4 | var write = require("geoscript/geom/io/json").write; 5 | 6 | var cases = [{ 7 | str: '{"type": "Point", "coordinates": [0, 1]}', 8 | geo: new GEOM.Point([0, 1]), 9 | id: "point" 10 | }, { 11 | str: '{' + 12 | '"type": "GeometryCollection",' + 13 | '"geometries": [' + 14 | '{' + 15 | '"type": "Point",' + 16 | '"coordinates": [100.0, 0.0]' + 17 | '}, {' + 18 | '"type": "LineString",' + 19 | '"coordinates": [[101.0, 0.0], [102.0, 1.0]]' + 20 | '}' + 21 | ']' + 22 | '}', 23 | geo: [ 24 | new GEOM.Point([100.0, 0.0]), 25 | new GEOM.LineString([[101.0, 0.0], [102.0, 1.0]]) 26 | ], 27 | id: "collection" 28 | }, { 29 | str: '{"coordinates": [0, 1]}', 30 | geo: Error, 31 | id: "invalid GeoJSON" 32 | }]; 33 | 34 | exports["test: read"] = function() { 35 | 36 | var c, got; 37 | for (var i=0, ii=cases.length; i