{"id":46561,"date":"2017-09-27T00:00:00","date_gmt":"2017-09-27T07:00:00","guid":{"rendered":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/blog\/using-geometry-values-griddb\/"},"modified":"2025-11-13T12:54:31","modified_gmt":"2025-11-13T20:54:31","slug":"using-geometry-values-griddb","status":"publish","type":"post","link":"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/","title":{"rendered":"Using Geometry Values with GridDB"},"content":{"rendered":"<h2 id=\"intro\">Introduction<\/h2>\n<p>Data comes in many, many forms. It comes temporally as well as spatially. GridDB&#8217;s Timeseries containers as well as its TQL and time-specific API operations cover the time aspect of data. GridDB has geospatial data covered as well in GridDB Standard Edition and Advanced Edition. Support is provided with <b>Geometry Columns and Data Types<\/b> along with specialized <b>Geometry Operations<\/b> through TQL as well as through the C and Java APIs.<\/p>\n<p>In GridDB, Geometry values can be created to represent <b>5<\/b> general models or shapes.<\/p>\n<h3 id=\"point\">POINT<\/h3>\n<p>A coordinate point in either two dimensional or three dimensional space.<br \/>\n<b>2D and 3D Points<\/b><\/p>\n<pre class=\"prettyprint\">\nGeometry point = Geometry.valueOf(\"POINT(1 3.4)\");\nGeometry threeDPt = Geometry.valueOf(\"POINT(2 -3 0.43)\");\n<\/pre>\n<p><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2017\/09\/points-281x300.png\" alt=\"points\" width=\"281\" height=\"300\" class=\"aligncenter size-medium wp-image-16863\" srcset=\"\/wp-content\/uploads\/2017\/09\/points-281x300.png 281w, \/wp-content\/uploads\/2017\/09\/points.png 556w\" sizes=\"(max-width: 281px) 100vw, 281px\" \/><\/p>\n<h3 id=\"linestring\">LINESTRING<\/h3>\n<p>A set of one or more <i>interconnected<\/i> lines in two or three dimensional space. They are represented by two or more points.<br \/>\n<img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2017\/09\/linestrings-1.png\" alt=\"\" width=\"679\" height=\"297\" class=\"aligncenter size-full wp-image-17363\" srcset=\"\/wp-content\/uploads\/2017\/09\/linestrings-1.png 679w, \/wp-content\/uploads\/2017\/09\/linestrings-1-300x131.png 300w\" sizes=\"(max-width: 679px) 100vw, 679px\" \/><\/p>\n<h3 id=\"polygon\">POLYGON<\/h3>\n<p>A closed area in either two or three dimensional space. The area consists of three or more points that are connected from a starting point, or <code>VERTEX<\/code>, to the endpoints and back to the starting point. It is possible to have the surface or area to have gaps or islands that are not part of the model by specifying the internal areas to exclude from the outer area.<br \/>\n<b>2D Polygon<\/b><\/p>\n<pre class=\"prettyprint\">\nGeometry polygon = Geometry.valueOf(\"POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))\");\n<\/pre>\n<p><b>3D Polygon<\/b><\/p>\n<pre class=\"prettyprint\">\nGeometry threeDSurface = Geometry.valueOf(\"POLYGON((0 0 0, 1 0 1, 1 1 1, 0 1 0, 0 0 0))\");\n<\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2017\/09\/rsz_polygons.png\" alt=\"example-polygons\" width=\"549\" height=\"168\" class=\"aligncenter size-full wp-image-17173\" srcset=\"\/wp-content\/uploads\/2017\/09\/rsz_polygons.png 549w, \/wp-content\/uploads\/2017\/09\/rsz_polygons-300x92.png 300w\" sizes=\"(max-width: 549px) 100vw, 549px\" \/><\/p>\n<h3 id=\"polyhedralsurface\">POLYHEDRALSURFACE<\/h3>\n<p>The <code>POLYHEDRALSURFACE<\/code> surface consists of <i>vertices, edges, and facets<\/i>. Simple examples tetrahedrons, polyhedrons, and octohedral surfaces. The <i>POLYHEDRALSURFACE<\/i> can only be a three-dimensional shape. This means all the points that make up its edges are supposed to contain <b>3 coordinates<\/b>. Polyhedral surfaces can be thought of as a full three-dimensional extension of the <i>POLYGON<\/i> in that the shape can enclose a volume where its faces are each comprised of a closed polygonal surface.<br \/>\n<b>Example<\/b><\/p>\n<pre class=\"prettyprint\">\nGeometry polySurface = Geometry.valueOf(  \n\"POLYHEDRALSURFACE ( ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\" \n+ \"((0 0 0, 0 1 0, 0 1 1, 0 0 1, 0 0 0 )),\" \n+ \"((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\" + \n\"((1 1 1, 1 0 1, 0 0 1, 0 1 1, 1 1 1)) ,\" + \n\"((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\" + \n\"((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1)) )\");\n<\/pre>\n<p>Every set of coordinates should be enclosed by double-parenthesis <code>((<\/code> , <code>))<\/code> because it represents a closed face that will make up part of the three-dimensional enclosed surface. Think of the faces as <code>POLYGON<\/code>&#8216;s that make up the sides of the surface. All these are then grouped and connected together to form the three-dimensional surface object.<br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2017\/09\/polysurface-300x152.png\" alt=\"Polyhedral Surface\" width=\"300\" height=\"152\" class=\"aligncenter size-medium wp-image-17003\" srcset=\"\/wp-content\/uploads\/2017\/09\/polysurface-300x152.png 300w, \/wp-content\/uploads\/2017\/09\/polysurface.png 621w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<h3 id=\"quadraticsurface\">QUADRATICSURFACE<\/h3>\n<p>A three dimensional quadratic surface. These objects are curved surfaces in three-dimensional space by the equation: <code>f(X) = &lt;AX,X&gt; + BX + C<\/code>. Create a surface by inserting <b>16<\/b> numbers that represent the <i>coefficents<\/i> of making that surface equation.<br \/>\nThe <i>QUADRATICSURFACE<\/i> is different from the other four Geometry objects in that its WKT (Well-Known-Text format) inputs are coefficients to an equation rather than coordinates in the 3D plane. This equation,<\/p>\n<pre class=\"prettyprint\">ax<sup>2<\/sup>+by<sup>2<\/sup>+cz<sup>2<\/sup>+2fyz+2gzx+2hxy+2px+2qy+2rz+d = 0<\/pre>\n<p>When converted into a <i>quadratic-form<\/i> matrix:<\/p>\n<table id=\"matrix-table\">\n<tr>\n<td><i>a<\/i><\/td>\n<td><i>h<\/i><\/td>\n<td><i>g<\/i><\/td>\n<td><i>p<\/i><\/tr>\n<tr>\n<td><i>h<\/i><\/td>\n<td><i>b<\/i><\/td>\n<td><i>f<\/i><\/td>\n<td><i>q<\/i><\/td>\n<\/tr>\n<tr>\n<td><i>g<\/i><\/td>\n<td><i>f<\/i><\/td>\n<td><i>c<\/i><\/td>\n<td><i>r<\/i><\/td>\n<\/tr>\n<tr>\n<td><i>p<\/i><\/td>\n<td><i>q<\/i><\/td>\n<td><i>r<\/i><\/td>\n<td><i>d<\/i><\/td>\n<\/tr>\n<\/table>\n<p><b>Example Surface<\/b><\/p>\n<pre class=\"prettyprint\">\nGSRow* row;\nconst GSChar* wkt = \"QUADRATICSURFACE(( 84 2 3 5 6 7 8 9 10 12 13 14 15 16 17 18 ))\";\n\/\/ (snip)\ngsGetNextRow(rowSet,row);\ngsSetRowFieldByGeometry(row,4,wkt);\ngsPutRow(timeseries,NULL,row,NULL);\n<\/pre>\n<p>Examples of quadric surfaces include parallel planes, hyperboloids, cones, cylinders and spheres. These types of surfaces are mapped to different polynomial equations. Some of these equations may not have certain factors or coefficients. For example, there may be no <code>x<\/code>&#8216;s in the equation like in <\/p>\n<pre class=\"prettyprint\">\ny<sup>2<\/sup> + z<sup>2<\/sup> - 1\n<\/pre>\n<p>Since there are no <i>x&#8217;s<\/i> in the equation, replace all coefficients that are near x like <i>a,h,p<\/i> with 0&#8217;s. When entering the matrix values for the <b>QUADRATICSURFACE<\/b> WKT, there must always be <b>16<\/b> values, with any missing values replaced with a 0.<\/p>\n<p>More examples and information on quadric surfaces can be found in this <a href=\"http:\/\/mathworld.wolfram.com\/QuadraticSurface.html\" target=\"_blank\" title=\"Quadratic Surfaces\" rel=\"noopener noreferrer\">Wolfram Alpha page<\/a>.<br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2017\/09\/rsz_quadratics.png\" alt=\"example-quadratics\" width=\"524\" height=\"158\" class=\"aligncenter size-full wp-image-17183\" srcset=\"\/wp-content\/uploads\/2017\/09\/rsz_quadratics.png 524w, \/wp-content\/uploads\/2017\/09\/rsz_quadratics-300x90.png 300w\" sizes=\"(max-width: 524px) 100vw, 524px\" \/><\/p>\n<h2 id=\"wkt\">Creating Objects with WKT Format<\/h2>\n<p>Creating any of these objects in GridDB is fairly simple. All that is needed on the development end is to know how to establish the model in <code>WKT<\/code> form. WKT (Well-Known-Text) text formatting is a text markup language used for representing vector geometry objects on a map or in a spatial reference system. If the WKT string is parsed correctly, the Geometry is created and inserted into its respective column into the Collection or Timeseries. There are certain characteristics of WKT format that should be noted and followed or else errors will be thrown or the Geometry object will not be created. <\/p>\n<h5 id=\"format\">General Formatting Rules<\/h5>\n<p>When stating the shape of the Geometry (POINT,LINESTRING,etc.) ensure that you use <b>ALL UPPERCASE LETTERS<\/b> and correct syntax. If not done so, the object will not be created and <i>exceptions<\/i> could be raised. Ensure that the formatting is correct and there are no syntax errors such as not having correct amount of parenthesis or not using proper spacing.<\/p>\n<p>If you wish to create an empty Geometry object, create a <code>POINT(EMPTY)<\/code> geometry.<br \/>\n<b>Empty LINESTRING and POLYGON<\/b><\/p>\n<pre class=\"prettyprint\">\nGeometry emptyPoint = Geometry.valueOf(\"POINT(EMPTY)\");\n<\/pre>\n<p>You can learn more about general WKT formatting on this <a href=\"https:\/\/en.wikipedia.org\/wiki\/Well-known_text\" target=\"_blank\" title=\"WKT Wikipedia\" rel=\"noopener noreferrer\">Wikipedia page<\/a>.<\/p>\n<h5 id=\"range-restrictions\">Range Restrictions<\/h5>\n<p>In some <i>GIS<\/i>-supporting (Geographic Information System) databases, the ranges or values of points can include special values like <code>NaN<\/code>, <code>INF<\/code>, <code>-INF<\/code> (Not-a-Number, Negative and Positive Infinity). Only numerical-types can be used which include positive or negative floating point numbers.<\/p>\n<h5 id=\"forming-surface\">Forming Closed Surfaces<\/h5>\n<p>Usually Geometries beyond POINT and QUADRATICSURFACE consist of points that are connected. The points, once connected together, form lines that will make up the edges. The edges usually converge to form a closed surface. For all Geometries except <i>POINT<\/i>, more than one data point is needed.<\/p>\n<h5 id=\"dimensions\">Dimensions of Geometry Values<\/h5>\n<p>The points that make a Geometry can only be in <i>two-dimensional or three-dimensional<\/i> format. Also, when creating points to outline an object the dimensions must stay consistent (i.e a polygon that has a coordinate in 2D must have all its other coordinates in 2D). Points are separated by commas: <code>,<\/code> and the <code>x,y,z<\/code> coordinates are delimited by <code>SPACES<\/code><\/p>\n<h2 id=\"column-creation\">Defining Geometric Columns and Indexes<\/h2>\n<p>Geometry columns can be added to the column schema for a container either in a static fashion or a dynamic fashion. The <code>Geometry<\/code> can be directly imported from the GridDB library and can be set as a column type for a <i>class schema<\/i> for a container. You can also set an index on a Geometry column by setting a <code>SPATIAL<\/code> index flag.<br \/>\n<b>Java Container Creation<\/b><\/p>\n<pre class=\"prettyprint\">\n\/\/ (snip)\nimport com.toshiba.mwcloud.gs.Geometry;\nimport com.toshiba.mwcloud.gs.GeometryOperator;\n\/\/(snip)\nstatic class Shape {\n\t@RowKey String name;\n\tdouble perimeter;\n\tdouble volume;\n\tDate creation;\n\tGeometry geom;\n\n\tpublic String toString(){\n\t\treturn String.format(\"Shape: Name = %s, Perimeter = %f, \n                                   Volume = %f, Creation Date = %s, WKT = %s\", \n                                name,perimeter,volume,creation.toString(),geom.toString());\n\/\/(snip)\nCollection&lt;String,Shape&gt; geometryCollection =  \n              gridstore.putCollection(\"GeometryCollection101\",Shape.class);\n\/\/ (snip)\ngeometryCollection.createIndex(\"geom\",IndexType.SPATIAL);\n<\/pre>\n<p>There is no explicit GSGeometry struct or enum in GridDB&#8217;s C API. When creating a container with a dynamic schema using <code>ContainerInfo<\/code> and <code>ColumnInfo<\/code> objects, set the ColumnInfo&#8217;s <i>type<\/i> as <code>GS_TYPE_GEOMETRY<\/code>. If you are using <b>struct-bindings<\/b>, set the column type that you wish to set as Geometry to have the type <code>const GSChar*<\/code>. From there, set the column&#8217;s type to Geometry when performing the struct-bindings. Simply set the column value with its <b>WKT<\/b> form and GridDB will convert it to its binary equivalent in the database.<br \/>\n<b>C Container Creation<\/b><\/p>\n<pre class=\"prettyprint\">\ntypedef struct {\n\tconst GSChar* name;\n\tGSTimestamp timestamp;\n\tdouble volume;\n\tdouble perimeter;\n\tconst GSChar* shape;\n} GeometryRow;\n\nGS_STRUCT_BINDING(GeometryRow,\n\tGS_STRUCT_BINDING_KEY(name, GS_TYPE_STRING)\n\tGS_STRUCT_BINDING_ELEMENT(timestamp,GS_TYPE_TIMESTAMP)\n\tGS_STRUCT_BINDING_ELEMENT(volume,GS_TYPE_DOUBLE)\n\tGS_STRUCT_BINDING_ELEMENT(perimeter,GS_TYPE_DOUBLE)\n\tGS_STRUCT_BINDING_ELEMENT(shape,GS_TYPE_GEOMETRY));\n\/\/(snip)\nGSCollection* collection;\ngsPutCollection(gridstore,\"GeometryCollection311\", \nGS_GET_STRUCT_BINDING(GeometryRow),NULL,GS_FALSE,&amp;collection);\n\ngsCreateIndex(collection,\"shape\",GS_INDEX_FLAG_SPATIAL);\n\nGeometryRow gRow; \ngRow.name = \"FirstPoint\";\ngRow.timestamp = gsCurrentTime();\ngRow.volume = 0;\n\ndouble x, y, z;\nsscanf(wkt,\"POINT(%lf %lf %lf)\",&amp;x,&amp;y,&amp;z);\ngRow.perimeter = sqrt((x * x) + (y * y) + (z * z));\ngRow.shape = \"POINT(1 4.23 4.2)\";\n\ngsPutRow(collection,NULL,&amp;gRow,NULL);\n<\/pre>\n<h2 id=\"spatial-operations\">Spatial Operations in GridDB&#8217;s API<\/h2>\n<p>Geometric data values, when inserted into a GridDB database, are stored in <i>binary<\/i> form, much like <code>BLOB<\/code> data types. This means that performing direct equality operations are not allowed with <code>TQL<\/code>.<br \/>\n<b>Example of Invalid TQL<\/b><\/p>\n<pre class=\"prettyprint\">\nSELECT * WHERE geom = ST_GeomFromText('POINT(2 4 5)') #(Throws Error)\n<\/pre>\n<p>In Java it is possible to compare the Geometry values directly to each using the API from GridDB.<\/p>\n<pre class=\"prettyprint\">\nGeometry pointToFind = Geometry.valueOf(\"POINT(0 4)\");\n\/\/ (snip)\nwhile(rowSet.hasNext){\n     Row row = rowSet.next();\n     Geometry rowPoint = row.getGeometry(4);\n     boolean match = rowPoint.equals(pointToFind);\n     System.out.println(match);\n<\/pre>\n<p>One spatial operation that is allowed through GridDB&#8217;s API and TQL is a <code>SPATIAL INTERSECTION<\/code>. This translates to searching for a common area or volume between the two objects. A 3D intersection consists of determining a <i>Minimum Bounding Box<\/i>, known as a rectangular parallelepiped, where the two objects intersect. When objects are two-dimensional, the z-coordinates have range values of <code>(-INF,INF)<\/code>. This means that checking against a 2D dimensional object with a 3D dimensional object will have a more inclusive z-range to increase the chances of intersection.<\/p>\n<p>When comparing an object with a <i>POINT<\/i>, the bounding box&#8217;s vertices are made up of the points. The box&#8217;s vertices are all on the same side and have a length of 0. If comparing a POINT to a non-point object, GridDB will check if the bounding box contains the point in its area.<\/p>\n<p>When comparing between shapes that are not points, such as two <i>POLYGON<\/i> objects, the bounding box will have minimum and maximum x, y, and z coordinates that will make up the intersection&#8217;s spatial structure.<\/p>\n<p><b>Examples of Spatial Intersections<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2017\/09\/rsz_spatial-intersections.png\" alt=\"spatial-intersection-thumbnail\" width=\"800\" height=\"450\" class=\"aligncenter size-full wp-image-17103\" srcset=\"\/wp-content\/uploads\/2017\/09\/rsz_spatial-intersections.png 800w, \/wp-content\/uploads\/2017\/09\/rsz_spatial-intersections-300x169.png 300w, \/wp-content\/uploads\/2017\/09\/rsz_spatial-intersections-768x432.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<h3 id=\"geometry-api\">Issuing Geometric Queries with GridDB API<\/h3>\n<p>Intersection queries can be made quickly without TQL on <code>Collection<\/code> containers by issuing <code>.query(String column,Geometry geom,GeometryOperator operator)<\/code> in Java or <code>gsQueryByGeometry()<\/code>. This query will search and fetch all rows<br \/>\nwhose &#8216;column&#8217; value will intersect with <code>const GSChar* geometry<\/code>.<br \/>\n<b>Java<\/b><\/p>\n<pre class=\"prettyprint\">\nGeometry intersection = Geometry.valueOf(\"POLYGON((0 0 0, 2 0 0, 2 2 0, 0 2 0, 0 0 0))\");\n\nQuery<Shape> query = geometryCollection.query(\"geom\",intersection, \n GeometryOperator.INTERSECT);\n\nRowSet<Shape> rowSet = query.fetch(false);\nwhile(rowSet.hasNext()){\n\tShape shape = rowSet.next();\n\tSystem.out.println(shape);\n<\/pre>\n<p><b>C<\/b><\/p>\n<pre class=\"prettyprint\">\nGSQuery* query;\nGSRowSet* rowSet;\nGeometryRow geometryRow;\n\nconst GSChar* point = \"POINT(1 4.56 4.2)\";\ngsQueryByGeometry(collection,\"shape\",point,GS_GEOMETRY_OPERATOR_INTERSECT,&amp;query);\n\ngsFetch(query,GS_FALSE,&amp;rowSet);\n\nwhile(gsHasNextRow(rowSet)){\n\tgsGetNextRow(rowSet, &amp;fetchedRow);\n\tGSChar timeStr[GS_TIME_STRING_SIZE_MAX];\n\tgsFormatTime(fetchedRow.timestamp,timeStr,sizeof(timeStr));\n\n\tprintf(\"Name = %s\",fetchedRow.name);\n\tprintf(\" Timestamp = %s\",timeStr);\n\tprintf(\" Volume = %.2lf\", fetchedRow.volume);\n\tprintf(\" Perimeter = %.2lf\", fetchedRow.perimeter);\n\tprintf(\" Shape = %sn\",fetchedRow.shape);\n<\/pre>\n<h3 id=\"geometry-tql\">TQL Queries with Geometry Values<\/h3>\n<p>TQL can be used to check for geometric intersections along with other conditions you wish to specify. In the case of comparing two <i>non-quadratic<\/i> shapes, you can use the GIS function <code>ST_MBRIntersects(geometry1,geometry2)<\/code>. If you wish to specify a Geometry to check for an intersection, simply enter the shape in WKT form and turn it into a Geometry object with TQL&#8217;s <code>ST_GeomFromText(wkt)<\/code> function. <\/p>\n<p>Let&#8217;s say we want to fetch up to 5 rows whose &#8216;geom&#8217; column value intersects with <b>POLYGON<\/b>:<br \/>\n<code>POLYGON((2 2 4, 5 2 4, 5 2 8, 2 2 8, 2 2 4))<\/code> <b>AND<\/b> whose <i>value<\/i> column is greater than 7.5 in <i>descending<\/i> order. You could issue the query as follows: <\/p>\n<pre class=\"prettyprint\">\nString tql = \"SELECT * WHERE ST_MBRIntersects(geom,\" +  \n\"ST_GeomFromText('POLYGON((2 2 4, 5 2 4, 5 2 8, 2 2 8, 2 2 4))'))\"\n+ \" AND value > 7.5 ORDER BY value DESC LIMIT 5\";\n\nQuery&lt;Row&gt; query = collection.query(tql);\n<\/pre>\n<p>One thing to note about <i>ST_MBRIntersects<\/i> is that you cannot use <i>QUADRATICSURFACES<\/i> for comparison. In the case that you want to check for intersection between a <i>quadratic surface<\/i> and a <i>non-quadratic-surface<\/i>. You can use the <code>ST_QSFMBRIntersects(quadratic,geometry)<\/code> to check for the intersection and use <code>ST_MakeQSF(A00,A10,A20,A01...)<\/code> The <i>A00, A10, A20,A01<\/i> are used to represent the coefficents of the <code>&lt;AX,X&gt; + BX + C<\/code> equation that make up the Quadratic Surface.<br \/>\n<b>Example of Quadratic Surface Query<\/b><\/p>\n<pre class=\"prettyprint\">\nGSQuery* query;\nGSRowSet* rowSet;\n\ngsQuery(timeseries, \n  \"select * where STQSFMBRIntersects( \nST_MakeQSF(84,2,3,5,6,7,8,9,10,12,13,14,15,16,17,18),geom) AND id='row1'\", \n&amp;query);\n\ngsFetch(query,GS_FALSE,&amp;rowSet);\n<\/pre>\n<h2 id=\"uses-spatial\">Best Uses of Spatial Data <\/h2>\n<p>Geometric and spatial data types are highly useful in domains like engineering, science, architecture, geography, and IoT. In geography or IoT, spatial data can be used to represent latitude, longitude, and elevation of sensors or objects. On example could be the last three categories can be represented as three-dimensional point in the format <code>POINT(latitude longitude elevation)<\/code>. You can use spatial intersections with <i>POINT&#8217;s<\/i> to find a row at a specific location. <\/p>\n<p><i>POLYGON<\/i>&#8216;s can be used to find rows that are within a geographic range. For example, a geometric query can be used with <code>POLYGON(57 110, 59 110, 59 130, 57 130, 57 110)<\/code> to find all rows within the area between 57 and 59 latitude and between 130 and 110 longitude. <\/p>\n<p>Linestrings, polygons, and surfaces can be used to represent vectors or three dimensional object. Being able to create, store, query, and index spatial data is especially useful for fields like engineering and architecture where buildings and devices are based off of 3D designs. <\/p>\n<p>A specific use case for GridDB could involve creating a collection of traffic sensors. It can store and track general data like whether its active or how many cars it has seen and other values. You can store its geographic location in terms of a <b>POINT<\/b> with the <b>GEOMETRY<\/b>. Intersection queries can be used to find filter based on locations using either API functions or TQL. <\/p>\n<p><b>Traffic Sensor in Java<\/b><\/p>\n<pre class=\"prettyprint\">\npublic class TrafficLight {\n\t@RowKey\n\tpublic  String tag; \/\/ Sensor Id of Smart Traffic Light\t\n\tpublic Geometry point; \/\/ Latitude, Longitude, and Elevation of Sensor\n\tpublic Date installation; \/\/ Time of installation to the Traffic Grid\n\tpublic boolean active; \/\/ Whether the traffic light sensor has been activated\n\tpublic int reports; \/\/ Number of reports that the Traffic Light has issued\n\tpublic String streets; \/\/ Cross streets of Traffic Light\n\/\/ (snip)\n<\/pre>\n<p><b>Querying the Traffic Collection in Java<\/b><\/p>\n<pre class=\"prettyprint\">\nCollection&lt;String,TrafficLight&gt; trafficLightCollection =  \n  gridstore.putCollection(\"trafficLights101\",TrafficLight.class);\n\/\/ (snip)\ntrafficLightCollection.createIndex(\"point\",IndexType.SPATIAL);\n\/\/ (snip)\n\/\/ Search for a specific POINT\nString ptTql = \"SELECT * WHERE ST_MBRIntersects(point,\" +\n                \"ST_GeomFromText('POINT(47.33 84.72 0.7)'))\";\n\nQuery&lt;TrafficLight&gt; ptQuery = trafficLightCollection.query(ptTql);\n\/\/ (snip)\n\/\/ Search for Point in a 2D Range using POLYGON\nString tql = \"SELECT * WHERE ST_MBRIntersects(point,\" + \n            \"ST_GeomFromText('POLYGON((49.00 86.00, 51.00 86.00,\" +\n             \"51.00 87.00, 49.00 87.00, 49.00 86.00))'))\";\n\nQuery&lt;TrafficLight&gt; query = trafficLightCollection.query(tql);\n<\/pre>\n<h2 id=\"griddb-se\">Using GridDB Standard Edition<\/h2>\n<p>In GridDB Community edition it is possible to create <b>Geometry<\/b> objects but it is not possible to insert them as column values or use them as part of a container&#8217;s schema. These features are only available for <b>Standard Edition<\/b> and beyond. GridDB Standard Edition can be used with <a href=\"https:\/\/aws.amazon.com\/marketplace\/pp\/B01N9QMCMF\/?ref=_ptnr_web_us\" target=\"_blank\" title=\"GridDB SE AWS\" rel=\"noopener noreferrer\">AWS<\/a>. General setup and configuration information can be found in the <a href=\"https:\/\/griddb.net\/en\/docs\/manuals\/v3.1\/GridDB_QuickStartGuide.html\" target=\"_blank\" title=\"Quick Start\" rel=\"noopener noreferrer\">Quick Start Guide<\/a>.<\/p>\n<p>More information on the GEOMETRY type can be found in <a href=\"https:\/\/griddb.net\/en\/docs\/manuals\/v3.1\/GridDB_TechnicalReference.html#sec-4.3.3\" target=\"_blank\" title=\"Geometry Section\" rel=\"noopener noreferrer\">this section<\/a> of the GridDB SE Technical Reference. There are more details on <a href=\"https:\/\/griddb.net\/en\/docs\/manuals\/v3.1\/GridDB_API_Reference.html#sec-3-2-9\" target=\"_blank\" title=\"Spatial Operations\" rel=\"noopener noreferrer\">Spatial operations<\/a> in the API Reference manual. GridDB uses regular expressions patterns to determine if an enter format is valid WKT. The patterns that are acceptable can be found in this section of the <a href=\"https:\/\/github.com\/griddb\/griddb_nosql\/blob\/master\/java_client\/src\/com\/toshiba\/mwcloud\/gs\/common\/GeometryUtils.java\" target=\"_blank\" title=\"GridDB Geometry Source Code\" rel=\"noopener noreferrer\">GridDB source code<\/a>. <\/p>\n<style>\n#matrix-table{\n    width: 50%;\n}\n#matrix-table tr td { \n      text-align: center; \n}\n.big-parenthesis {\n      font-size: 10em;\n}\n<\/style>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Data comes in many, many forms. It comes temporally as well as spatially. GridDB&#8217;s Timeseries containers as well as its TQL and time-specific API operations cover the time aspect of data. GridDB has geospatial data covered as well in GridDB Standard Edition and Advanced Edition. Support is provided with Geometry Columns and Data Types [&hellip;]<\/p>\n","protected":false},"author":123,"featured_media":22055,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[121],"tags":[],"class_list":["post-46561","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Using Geometry Values with GridDB | GridDB: Open Source Time Series Database for IoT<\/title>\n<meta name=\"description\" content=\"Introduction Data comes in many, many forms. It comes temporally as well as spatially. GridDB&#039;s Timeseries containers as well as its TQL and time-specific\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using Geometry Values with GridDB | GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"og:description\" content=\"Introduction Data comes in many, many forms. It comes temporally as well as spatially. GridDB&#039;s Timeseries containers as well as its TQL and time-specific\" \/>\n<meta property=\"og:url\" content=\"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/\" \/>\n<meta property=\"og:site_name\" content=\"GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/griddbcommunity\/\" \/>\n<meta property=\"article:published_time\" content=\"2017-09-27T07:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-13T20:54:31+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/griddb.net\/wp-content\/uploads\/2017\/09\/blog_title_18.png\" \/>\n\t<meta property=\"og:image:width\" content=\"870\" \/>\n\t<meta property=\"og:image:height\" content=\"490\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Joshua Pascascio\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:site\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Joshua Pascascio\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/\"},\"author\":{\"name\":\"Joshua Pascascio\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/ca72185e9a3778df765a76313f789fd8\"},\"headline\":\"Using Geometry Values with GridDB\",\"datePublished\":\"2017-09-27T07:00:00+00:00\",\"dateModified\":\"2025-11-13T20:54:31+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/\"},\"wordCount\":1812,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2017\/09\/blog_title_18.png\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/\",\"url\":\"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/\",\"name\":\"Using Geometry Values with GridDB | GridDB: Open Source Time Series Database for IoT\",\"isPartOf\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2017\/09\/blog_title_18.png\",\"datePublished\":\"2017-09-27T07:00:00+00:00\",\"dateModified\":\"2025-11-13T20:54:31+00:00\",\"description\":\"Introduction Data comes in many, many forms. It comes temporally as well as spatially. GridDB's Timeseries containers as well as its TQL and time-specific\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/#primaryimage\",\"url\":\"\/wp-content\/uploads\/2017\/09\/blog_title_18.png\",\"contentUrl\":\"\/wp-content\/uploads\/2017\/09\/blog_title_18.png\",\"width\":870,\"height\":490},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website\",\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/\",\"name\":\"GridDB: Open Source Time Series Database for IoT\",\"description\":\"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL\",\"publisher\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\",\"name\":\"Fixstars\",\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"contentUrl\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"width\":200,\"height\":83,\"caption\":\"Fixstars\"},\"image\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/griddbcommunity\/\",\"https:\/\/x.com\/GridDBCommunity\",\"https:\/\/www.linkedin.com\/company\/griddb-by-toshiba\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/ca72185e9a3778df765a76313f789fd8\",\"name\":\"Joshua Pascascio\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/872ef8be79cb5117c256feb4c279ac41b954bfba599d647db925185c449aff1c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/872ef8be79cb5117c256feb4c279ac41b954bfba599d647db925185c449aff1c?s=96&d=mm&r=g\",\"caption\":\"Joshua Pascascio\"},\"url\":\"https:\/\/griddb.net\/en\/author\/joshua\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using Geometry Values with GridDB | GridDB: Open Source Time Series Database for IoT","description":"Introduction Data comes in many, many forms. It comes temporally as well as spatially. GridDB's Timeseries containers as well as its TQL and time-specific","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/","og_locale":"en_US","og_type":"article","og_title":"Using Geometry Values with GridDB | GridDB: Open Source Time Series Database for IoT","og_description":"Introduction Data comes in many, many forms. It comes temporally as well as spatially. GridDB's Timeseries containers as well as its TQL and time-specific","og_url":"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/","og_site_name":"GridDB: Open Source Time Series Database for IoT","article_publisher":"https:\/\/www.facebook.com\/griddbcommunity\/","article_published_time":"2017-09-27T07:00:00+00:00","article_modified_time":"2025-11-13T20:54:31+00:00","og_image":[{"width":870,"height":490,"url":"https:\/\/griddb.net\/wp-content\/uploads\/2017\/09\/blog_title_18.png","type":"image\/png"}],"author":"Joshua Pascascio","twitter_card":"summary_large_image","twitter_creator":"@GridDBCommunity","twitter_site":"@GridDBCommunity","twitter_misc":{"Written by":"Joshua Pascascio","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/#article","isPartOf":{"@id":"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/"},"author":{"name":"Joshua Pascascio","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/ca72185e9a3778df765a76313f789fd8"},"headline":"Using Geometry Values with GridDB","datePublished":"2017-09-27T07:00:00+00:00","dateModified":"2025-11-13T20:54:31+00:00","mainEntityOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/"},"wordCount":1812,"commentCount":0,"publisher":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2017\/09\/blog_title_18.png","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/","url":"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/","name":"Using Geometry Values with GridDB | GridDB: Open Source Time Series Database for IoT","isPartOf":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/#primaryimage"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2017\/09\/blog_title_18.png","datePublished":"2017-09-27T07:00:00+00:00","dateModified":"2025-11-13T20:54:31+00:00","description":"Introduction Data comes in many, many forms. It comes temporally as well as spatially. GridDB's Timeseries containers as well as its TQL and time-specific","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/blog\/using-geometry-values-griddb\/#primaryimage","url":"\/wp-content\/uploads\/2017\/09\/blog_title_18.png","contentUrl":"\/wp-content\/uploads\/2017\/09\/blog_title_18.png","width":870,"height":490},{"@type":"WebSite","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website","url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/","name":"GridDB: Open Source Time Series Database for IoT","description":"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL","publisher":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization","name":"Fixstars","url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/","url":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","contentUrl":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","width":200,"height":83,"caption":"Fixstars"},"image":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/griddbcommunity\/","https:\/\/x.com\/GridDBCommunity","https:\/\/www.linkedin.com\/company\/griddb-by-toshiba"]},{"@type":"Person","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/ca72185e9a3778df765a76313f789fd8","name":"Joshua Pascascio","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/872ef8be79cb5117c256feb4c279ac41b954bfba599d647db925185c449aff1c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/872ef8be79cb5117c256feb4c279ac41b954bfba599d647db925185c449aff1c?s=96&d=mm&r=g","caption":"Joshua Pascascio"},"url":"https:\/\/griddb.net\/en\/author\/joshua\/"}]}},"_links":{"self":[{"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/posts\/46561","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/users\/123"}],"replies":[{"embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/comments?post=46561"}],"version-history":[{"count":1,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/posts\/46561\/revisions"}],"predecessor-version":[{"id":51253,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/posts\/46561\/revisions\/51253"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/media\/22055"}],"wp:attachment":[{"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/media?parent=46561"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/categories?post=46561"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/tags?post=46561"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}