From: Paul Ramsey Date: Mon, 27 Feb 2012 22:08:12 +0000 (+0000) Subject: Try again with line endings, this time using eol-style instead of eol-type (#1605) X-Git-Tag: 2.0.0beta1~32 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=729d1061cbed81d7d1ddf339ff8e948dc742f41d;p=postgis Try again with line endings, this time using eol-style instead of eol-type (#1605) git-svn-id: http://svn.osgeo.org/postgis/trunk@9324 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/doc/html/image_src/st_azimuthmath.sql b/doc/html/image_src/st_azimuthmath.sql index 21c0e5635..a3e00ba5c 100644 --- a/doc/html/image_src/st_azimuthmath.sql +++ b/doc/html/image_src/st_azimuthmath.sql @@ -1,37 +1,37 @@ --- st_azimuth01.wkt -POINT(25 45); --point 1 -POINT(75 100); -- point 2 -SELECT ST_AsText( - ST_MakeLine( - ST_Point(25,45), ST_Point(25 + ST_Length('LINESTRING(25 45,75 100)'::Geometry) ,45)) - ); -- horizontal -- LINESTRING(25 45,99.33034 45) - --- control point -SELECT ST_AsText( - ST_SnapToGrid( - ST_PointN(ST_Boundary(ST_Buffer(ST_Point(25, 45),ST_Length('LINESTRING(25 45,75 100)'::Geometry))),30), - 0.0001)); --POINT(86.8034 86.2957) - --- arc from horizontal --- LINESTRING(99.33034 45,98.9724 52.28569,97.90206 59.50121,96.12963 66.57707,93.67218 73.44514,90.55337 80.03925,86.80325 86.29593,82.45792 92.15489,77.55924 97.55973,75 100) -SELECT ST_AsText(ST_SnapToGrid(ST_CurveToLine('CIRCULARSTRING(99.33034 45, 86.8034 86.2957,75 100)',16),0.00001)); - --- st_azimuth02.wkt -POINT(75 100); --point 1 -POINT(25 45); -- point 2 -SELECT ST_AsText( - ST_MakeLine( - ST_Point(75,100), ST_Point(75 + ST_Length('LINESTRING(25 45,75 100)'::Geometry) ,100)) - ); -- horizontal -- LINESTRING(75 100,149.33034 100) - --- control point -SELECT ST_AsText( - ST_SnapToGrid( - ST_PointN(ST_Boundary(ST_Buffer(ST_Point(75, 100),ST_Length('LINESTRING(25 45,75 100)'::Geometry))),30), - 0.0001)); --POINT(136.8034 141.2957) - --- arc from horizontal --- LINESTRING(149.33034 100,148.97241 107.28565,147.90209 114.50113,146.12969 121.57695,143.67226 128.44498,140.55349 135.03907,136.8034 141.29571,132.4581 147.15465,127.55946 152.55946,122.15464 157.4581,116.29569 161.80338,110.03905 165.55347,103.44496 168.67223,96.57693 171.12965,89.5011 172.90205,82.28562 173.97236,74.99997 174.33027,67.71433 173.97235,60.49885 172.90203,53.42302 171.12962,46.55499 168.6722,39.96091 165.55342,33.70427 161.80333,27.84533 157.45804,22.44051 152.55939,17.54187 147.15457,13.19659 141.29563,9.44651 135.03898,6.32774 128.44489,3.87032 121.57686,2.09792 114.50103,1.02761 107.28555,0.6697 99.99991,1.02762 92.71426,2.09794 85.49878,3.87035 78.42295,6.32777 71.55493,9.44655 64.96084,13.19664 58.7042,17.54193 52.84526,22.44058 47.44045,25 45) -SELECT ST_AsText(ST_SnapToGrid(ST_CurveToLine('CIRCULARSTRING(149.33034 100, 136.8034 141.2957,25 45)',16),0.00001)); - - +-- st_azimuth01.wkt +POINT(25 45); --point 1 +POINT(75 100); -- point 2 +SELECT ST_AsText( + ST_MakeLine( + ST_Point(25,45), ST_Point(25 + ST_Length('LINESTRING(25 45,75 100)'::Geometry) ,45)) + ); -- horizontal -- LINESTRING(25 45,99.33034 45) + +-- control point +SELECT ST_AsText( + ST_SnapToGrid( + ST_PointN(ST_Boundary(ST_Buffer(ST_Point(25, 45),ST_Length('LINESTRING(25 45,75 100)'::Geometry))),30), + 0.0001)); --POINT(86.8034 86.2957) + +-- arc from horizontal +-- LINESTRING(99.33034 45,98.9724 52.28569,97.90206 59.50121,96.12963 66.57707,93.67218 73.44514,90.55337 80.03925,86.80325 86.29593,82.45792 92.15489,77.55924 97.55973,75 100) +SELECT ST_AsText(ST_SnapToGrid(ST_CurveToLine('CIRCULARSTRING(99.33034 45, 86.8034 86.2957,75 100)',16),0.00001)); + +-- st_azimuth02.wkt +POINT(75 100); --point 1 +POINT(25 45); -- point 2 +SELECT ST_AsText( + ST_MakeLine( + ST_Point(75,100), ST_Point(75 + ST_Length('LINESTRING(25 45,75 100)'::Geometry) ,100)) + ); -- horizontal -- LINESTRING(75 100,149.33034 100) + +-- control point +SELECT ST_AsText( + ST_SnapToGrid( + ST_PointN(ST_Boundary(ST_Buffer(ST_Point(75, 100),ST_Length('LINESTRING(25 45,75 100)'::Geometry))),30), + 0.0001)); --POINT(136.8034 141.2957) + +-- arc from horizontal +-- LINESTRING(149.33034 100,148.97241 107.28565,147.90209 114.50113,146.12969 121.57695,143.67226 128.44498,140.55349 135.03907,136.8034 141.29571,132.4581 147.15465,127.55946 152.55946,122.15464 157.4581,116.29569 161.80338,110.03905 165.55347,103.44496 168.67223,96.57693 171.12965,89.5011 172.90205,82.28562 173.97236,74.99997 174.33027,67.71433 173.97235,60.49885 172.90203,53.42302 171.12962,46.55499 168.6722,39.96091 165.55342,33.70427 161.80333,27.84533 157.45804,22.44051 152.55939,17.54187 147.15457,13.19659 141.29563,9.44651 135.03898,6.32774 128.44489,3.87032 121.57686,2.09792 114.50103,1.02761 107.28555,0.6697 99.99991,1.02762 92.71426,2.09794 85.49878,3.87035 78.42295,6.32777 71.55493,9.44655 64.96084,13.19664 58.7042,17.54193 52.84526,22.44058 47.44045,25 45) +SELECT ST_AsText(ST_SnapToGrid(ST_CurveToLine('CIRCULARSTRING(149.33034 100, 136.8034 141.2957,25 45)',16),0.00001)); + + diff --git a/extras/tiger_geocoder/README b/extras/tiger_geocoder/README index 0e9f0f950..3cb020d2c 100644 --- a/extras/tiger_geocoder/README +++ b/extras/tiger_geocoder/README @@ -1,62 +1,62 @@ -$Id$ -TIGER Geocoder - - 2011/01/23 - - A plpgsql based geocoder written for TIGER census data. - -Design: - -There are two components to the geocoder, the address normalizer and the -address geocoder. These two components are described separately. - -The goal of this project is to build a fully functional geocoder that can -process an arbitrary address string and, using normalized TIGER census data, -produce a point geometry reflecting the location of the given address. - -- The geocoder should be simple for anyone familiar with PostGIS to install - and use. -- It should be robust enough to function properly despite formatting and - spelling errors. -- It should be extensible enough to be used with future data updates, or - alternate data sources with a minimum of coding changes. - -Installation: - - Refer to the README in the respective year tiger folder for installation and example usage. The latest scripts as of this writing are for tiger_2010. - - -Usage: - - SELECT g.rating, g.geomout, (addy).* FROM geocode('address string') As g; - -e.g: SELECT g.rating, - ST_X(geomout) As lon, - ST_Y(geomout) As lat, (addy).* FROM geocode('1731 New Hampshire Avenue Northwest, Washington, DC 20010') As g; - -Notes: - -- The assumed format for the address is the US Postal Service standard: - () indicates a field required by the geocoder, [] indicates an optional field. - - (address) [dirPrefix] (streetName) [streetType] [dirSuffix] - [internalAddress] [location] [state] [zipCode] - - - -Address Normalizer: - -The goal of the address normalizer is to provide a robust function to break a -given address string down into the components of an address. While the -normalizer is built specifically for the normalized US TIGER Census data, it -has been designed to be reasonably extensible to other data sets and localities. - -Usage: - - normalize_address('address string'); - - e.g.: SELECT naddy.* FROM normalize_address('29645 7th Street SW Federal Way 98023') AS naddy; - - address | predirabbrev | streetname | streettypeabbrev | postdirabbrev | internal | location | stateabbrev | zip | parsed - ---------+-------------+-----------------------+------------------+---------------+----------+----------+-------------+-------+-------- +$Id$ +TIGER Geocoder + + 2011/01/23 + + A plpgsql based geocoder written for TIGER census data. + +Design: + +There are two components to the geocoder, the address normalizer and the +address geocoder. These two components are described separately. + +The goal of this project is to build a fully functional geocoder that can +process an arbitrary address string and, using normalized TIGER census data, +produce a point geometry reflecting the location of the given address. + +- The geocoder should be simple for anyone familiar with PostGIS to install + and use. +- It should be robust enough to function properly despite formatting and + spelling errors. +- It should be extensible enough to be used with future data updates, or + alternate data sources with a minimum of coding changes. + +Installation: + + Refer to the README in the respective year tiger folder for installation and example usage. The latest scripts as of this writing are for tiger_2010. + + +Usage: + + SELECT g.rating, g.geomout, (addy).* FROM geocode('address string') As g; + +e.g: SELECT g.rating, + ST_X(geomout) As lon, + ST_Y(geomout) As lat, (addy).* FROM geocode('1731 New Hampshire Avenue Northwest, Washington, DC 20010') As g; + +Notes: + +- The assumed format for the address is the US Postal Service standard: + () indicates a field required by the geocoder, [] indicates an optional field. + + (address) [dirPrefix] (streetName) [streetType] [dirSuffix] + [internalAddress] [location] [state] [zipCode] + + + +Address Normalizer: + +The goal of the address normalizer is to provide a robust function to break a +given address string down into the components of an address. While the +normalizer is built specifically for the normalized US TIGER Census data, it +has been designed to be reasonably extensible to other data sets and localities. + +Usage: + + normalize_address('address string'); + + e.g.: SELECT naddy.* FROM normalize_address('29645 7th Street SW Federal Way 98023') AS naddy; + + address | predirabbrev | streetname | streettypeabbrev | postdirabbrev | internal | location | stateabbrev | zip | parsed + ---------+-------------+-----------------------+------------------+---------------+----------+----------+-------------+-------+-------- 29645 | | 7th Street SW Federal | Way | | | | | 98023 | \ No newline at end of file diff --git a/extras/tiger_geocoder/tiger_2006andbefore/README b/extras/tiger_geocoder/tiger_2006andbefore/README index 6e4fc4c6d..a476d735f 100644 --- a/extras/tiger_geocoder/tiger_2006andbefore/README +++ b/extras/tiger_geocoder/tiger_2006andbefore/README @@ -1,350 +1,350 @@ -$Id: README 6731 2011-01-25 18:08:57Z robe $ -TIGER Geocoder - - 2004/10/28 - - A plpgsql based geocoder written for TIGER census data. - -Design: - -There are two components to the geocoder, the address normalizer and the -address geocoder. These two components are described seperatly below. - -The goal of this project is to build a fully functional geocoder that can -process an arbitrary address string and, using normalized TIGER censes data, -produce a point geometry reflecting the location of the given address. - -- The geocoder should be simple for anyone familiar with PostGIS to install - and use. -- It should be robust enough to function properly despite formatting and - spelling errors. -- It should be extensible enough to be used with future data updates, or - alternate data sources with a minimum of coding changes. - -Installation: - - Refer to the INSTALL file for installation instructions. - -Usage: - - refcursor geocode(refcursor, 'address string'); - -Notes: - -- The assumed format for the address is the US Postal Service standard: - () indicates a field required by the geocoder, [] indicates an optional field. - - (address) [dirPrefix] (streetName) [streetType] [dirSuffix] - [internalAddress] [location] [state] [zipCode] - - - -Address Normalizer: - -The goal of the address normalizer is to provide a robust function to break a -given address string down into the components of an address. While the -normalizer is built specifically for the normalized US TIGER Census data, it -has been designed to be reasonably extensible to other data sets and localities. - -Usage: - - normalize_address('address string'); - -Support functions: - - location_extract_countysub_exact('partial address string', 'state abbreviation') - location_extract_countysub_fuzzy('partial address string', 'state abbreviation') - location_extract_place_exact('partial address string', 'state abbreviation') - location_extract_place_fuzzy('partial address string', 'state abbreviation') - cull_null('string') - count_words('string') - get_last_words('string') - state_extract('partial address string') - levenshtein_ignore_case('string', 'string') - -Notes: - -- A set of lookup tables, listed below, is used to provide street type, - secondary unit and direction abbreviation standards for a given set - of data. These are provided with the geocoder, but will need to be - customized for the data used. - - direction_lookup - secondary_unit_lookup - street_type_lookup - -- Additional lookup tables are required to perform matching for state - and location extraction. The state lookup is derived from the - US Postal Service standards, while the place and county subdivision - lookups are generated from the dataset. The creation statements for - the place and countysub tables are given in the INSTALL file. - - state_lookup - place_lookup - countysub_lookup - -- The use of lookup tables is intended to provide a versatile way of applying - the normalizer to data sets and localities other than the US Census TIGER - data. However, due to the need for matching based extraction in the event - of poorly formatted or incomplete address strings, assumptions are made about - the data available. Most notably the division of place and county - subdivision. For data sets without exactly two logical divisions in location - precision, code changes will be required. - -- The normalizer will perform better the more information is provided. - -- The process for normalization is roughly as follows: - - Extract the address from the beginning. - Extract the zipCode from the end. - Extract the state, using a fuzzy search if exact matching fails. - Attempt to extract the location by parsing the punctuation - of the address. - Find and remove any internal address. - If internal address was found: - Set location as everything between internal address and state. - Extract the street type from the string. - If multiple potential street types are found: - If internal address was found: - Extract the last street type that preceeds the internal address. - Else: - Extract the last street type. - If street type was found: - If a word beginning with a number follows the street type. - This indicates the street type is part of the street name, - eg. 'State Hwy 92a'. - Set street type to NULL. - Else if location not yet found: - Set location as everything between street type and state. - Extract direction prefix from start of street name. - If internal address was found: - Extract direction suffix from end of street name. - Else: - Extract direction suffix from start of location. - Set street name as everything that is not the address, direction - prefix or suffix, internal address, location, state or - zip code. - Else: - If internal address was found: - Extract direction prefix from beginning of string. - Extract direction suffix before internal address. - Set street name as everything that is not the address, direction - prefix or suffix, internal address, location, state or - zip code. - Else: - Extract direction suffix. - If direction suffix is found: - Set location as everything between direction suffix and state, - zip or end of string as appropriate. - Extract direction prefix from beginning of string. - Set street name as everything that is not the address, direction - prefix or suffix, internal address, location, state or - zip code. - Else: - Attempt to determine the location via exact comparison against - the places lookup. - Attempt to determine the location via exact comparison against - the countysub lookup. - Attempt to determine the location via fuzzy comparison against - the places lookup. - Attempt to determine the location via fuzzy comparison against - the countysub lookup. - Extract direction prefix. - Set street name as everything that is not the address, direction - prefix or suffix, internal address, location, state or - zip code. - - - -Address Geocoder: - -The goal of the address geocoder is to provide a robust means of searching -the database for a match to whatever data the user provides. To accomplish -this, the coder uses a series of checks and fallthrough cases. Starting with -the most specific combination of parameters, the algorithm works outwards -towards the most vague combination, until valid results are found. The result -of this is that the more accurate information that is provided, the faster the -algorithm will return. - -Usage: - - normalize_address('address string'); - -Support functions: - - geocode_address(cursor, address, 'dirPrefix', 'streetName', 'streetType', - 'dirSuffix', 'location', 'state', zipCode) - geocode_address_zip(cursor, address, 'dirPrefix', 'streetName', - 'streetType', 'dirSuffix', zipCode) - geocode_address_countysub_exact(cursor, address, 'dirPrefix', 'streetName', - 'streetType', 'dirSuffix', 'location', 'state') - geocode_address_countysub_fuzzy(cursor, address, 'dirPrefix', 'streetName', - 'streetType', 'dirSuffix', 'location', 'state') - geocode_address_place_exact(cursor, address, 'dirPrefix', 'streetName', - 'streetType', 'dirSuffix', 'location', 'state') - geocode_address_place_fuzzy(cursor, address, 'dirPrefix', 'streetName', - 'streetType', 'dirSuffix', 'location', 'state') - rate_attributes('dirPrefixA', 'dirPrefixB', 'streetNameA', 'streetNameB', - 'streetTypeA', 'streetTypeB', 'dirSuffixA', 'dirSuffixB') - rate_attributes('dirPrefixA', 'dirPrefixB', 'streetNameA', 'streetNameB', - 'streetTypeA', 'streetTypeB', 'dirSuffixA', 'dirSuffixB', - 'locationA', 'locationB') - location_extract_countysub_exact('partial address string', 'state abbreviation') - location_extract_countysub_fuzzy('partial address string', 'state abbreviation') - location_extract_place_exact('partial address string', 'state abbreviation') - location_extract_place_fuzzy('partial address string', 'state abbreviation') - cull_null('string') - count_words('string') - get_last_words('string') - state_extract('partial address string') - levenshtein_ignore_case('string', 'string') - interpolate_from_address(given address, from address L, to address L, - from address R, to address R, street segment) - interpolate_from_address(given address, 'from address L', 'to address L', - 'from address R', 'to address R', street segment) - includes_address(given address, from address L, to address L, - from address R, to address R) - includes_address(given address, 'from address L', 'to address L', - 'from address R', 'to address R') - -Notes: - -- The geocoder is quite dependent on the address normalizer. The direction - prefix and suffix, streetType and state are all expected to be standard - abbreviations that will match exactly to the database. - -- Either a zip code, or a location must be provided. No exception will be - thrown, but the result will be null. If the zip code or location cannot - be matched, with the other information provided, against the database - the result is null. - -- The process is as follows: - - If a zipCode is provided: - Check if the zipCode, streetName and optionally state match any roads. - If they do: - Check if the given address fits any of the roads. - If it does: - Return the matching road segment information, rating and - interpolated geographic point. - If location exactly matches a place: - Check if the place, streetName and optionally state match any roads. - If they do: - Check if the given address fits any of the roads. - If it does: - Return the matching road segment information, rating and - interpolated geographic point. - If location exactly matches a countySubdivision: - Check if the countySubdivision, streetName and optionally state - match any roads. - If they do: - Check if the given address fits any of the roads. - If it does: - Return the matching road segment information, rating and - interpolated geographic point. - If location approximately matches a place: - Check if the place, streetName and optionally state match any roads. - If they do: - Check if the given address fits any of the roads. - If it does: - Return the matching road segment information, rating and - interpolated geographic point. - If location approximately matches a countySubdivision: - Check if the countySubdivision, streetName and optionally state - match any roads. - If they do: - Check if the given address fits any of the roads. - If it does: - Return the matching road segment information, rating and - interpolated geographic point. - - -Current Issues / Known Failures: - -- If a location starts with a direction, eg. East Seattle, and no suffix - direction is given, the direction from the location will be interpreted - as the streets suffix direction. - - '18196 68th Ave East Seattle Washington' - address = 18196 - dirPrefix = NULL - streetName = '68th' - streetType = 'Ave' - dirSuffix = 'E' - location = 'Seattle' - state = 'WA' - zip = NULL - -- The last possible street type in the string is interpreted as the street type - to allow street names to contain type words. As a result, any location - containing a street type will have the type interpreted as the street type. - - '29645 7th Street SW Federal Way 98023' - address = 29645 - dirPrefix = NULL - streetName = 7th Street SW Federal - streetType = Way - dirSuffix = NULL - location = NULL - state = NULL - zip = 98023 - -- While some state misspellings will be picked up by the fuzzy searches, - misspelled or non-standard abbreviations may not be picked up, due to - the length (soundex uses an intial character plus three codeable - characters) - - '2554 E Highland Dr Seatel Wash' - address = 2554 - dirPrefix = 'E' - streetName = 'Highland' - streetType = 'Dr' - dirSuffix = NULL - location = 'Seatel Wash' - state = NULL - zip = NULL - -- If neither a location or a zip code are found by the normalizer, no search - is performed. - -- If neither street type, direction suffix nor location are given in the - address string, the street name is generally misclassified as the - location. - - '98 E Main Washington 98012' - address = 98 - dirPrefix = 'E' - streetName = NULL - streetType = NULL - dirSuffix = NULL - location = 'Main' - state = 'WA' - zip = 98012 - -- If no street type is given and the street name contains a type word, then the - type in the street name is interpreted as the street type. - - '1348 SW Orchard Seattle wa 98106' - 1348::SW:Orch::Seattle:WA:98106 - address = 1348 - dirPrefix = NULL - streetName = SW - streetType = Orch - dirSuffix = NULL - location = Seattle - state = WA - zip = 98106 - -- Misspellings of words are only handled so far as their soundex values match. - - 'Hiland' will not be matched with 'Highland' - soundex('Hiland') = 'H453' - soundex('Highland') = 'H245' - -- Missing words in location or street name are not handled. - - 'Redmond Fall' will not be matched with 'Redmond Fall City' - -- Unacceptable failure cases: - The street name is parsed out as 'West Central Park' - '500 South West Central Park Ave Chicago Illinois 60624' +$Id: README 6731 2011-01-25 18:08:57Z robe $ +TIGER Geocoder + + 2004/10/28 + + A plpgsql based geocoder written for TIGER census data. + +Design: + +There are two components to the geocoder, the address normalizer and the +address geocoder. These two components are described seperatly below. + +The goal of this project is to build a fully functional geocoder that can +process an arbitrary address string and, using normalized TIGER censes data, +produce a point geometry reflecting the location of the given address. + +- The geocoder should be simple for anyone familiar with PostGIS to install + and use. +- It should be robust enough to function properly despite formatting and + spelling errors. +- It should be extensible enough to be used with future data updates, or + alternate data sources with a minimum of coding changes. + +Installation: + + Refer to the INSTALL file for installation instructions. + +Usage: + + refcursor geocode(refcursor, 'address string'); + +Notes: + +- The assumed format for the address is the US Postal Service standard: + () indicates a field required by the geocoder, [] indicates an optional field. + + (address) [dirPrefix] (streetName) [streetType] [dirSuffix] + [internalAddress] [location] [state] [zipCode] + + + +Address Normalizer: + +The goal of the address normalizer is to provide a robust function to break a +given address string down into the components of an address. While the +normalizer is built specifically for the normalized US TIGER Census data, it +has been designed to be reasonably extensible to other data sets and localities. + +Usage: + + normalize_address('address string'); + +Support functions: + + location_extract_countysub_exact('partial address string', 'state abbreviation') + location_extract_countysub_fuzzy('partial address string', 'state abbreviation') + location_extract_place_exact('partial address string', 'state abbreviation') + location_extract_place_fuzzy('partial address string', 'state abbreviation') + cull_null('string') + count_words('string') + get_last_words('string') + state_extract('partial address string') + levenshtein_ignore_case('string', 'string') + +Notes: + +- A set of lookup tables, listed below, is used to provide street type, + secondary unit and direction abbreviation standards for a given set + of data. These are provided with the geocoder, but will need to be + customized for the data used. + + direction_lookup + secondary_unit_lookup + street_type_lookup + +- Additional lookup tables are required to perform matching for state + and location extraction. The state lookup is derived from the + US Postal Service standards, while the place and county subdivision + lookups are generated from the dataset. The creation statements for + the place and countysub tables are given in the INSTALL file. + + state_lookup + place_lookup + countysub_lookup + +- The use of lookup tables is intended to provide a versatile way of applying + the normalizer to data sets and localities other than the US Census TIGER + data. However, due to the need for matching based extraction in the event + of poorly formatted or incomplete address strings, assumptions are made about + the data available. Most notably the division of place and county + subdivision. For data sets without exactly two logical divisions in location + precision, code changes will be required. + +- The normalizer will perform better the more information is provided. + +- The process for normalization is roughly as follows: + + Extract the address from the beginning. + Extract the zipCode from the end. + Extract the state, using a fuzzy search if exact matching fails. + Attempt to extract the location by parsing the punctuation + of the address. + Find and remove any internal address. + If internal address was found: + Set location as everything between internal address and state. + Extract the street type from the string. + If multiple potential street types are found: + If internal address was found: + Extract the last street type that preceeds the internal address. + Else: + Extract the last street type. + If street type was found: + If a word beginning with a number follows the street type. + This indicates the street type is part of the street name, + eg. 'State Hwy 92a'. + Set street type to NULL. + Else if location not yet found: + Set location as everything between street type and state. + Extract direction prefix from start of street name. + If internal address was found: + Extract direction suffix from end of street name. + Else: + Extract direction suffix from start of location. + Set street name as everything that is not the address, direction + prefix or suffix, internal address, location, state or + zip code. + Else: + If internal address was found: + Extract direction prefix from beginning of string. + Extract direction suffix before internal address. + Set street name as everything that is not the address, direction + prefix or suffix, internal address, location, state or + zip code. + Else: + Extract direction suffix. + If direction suffix is found: + Set location as everything between direction suffix and state, + zip or end of string as appropriate. + Extract direction prefix from beginning of string. + Set street name as everything that is not the address, direction + prefix or suffix, internal address, location, state or + zip code. + Else: + Attempt to determine the location via exact comparison against + the places lookup. + Attempt to determine the location via exact comparison against + the countysub lookup. + Attempt to determine the location via fuzzy comparison against + the places lookup. + Attempt to determine the location via fuzzy comparison against + the countysub lookup. + Extract direction prefix. + Set street name as everything that is not the address, direction + prefix or suffix, internal address, location, state or + zip code. + + + +Address Geocoder: + +The goal of the address geocoder is to provide a robust means of searching +the database for a match to whatever data the user provides. To accomplish +this, the coder uses a series of checks and fallthrough cases. Starting with +the most specific combination of parameters, the algorithm works outwards +towards the most vague combination, until valid results are found. The result +of this is that the more accurate information that is provided, the faster the +algorithm will return. + +Usage: + + normalize_address('address string'); + +Support functions: + + geocode_address(cursor, address, 'dirPrefix', 'streetName', 'streetType', + 'dirSuffix', 'location', 'state', zipCode) + geocode_address_zip(cursor, address, 'dirPrefix', 'streetName', + 'streetType', 'dirSuffix', zipCode) + geocode_address_countysub_exact(cursor, address, 'dirPrefix', 'streetName', + 'streetType', 'dirSuffix', 'location', 'state') + geocode_address_countysub_fuzzy(cursor, address, 'dirPrefix', 'streetName', + 'streetType', 'dirSuffix', 'location', 'state') + geocode_address_place_exact(cursor, address, 'dirPrefix', 'streetName', + 'streetType', 'dirSuffix', 'location', 'state') + geocode_address_place_fuzzy(cursor, address, 'dirPrefix', 'streetName', + 'streetType', 'dirSuffix', 'location', 'state') + rate_attributes('dirPrefixA', 'dirPrefixB', 'streetNameA', 'streetNameB', + 'streetTypeA', 'streetTypeB', 'dirSuffixA', 'dirSuffixB') + rate_attributes('dirPrefixA', 'dirPrefixB', 'streetNameA', 'streetNameB', + 'streetTypeA', 'streetTypeB', 'dirSuffixA', 'dirSuffixB', + 'locationA', 'locationB') + location_extract_countysub_exact('partial address string', 'state abbreviation') + location_extract_countysub_fuzzy('partial address string', 'state abbreviation') + location_extract_place_exact('partial address string', 'state abbreviation') + location_extract_place_fuzzy('partial address string', 'state abbreviation') + cull_null('string') + count_words('string') + get_last_words('string') + state_extract('partial address string') + levenshtein_ignore_case('string', 'string') + interpolate_from_address(given address, from address L, to address L, + from address R, to address R, street segment) + interpolate_from_address(given address, 'from address L', 'to address L', + 'from address R', 'to address R', street segment) + includes_address(given address, from address L, to address L, + from address R, to address R) + includes_address(given address, 'from address L', 'to address L', + 'from address R', 'to address R') + +Notes: + +- The geocoder is quite dependent on the address normalizer. The direction + prefix and suffix, streetType and state are all expected to be standard + abbreviations that will match exactly to the database. + +- Either a zip code, or a location must be provided. No exception will be + thrown, but the result will be null. If the zip code or location cannot + be matched, with the other information provided, against the database + the result is null. + +- The process is as follows: + + If a zipCode is provided: + Check if the zipCode, streetName and optionally state match any roads. + If they do: + Check if the given address fits any of the roads. + If it does: + Return the matching road segment information, rating and + interpolated geographic point. + If location exactly matches a place: + Check if the place, streetName and optionally state match any roads. + If they do: + Check if the given address fits any of the roads. + If it does: + Return the matching road segment information, rating and + interpolated geographic point. + If location exactly matches a countySubdivision: + Check if the countySubdivision, streetName and optionally state + match any roads. + If they do: + Check if the given address fits any of the roads. + If it does: + Return the matching road segment information, rating and + interpolated geographic point. + If location approximately matches a place: + Check if the place, streetName and optionally state match any roads. + If they do: + Check if the given address fits any of the roads. + If it does: + Return the matching road segment information, rating and + interpolated geographic point. + If location approximately matches a countySubdivision: + Check if the countySubdivision, streetName and optionally state + match any roads. + If they do: + Check if the given address fits any of the roads. + If it does: + Return the matching road segment information, rating and + interpolated geographic point. + + +Current Issues / Known Failures: + +- If a location starts with a direction, eg. East Seattle, and no suffix + direction is given, the direction from the location will be interpreted + as the streets suffix direction. + + '18196 68th Ave East Seattle Washington' + address = 18196 + dirPrefix = NULL + streetName = '68th' + streetType = 'Ave' + dirSuffix = 'E' + location = 'Seattle' + state = 'WA' + zip = NULL + +- The last possible street type in the string is interpreted as the street type + to allow street names to contain type words. As a result, any location + containing a street type will have the type interpreted as the street type. + + '29645 7th Street SW Federal Way 98023' + address = 29645 + dirPrefix = NULL + streetName = 7th Street SW Federal + streetType = Way + dirSuffix = NULL + location = NULL + state = NULL + zip = 98023 + +- While some state misspellings will be picked up by the fuzzy searches, + misspelled or non-standard abbreviations may not be picked up, due to + the length (soundex uses an intial character plus three codeable + characters) + + '2554 E Highland Dr Seatel Wash' + address = 2554 + dirPrefix = 'E' + streetName = 'Highland' + streetType = 'Dr' + dirSuffix = NULL + location = 'Seatel Wash' + state = NULL + zip = NULL + +- If neither a location or a zip code are found by the normalizer, no search + is performed. + +- If neither street type, direction suffix nor location are given in the + address string, the street name is generally misclassified as the + location. + + '98 E Main Washington 98012' + address = 98 + dirPrefix = 'E' + streetName = NULL + streetType = NULL + dirSuffix = NULL + location = 'Main' + state = 'WA' + zip = 98012 + +- If no street type is given and the street name contains a type word, then the + type in the street name is interpreted as the street type. + + '1348 SW Orchard Seattle wa 98106' + 1348::SW:Orch::Seattle:WA:98106 + address = 1348 + dirPrefix = NULL + streetName = SW + streetType = Orch + dirSuffix = NULL + location = Seattle + state = WA + zip = 98106 + +- Misspellings of words are only handled so far as their soundex values match. + + 'Hiland' will not be matched with 'Highland' + soundex('Hiland') = 'H453' + soundex('Highland') = 'H245' + +- Missing words in location or street name are not handled. + + 'Redmond Fall' will not be matched with 'Redmond Fall City' + +- Unacceptable failure cases: + The street name is parsed out as 'West Central Park' + '500 South West Central Park Ave Chicago Illinois 60624' diff --git a/extras/tiger_geocoder/tiger_2006andbefore/orig/tiger_geocoder.sql b/extras/tiger_geocoder/tiger_2006andbefore/orig/tiger_geocoder.sql index b7b8ee1f8..0d016dbf9 100644 --- a/extras/tiger_geocoder/tiger_2006andbefore/orig/tiger_geocoder.sql +++ b/extras/tiger_geocoder/tiger_2006andbefore/orig/tiger_geocoder.sql @@ -1,2657 +1,2657 @@ --- Runs the soundex function on the last word in the string provided. --- Words are allowed to be seperated by space, comma, period, new-line --- tab or form feed. -CREATE OR REPLACE FUNCTION end_soundex(VARCHAR) RETURNS VARCHAR -AS ' -DECLARE - tempString VARCHAR; -BEGIN - tempString := substring($1, ''[ ,\.\n\t\f]([a-zA-Z0-9]*)$''); - IF tempString IS NOT NULL THEN - tempString := soundex(tempString); - ELSE - tempString := soundex($1); - END IF; - return tempString; -END; -' LANGUAGE plpgsql; - --- Returns the value passed, or an empty string if null. --- This is used to concatinate values that may be null. -CREATE OR REPLACE FUNCTION cull_null(VARCHAR) RETURNS VARCHAR -AS ' -BEGIN - IF $1 IS NULL THEN - return ''''; - ELSE - return $1; - END IF; -END; -' LANGUAGE plpgsql; - --- Determine the number of words in a string. Words are allowed to --- be seperated only by spaces, but multiple spaces between --- words are allowed. -CREATE OR REPLACE FUNCTION count_words(VARCHAR) RETURNS INTEGER -AS ' -DECLARE - tempString VARCHAR; - tempInt INTEGER; - count INTEGER := 1; - lastSpace BOOLEAN := FALSE; -BEGIN - IF $1 IS NULL THEN - return -1; - END IF; - tempInt := length($1); - IF tempInt = 0 THEN - return 0; - END IF; - FOR i IN 1..tempInt LOOP - tempString := substring($1 from i for 1); - IF tempString = '' '' THEN - IF NOT lastSpace THEN - count := count + 1; - END IF; - lastSpace := TRUE; - ELSE - lastSpace := FALSE; - END IF; - END LOOP; - return count; -END; -' LANGUAGE plpgsql; - - - -CREATE OR REPLACE FUNCTION geocode(VARCHAR) RETURNS REFCURSOR -AS ' -BEGIN - return geocode(NULL, $1); -END; -' LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION geocode(REFCURSOR, VARCHAR) RETURNS REFCURSOR -AS ' -DECLARE - result REFCURSOR; - input VARCHAR; - parsed VARCHAR; - addressString VARCHAR; - address INTEGER; - directionPrefix VARCHAR; - streetName VARCHAR; - streetType VARCHAR; - directionSuffix VARCHAR; - location VARCHAR; - state VARCHAR; - zipCodeString VARCHAR; - zipCode INTEGER; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''geocode()''; - END IF; - -- Check inputs. - IF $1 IS NOT NULL THEN - result := $1; - END IF; - IF $2 IS NULL THEN - -- The address string is manditory. - RAISE EXCEPTION ''geocode() - No address string provided.''; - ELSE - input := $2; - END IF; - - -- Pass the input string into the address normalizer - parsed := normalize_address(input); - IF parsed IS NULL THEN - RAISE EXCEPTION ''geocode() - address string failed to parse.''; - END IF; - - addressString := split_part(parsed, '':'', 1); - directionPrefix := split_part(parsed, '':'', 2); - streetName := split_part(parsed, '':'', 3); - streetType := split_part(parsed, '':'', 4); - directionSuffix := split_part(parsed, '':'', 5); - location := split_part(parsed, '':'', 6); - state := split_part(parsed, '':'', 7); - zipCodeString := split_part(parsed, '':'', 8); - - -- Empty strings must be converted to nulls; - IF addressString = '''' THEN - addressString := NULL; - END IF; - IF directionPrefix = '''' THEN - directionPrefix := NULL; - END IF; - IF streetName = '''' THEN - streetName := NULL; - END IF; - IF streetType = '''' THEN - streetType := NULL; - END IF; - IF directionSuffix = '''' THEN - directionSuffix := NULL; - END IF; - IF location = '''' THEN - location := NULL; - END IF; - IF state = '''' THEN - state := NULL; - END IF; - IF zipCodeString = '''' THEN - zipCodeString := NULL; - END IF; - - -- address and zipCode must be integers - IF addressString IS NOT NULL THEN - address := to_number(addressString, ''99999999999''); - END IF; - IF zipCodeString IS NOT NULL THEN - zipCode := to_number(zipCodeString, ''99999''); - END IF; - - IF verbose THEN - RAISE NOTICE ''geocode() - address %'', address; - RAISE NOTICE ''geocode() - directionPrefix %'', directionPrefix; - RAISE NOTICE ''geocode() - streetName "%"'', streetName; - RAISE NOTICE ''geocode() - streetType %'', streetType; - RAISE NOTICE ''geocode() - directionSuffix %'', directionSuffix; - RAISE NOTICE ''geocode() - location "%"'', location; - RAISE NOTICE ''geocode() - state %'', state; - RAISE NOTICE ''geocode() - zipCode %'', zipCode; - END IF; - -- This is where any validation above the geocode_address functions would go. - - -- Call geocode_address - result := geocode_address(result, address, directionPrefix, streetName, - streetType, directionSuffix, location, state, zipCode); - RETURN result; -END; -' LANGUAGE plpgsql; - - - --- geocode(cursor, address, directionPrefix, streetName, --- streetTypeAbbreviation, directionSuffix, location, stateAbbreviation, --- zipCode) -CREATE OR REPLACE FUNCTION geocode_address(refcursor, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, INTEGER) RETURNS REFCURSOR -AS ' -DECLARE - result REFCURSOR; - address INTEGER; - directionPrefix VARCHAR; - streetName VARCHAR; - streetTypeAbbrev VARCHAR; - directionSuffix VARCHAR; - location VARCHAR; - stateAbbrev VARCHAR; - state VARCHAR; - zipCode INTEGER; - tempString VARCHAR; - tempInt VARCHAR; - locationPlaceExact BOOLEAN := FALSE; - locationPlaceFuzzy BOOLEAN := FALSE; - locationCountySubExact BOOLEAN := FALSE; - locationCountySubFuzzy BOOLEAN := FALSE; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''geocode_address()''; - END IF; - -- The first step is to determine what weve been given, and if its enough. - IF $1 IS NOT NULL THEN - -- The result was not provided. No matter, we can use an unnamed one. - result := $1; - END IF; - IF $2 IS NULL THEN - -- The address is manditory. - -- Without it, wed be wandering into strangers homes all the time. - RAISE EXCEPTION ''geocode_address() - No address provided!''; - ELSE - address := $2; - END IF; - IF $3 IS NOT NULL THEN - -- The direction prefix really isnt important. - -- It will be used for rating if provided. - directionPrefix := $3; - END IF; - IF $4 IS NULL THEN - -- A street name must be given. Think about it. - RAISE EXCEPTION ''geocode_address() - No street name provided!''; - ELSE - streetName := $4; - END IF; - IF $5 IS NOT NULL THEN - -- A street type will be used for rating if provided, but isnt required. - streetTypeAbbrev := $5; - END IF; - IF $6 IS NOT NULL THEN - -- Same as direction prefix, only later. - directionSuffix := $6; - END IF; - IF $7 IS NOT NULL THEN - -- Location is not needed iff a zip is given. The check occurs after - -- the geocode_address_zip call. - location := $7; - END IF; - IF $8 IS NULL THEN - -- State abbreviation is manditory. It is also assumed to be valid. - ELSE - stateAbbrev := $8; - END IF; - IF $9 IS NOT NULL THEN - -- Zip code is optional, but nice. - zipCode := $9; - END IF; - - -- The geocoding tables store the state name rather than the abbreviation. - -- We can validate the abbreviation while retrieving the name. - IF stateAbbrev IS NOT NULL THEN - SELECT INTO state name FROM state_lookup - WHERE state_lookup.abbrev = stateAbbrev; - IF state IS NULL THEN - END IF; - END IF; - - IF zipCode IS NOT NULL THEN - IF verbose THEN - RAISE NOTICE ''geocode_address() - calling geocode_address_zip()''; - END IF; - -- If the zip code is given, it is the most useful way to narrow the - -- search. We will try it first, and if no results match, we will move - -- on to a location search. There is no fuzzy searching on zip codes. - result := geocode_address_zip(result, address, directionPrefix, streetName, - streetTypeAbbrev, directionSuffix, zipCode); - IF result IS NOT NULL THEN - RETURN result; - ELSE - result := $1; - END IF; - END IF; - -- After now, the location becomes manditory. - IF location IS NOT NULL THEN - -- location may be useful, it may not. The first step is to determine if - -- there are any potenial matches in the place and countysub fields. - -- This is done against the lookup tables, and will save us time on much - -- larger queries if they dont match. - IF verbose THEN - RAISE NOTICE ''geocode_address() - calling location_extract_place_*()''; - END IF; - tempString := location_extract_place_exact(location, stateAbbrev); - IF tempString IS NOT NULL THEN - locationPlaceExact := TRUE; - ELSE - locationPlaceExact := FALSE; - END IF; - tempString := location_extract_place_fuzzy(location, stateAbbrev); - IF tempString IS NOT NULL THEN - locationPlaceFuzzy := true; - ELSE - locationPlaceFuzzy := false; - END IF; - IF verbose THEN - RAISE NOTICE ''geocode_address() - calling location_extract_countysub_*()''; - END IF; - tempString := location_extract_countysub_exact(location, stateAbbrev); - IF tempString IS NOT NULL THEN - locationCountySubExact := TRUE; - ELSE - locationCountySubExact := FALSE; - END IF; - tempString := location_extract_countysub_fuzzy(location, stateAbbrev); - IF tempString IS NOT NULL THEN - locationCountySubFuzzy := true; - ELSE - locationCountySubFuzzy := false; - END IF; - END IF; - IF locationPlaceExact THEN - IF verbose THEN - RAISE NOTICE ''geocode_address() - calling geocode_address_place_exact()''; - END IF; - result := geocode_address_place_exact(result, address, directionPrefix, - streetName, streetTypeAbbrev, directionSuffix, location, state); - IF result IS NOT NULL THEN - RETURN result; - ELSE - result := $1; - END IF; - END IF; - IF locationCountySubExact THEN - IF verbose THEN - RAISE NOTICE ''geocode_address() - calling geocode_address_countysub_exact()''; - END IF; - result := geocode_address_countysub_exact(result, address, directionPrefix, - streetName, streetTypeAbbrev, directionSuffix, location, state); - IF result IS NOT NULL THEN - RETURN result; - ELSE - result := $1; - END IF; - END IF; - IF locationPlaceFuzzy THEN - IF verbose THEN - RAISE NOTICE ''geocode_address() - calling geocode_address_place_fuzzy()''; - END IF; - result := geocode_address_place_fuzzy(result, address, directionPrefix, - streetName, streetTypeAbbrev, directionSuffix, location, state); - IF result IS NOT NULL THEN - RETURN result; - ELSE - result := $1; - END IF; - END IF; - IF locationCountySubFuzzy THEN - IF verbose THEN - RAISE NOTICE ''geocode_address() - calling geocode_address_countysub_fuzzy()''; - END IF; - result := geocode_address_countysub_fuzzy(result, address, directionPrefix, - streetName, streetTypeAbbrev, directionSuffix, location, state); - IF result IS NOT NULL THEN - RETURN result; - ELSE - result := $1; - END IF; - END IF; - IF state IS NOT NULL THEN - IF verbose THEN - RAISE NOTICE ''geocode_address() - calling geocode_address_state()''; - END IF; - result := geocode_address_state(result, address, directionPrefix, - streetName, streetTypeAbbrev, directionSuffix, state); - IF result IS NOT NULL THEN - RETURN result; - ELSE - result := $1; - END IF; - END IF; - RETURN NULL; -END; -' LANGUAGE plpgsql; - - - -CREATE OR REPLACE FUNCTION geocode_address_countysub_exact(REFCURSOR, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS REFCURSOR -AS ' -DECLARE - result REFCURSOR; - address INTEGER; - directionPrefix VARCHAR; - streetName VARCHAR; - streetTypeAbbrev VARCHAR; - directionSuffix VARCHAR; - state VARCHAR; - location VARCHAR; - tempString VARCHAR; - tempInt VARCHAR; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''geocode_address_countysub_exact()''; - END IF; - -- The first step is to determine what weve been given, and if its enough. - IF $1 IS NOT NULL THEN - -- The cursor was not provided. No matter, we can use an unnamed one. - result := $1; - END IF; - IF $2 IS NULL THEN - -- The address is manditory. - -- Without it, wed be wandering into strangers homes all the time. - RAISE EXCEPTION ''geocode_address_countysub_exact() - No address provided!''; - ELSE - address := $2; - END IF; - IF $3 IS NOT NULL THEN - -- The direction prefix really isnt important. - -- It will be used for rating if provided. - directionPrefix := $3; - END IF; - IF $4 IS NULL THEN - -- A street name must be given. Think about it. - RAISE EXCEPTION ''geocode_address_countysub_exact() - No street name provided!''; - ELSE - streetName := $4; - END IF; - IF $5 IS NOT NULL THEN - -- A street type will be used for rating if provided, but isnt required. - streetTypeAbbrev := $5; - END IF; - IF $6 IS NOT NULL THEN - -- Same as direction prefix, only later. - directionSuffix := $6; - END IF; - IF $7 IS NULL THEN - -- location is manditory. This is the location geocoder after all. - RAISE EXCEPTION ''geocode_address_countysub_exact() - No location provided!''; - ELSE - location := $7; - END IF; - IF $8 IS NOT NULL THEN - state := $8; - END IF; - - -- Check to see if the road name can be matched. - IF state IS NOT NULL THEN - SELECT INTO tempInt count(*) FROM tiger_geocode_roads - WHERE location = tiger_geocode_roads.cousub - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state; - ELSE - SELECT INTO tempInt count(*) FROM tiger_geocode_roads - WHERE location = tiger_geocode_roads.cousub - AND soundex(streetName) = soundex(tiger_geocode_roads.fename); - END IF; - IF verbose THEN - RAISE NOTICE ''geocode_address_countysub_exact() - % potential matches.'', tempInt; - END IF; - IF tempInt = 0 THEN - RETURN NULL; - ELSE - -- The road name matches, now we check to see if the addresses match - IF state IS NOT NULL THEN - SELECT INTO tempInt count(*) - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs) as rating - FROM tiger_geocode_roads - WHERE location = tiger_geocode_roads.cousub - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid; - ELSE - SELECT INTO tempInt count(*) - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs) as rating - FROM tiger_geocode_roads - WHERE location = tiger_geocode_roads.cousub - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid; - END IF; - IF verbose THEN - RAISE NOTICE ''geocode_address_countysub_exact() - % address matches.'', tempInt; - END IF; - IF tempInt = 0 THEN - return NULL; - ELSE - IF state IS NOT NULL THEN - OPEN result FOR - SELECT *, interpolate_from_address(address, roads_local.fraddl, - roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, - roads_local.geom) as address_geom - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs, location, - tiger_geocode_roads.cousub) as rating - FROM tiger_geocode_roads - WHERE location = tiger_geocode_roads.cousub - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid - ORDER BY subquery.rating; - return result; - ELSE - OPEN result FOR - SELECT *, interpolate_from_address(address, roads_local.fraddl, - roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, - roads_local.geom) as address_geom - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs, location, - tiger_geocode_roads.cousub) as rating - FROM tiger_geocode_roads - WHERE location = tiger_geocode_roads.cousub - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid - ORDER BY subquery.rating; - RETURN result; - END IF; - END IF; - END IF; -END; -' LANGUAGE plpgsql; - - -CREATE OR REPLACE FUNCTION geocode_address_countysub_fuzzy(REFCURSOR, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS REFCURSOR -AS ' -DECLARE - result REFCURSOR; - address INTEGER; - directionPrefix VARCHAR; - streetName VARCHAR; - streetTypeAbbrev VARCHAR; - directionSuffix VARCHAR; - state VARCHAR; - location VARCHAR; - tempString VARCHAR; - tempInt VARCHAR; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''geocode_address_countysub_fuzzy()''; - END IF; - -- The first step is to determine what weve been given, and if its enough. - IF $1 IS NOT NULL THEN - -- The cursor was not provided. No matter, we can use an unnamed one. - result := $1; - END IF; - IF $2 IS NULL THEN - -- The address is manditory. - -- Without it, wed be wandering into strangers homes all the time. - RAISE EXCEPTION ''geocode_address_countysub_fuzzy() - No address provided!''; - ELSE - address := $2; - END IF; - IF $3 IS NOT NULL THEN - -- The direction prefix really isnt important. - -- It will be used for rating if provided. - directionPrefix := $3; - END IF; - IF $4 IS NULL THEN - -- A street name must be given. Think about it. - RAISE EXCEPTION ''geocode_address_countysub_fuzzy() - No street name provided!''; - ELSE - streetName := $4; - END IF; - IF $5 IS NOT NULL THEN - -- A street type will be used for rating if provided, but isnt required. - streetTypeAbbrev := $5; - END IF; - IF $6 IS NOT NULL THEN - -- Same as direction prefix, only later. - directionSuffix := $6; - END IF; - IF $7 IS NULL THEN - -- location is manditory. This is the location geocoder after all. - RAISE EXCEPTION ''geocode_address_countysub_fuzzy() - No location provided!''; - ELSE - location := $7; - END IF; - IF $8 IS NOT NULL THEN - state := $8; - END IF; - - -- Check to see if the road name can be matched. - IF state IS NOT NULL THEN - SELECT INTO tempInt count(*) FROM tiger_geocode_roads - WHERE soundex(location) = soundex(tiger_geocode_roads.cousub) - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state; - ELSE - SELECT INTO tempInt count(*) FROM tiger_geocode_roads - WHERE soundex(location) = soundex(tiger_geocode_roads.cousub) - AND soundex(streetName) = soundex(tiger_geocode_roads.fename); - END IF; - IF verbose THEN - RAISE NOTICE ''geocode_address_countysub_fuzzy() - % potential matches.'', tempInt; - END IF; - IF tempInt = 0 THEN - RETURN NULL; - ELSE - -- The road name matches, now we check to see if the addresses match - IF state IS NOT NULL THEN - SELECT INTO tempInt count(*) - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs) as rating - FROM tiger_geocode_roads - WHERE soundex(location) = soundex(tiger_geocode_roads.cousub) - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid; - ELSE - SELECT INTO tempInt count(*) - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs) as rating - FROM tiger_geocode_roads - WHERE soundex(location) = soundex(tiger_geocode_roads.cousub) - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid; - END IF; - IF verbose THEN - RAISE NOTICE ''geocode_address_countysub_fuzzy() - % address matches.'', tempInt; - END IF; - IF tempInt = 0 THEN - return NULL; - ELSE - IF state IS NOT NULL THEN - OPEN result FOR - SELECT *, interpolate_from_address(address, roads_local.fraddl, - roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, - roads_local.geom) as address_geom - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs, location, - tiger_geocode_roads.cousub) as rating - FROM tiger_geocode_roads - WHERE soundex(location) = soundex(tiger_geocode_roads.cousub) - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid - ORDER BY subquery.rating; - return result; - ELSE - OPEN result FOR - SELECT *, interpolate_from_address(address, roads_local.fraddl, - roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, - roads_local.geom) as address_geom - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs, location, - tiger_geocode_roads.cousub) as rating - FROM tiger_geocode_roads - WHERE soundex(location) = soundex(tiger_geocode_roads.cousub) - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid - ORDER BY subquery.rating; - RETURN result; - END IF; - END IF; - END IF; -END; -' LANGUAGE plpgsql; - - -CREATE OR REPLACE FUNCTION geocode_address_place_exact(REFCURSOR, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS REFCURSOR -AS ' -DECLARE - result REFCURSOR; - address INTEGER; - directionPrefix VARCHAR; - streetName VARCHAR; - streetTypeAbbrev VARCHAR; - directionSuffix VARCHAR; - state VARCHAR; - location VARCHAR; - tempString VARCHAR; - tempInt VARCHAR; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''geocode_address_place_exact()''; - END IF; - -- The first step is to determine what weve been given, and if its enough. - IF $1 IS NOT NULL THEN - -- The cursor was not provided. No matter, we can use an unnamed one. - result := $1; - END IF; - IF $2 IS NULL THEN - -- The address is manditory. - -- Without it, wed be wandering into strangers homes all the time. - RAISE EXCEPTION ''geocode_address_place_exact() - No address provided!''; - ELSE - address := $2; - END IF; - IF $3 IS NOT NULL THEN - -- The direction prefix really isnt important. - -- It will be used for rating if provided. - directionPrefix := $3; - END IF; - IF $4 IS NULL THEN - -- A street name must be given. Think about it. - RAISE EXCEPTION ''geocode_address_place_exact() - No street name provided!''; - ELSE - streetName := $4; - END IF; - IF $5 IS NOT NULL THEN - -- A street type will be used for rating if provided, but isnt required. - streetTypeAbbrev := $5; - END IF; - IF $6 IS NOT NULL THEN - -- Same as direction prefix, only later. - directionSuffix := $6; - END IF; - IF $7 IS NULL THEN - -- location is manditory. This is the location geocoder after all. - RAISE EXCEPTION ''geocode_address_place_exact() - No location provided!''; - ELSE - location := $7; - END IF; - IF $8 IS NOT NULL THEN - state := $8; - END IF; - - -- Check to see if the road name can be matched. - IF state IS NOT NULL THEN - SELECT INTO tempInt count(*) FROM tiger_geocode_roads - WHERE location = tiger_geocode_roads.place - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state; - ELSE - SELECT INTO tempInt count(*) FROM tiger_geocode_roads - WHERE location = tiger_geocode_roads.place - AND soundex(streetName) = soundex(tiger_geocode_roads.fename); - END IF; - IF verbose THEN - RAISE NOTICE ''geocode_address_place_exact() - % potential matches.'', tempInt; - END IF; - IF tempInt = 0 THEN - RETURN NULL; - ELSE - -- The road name matches, now we check to see if the addresses match - IF state IS NOT NULL THEN - SELECT INTO tempInt count(*) - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs) as rating - FROM tiger_geocode_roads - WHERE location = tiger_geocode_roads.place - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid; - ELSE - SELECT INTO tempInt count(*) - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs) as rating - FROM tiger_geocode_roads - WHERE location = tiger_geocode_roads.place - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid; - END IF; - IF verbose THEN - RAISE NOTICE ''geocode_address_place_exact() - % address matches.'', tempInt; - END IF; - IF tempInt = 0 THEN - return NULL; - ELSE - IF state IS NOT NULL THEN - OPEN result FOR - SELECT *, interpolate_from_address(address, roads_local.fraddl, - roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, - roads_local.geom) as address_geom - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs, location, - tiger_geocode_roads.place) as rating - FROM tiger_geocode_roads - WHERE location = tiger_geocode_roads.place - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid - ORDER BY subquery.rating; - return result; - ELSE - OPEN result FOR - SELECT *, interpolate_from_address(address, roads_local.fraddl, - roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, - roads_local.geom) as address_geom - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs, location, - tiger_geocode_roads.place) as rating - FROM tiger_geocode_roads - WHERE location = tiger_geocode_roads.place - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid - ORDER BY subquery.rating; - RETURN result; - END IF; - END IF; - END IF; -END; -' LANGUAGE plpgsql; - - - -CREATE OR REPLACE FUNCTION geocode_address_place_fuzzy(REFCURSOR, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS REFCURSOR -AS ' -DECLARE - result REFCURSOR; - address INTEGER; - directionPrefix VARCHAR; - streetName VARCHAR; - streetTypeAbbrev VARCHAR; - directionSuffix VARCHAR; - state VARCHAR; - location VARCHAR; - tempString VARCHAR; - tempInt VARCHAR; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''geocode_address_place_fuzzy()''; - END IF; - -- The first step is to determine what weve been given, and if its enough. - IF $1 IS NOT NULL THEN - -- The cursor was not provided. No matter, we can use an unnamed one. - result := $1; - END IF; - IF $2 IS NULL THEN - -- The address is manditory. - -- Without it, wed be wandering into strangers homes all the time. - RAISE EXCEPTION ''geocode_address_place_fuzzy() - No address provided!''; - ELSE - address := $2; - END IF; - IF $3 IS NOT NULL THEN - -- The direction prefix really isnt important. - -- It will be used for rating if provided. - directionPrefix := $3; - END IF; - IF $4 IS NULL THEN - -- A street name must be given. Think about it. - RAISE EXCEPTION ''geocode_address_place_fuzzy() - No street name provided!''; - ELSE - streetName := $4; - END IF; - IF $5 IS NOT NULL THEN - -- A street type will be used for rating if provided, but isnt required. - streetTypeAbbrev := $5; - END IF; - IF $6 IS NOT NULL THEN - -- Same as direction prefix, only later. - directionSuffix := $6; - END IF; - IF $7 IS NULL THEN - -- location is manditory. This is the location geocoder after all. - RAISE EXCEPTION ''geocode_address_place_fuzzy() - No location provided!''; - ELSE - location := $7; - END IF; - IF $8 IS NOT NULL THEN - state := $8; - END IF; - - -- Check to see if the road name can be matched. - IF state IS NOT NULL THEN - SELECT INTO tempInt count(*) FROM tiger_geocode_roads - WHERE soundex(location) = soundex(tiger_geocode_roads.place) - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state; - ELSE - SELECT INTO tempInt count(*) FROM tiger_geocode_roads - WHERE soundex(location) = soundex(tiger_geocode_roads.place) - AND soundex(streetName) = soundex(tiger_geocode_roads.fename); - END IF; - IF verbose THEN - RAISE NOTICE ''geocode_address_place_fuzzy() - % potential matches.'', tempInt; - END IF; - IF tempInt = 0 THEN - RETURN NULL; - ELSE - -- The road name matches, now we check to see if the addresses match - IF state IS NOT NULL THEN - SELECT INTO tempInt count(*) - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs) as rating - FROM tiger_geocode_roads - WHERE soundex(location) = soundex(tiger_geocode_roads.place) - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid; - ELSE - SELECT INTO tempInt count(*) - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs) as rating - FROM tiger_geocode_roads - WHERE soundex(location) = soundex(tiger_geocode_roads.place) - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid; - END IF; - IF verbose THEN - RAISE NOTICE ''geocode_address_place_fuzzy() - % address matches.'', tempInt; - END IF; - IF tempInt = 0 THEN - return NULL; - ELSE - IF state IS NOT NULL THEN - OPEN result FOR - SELECT *, interpolate_from_address(address, roads_local.fraddl, - roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, - roads_local.geom) as address_geom - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs, location, - tiger_geocode_roads.place) as rating - FROM tiger_geocode_roads - WHERE soundex(location) = soundex(tiger_geocode_roads.place) - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid - ORDER BY subquery.rating; - return result; - ELSE - OPEN result FOR - SELECT *, interpolate_from_address(address, roads_local.fraddl, - roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, - roads_local.geom) as address_geom - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs, location, - tiger_geocode_roads.place) as rating - FROM tiger_geocode_roads - WHERE soundex(location) = soundex(tiger_geocode_roads.place) - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid - ORDER BY subquery.rating; - RETURN result; - END IF; - END IF; - END IF; -END; -' LANGUAGE plpgsql; - - - -CREATE OR REPLACE FUNCTION geocode_address_state(REFCURSOR, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS REFCURSOR -AS ' -DECLARE - result REFCURSOR; - address INTEGER; - directionPrefix VARCHAR; - streetName VARCHAR; - streetTypeAbbrev VARCHAR; - directionSuffix VARCHAR; - state VARCHAR; - tempString VARCHAR; - tempInt VARCHAR; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''geocode_address_state()''; - END IF; - -- The first step is to determine what weve been given, and if its enough. - IF $1 IS NOT NULL THEN - -- The cursor was not provided. No matter, we can use an unnamed one. - result := $1; - END IF; - IF $2 IS NULL THEN - -- The address is manditory. - -- Without it, wed be wandering into strangers homes all the time. - RAISE EXCEPTION ''geocode_address_state() - No address provided!''; - ELSE - address := $2; - END IF; - IF $3 IS NOT NULL THEN - -- The direction prefix really isnt important. - -- It will be used for rating if provided. - directionPrefix := $3; - END IF; - IF $4 IS NULL THEN - -- A street name must be given. Think about it. - RAISE EXCEPTION ''geocode_address_state() - No street name provided!''; - ELSE - streetName := $4; - END IF; - IF $5 IS NOT NULL THEN - -- A street type will be used for rating if provided, but isnt required. - streetTypeAbbrev := $5; - END IF; - IF $6 IS NOT NULL THEN - -- Same as direction prefix, only later. - directionSuffix := $6; - END IF; - IF $7 IS NOT NULL THEN - state := $7; - ELSE - -- It is unreasonable to do a country wide search. State is already - -- pretty sketchy. No state, no search. - RAISE EXCEPTION ''geocode_address_state() - No state name provided!''; - END IF; - - -- Check to see if the road name can be matched. - SELECT INTO tempInt count(*) FROM tiger_geocode_roads - WHERE soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state; - IF verbose THEN - RAISE NOTICE ''geocode_address_state() - % potential matches.'', tempInt; - END IF; - IF tempInt = 0 THEN - RETURN NULL; - ELSE - -- The road name matches, now we check to see if the addresses match - SELECT INTO tempInt count(*) - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs) as rating - FROM tiger_geocode_roads - WHERE soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid; - IF verbose THEN - RAISE NOTICE ''geocode_address_state() - % address matches.'', tempInt; - END IF; - IF tempInt = 0 THEN - return NULL; - ELSE - OPEN result FOR - SELECT *, interpolate_from_address(address, roads_local.fraddl, - roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, - roads_local.geom) as address_geom - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs) as rating - FROM tiger_geocode_roads - WHERE soundex(streetName) = soundex(tiger_geocode_roads.fename) - AND state = tiger_geocode_roads.state - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid - ORDER BY subquery.rating; - return result; - END IF; - END IF; -END; -' LANGUAGE plpgsql; - - - -CREATE OR REPLACE FUNCTION geocode_address_zip(REFCURSOR, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, INTEGER) RETURNS REFCURSOR -AS ' -DECLARE - result REFCURSOR; - address INTEGER; - directionPrefix VARCHAR; - streetName VARCHAR; - streetTypeAbbrev VARCHAR; - directionSuffix VARCHAR; - zipCode INTEGER; - tempString VARCHAR; - tempInt VARCHAR; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''geocode_address_zip()''; - END IF; - -- The first step is to determine what weve been given, and if its enough. - IF $1 IS NOT NULL THEN - -- The cursor was not provided. No matter, we can use an unnamed one. - result := $1; - END IF; - IF $2 IS NULL THEN - -- The address is manditory. - -- Without it, wed be wandering into strangers homes all the time. - RAISE EXCEPTION ''geocode_address_zip() - No address provided!''; - ELSE - address := $2; - END IF; - IF $3 IS NOT NULL THEN - -- The direction prefix really isnt important. - -- It will be used for rating if provided. - directionPrefix := $3; - END IF; - IF $4 IS NULL THEN - -- A street name must be given. Think about it. - RAISE EXCEPTION ''geocode_address_zip() - No street name provided!''; - ELSE - streetName := $4; - END IF; - IF $5 IS NOT NULL THEN - -- A street type will be used for rating if provided, but isnt required. - streetTypeAbbrev := $5; - END IF; - IF $6 IS NOT NULL THEN - -- Same as direction prefix, only later. - directionSuffix := $6; - END IF; - IF $7 IS NULL THEN - -- Zip code is not optional. - RAISE EXCEPTION ''geocode_address_zip() - No zip provided!''; - ELSE - zipCode := $7; - END IF; - - -- Check to see if the road name can be matched. - SELECT INTO tempInt count(*) FROM tiger_geocode_roads - WHERE zipCode = tiger_geocode_roads.zip - AND soundex(streetName) = soundex(tiger_geocode_roads.fename); - IF tempInt = 0 THEN - return NULL; - ELSE - -- The road name matches, now we check to see if the addresses match - SELECT INTO tempInt count(*) - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs) as rating - FROM tiger_geocode_roads - WHERE zipCode = tiger_geocode_roads.zip - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid; - IF tempInt = 0 THEN - return NULL; - ELSE - OPEN result FOR - SELECT *, interpolate_from_address(address, roads_local.fraddl, - roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, - roads_local.geom) as address_geom - FROM ( - SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, - streetName, tiger_geocode_roads.fename, streetTypeAbbrev, - tiger_geocode_roads.fetype, directionSuffix, - tiger_geocode_roads.fedirs) as rating - FROM tiger_geocode_roads - WHERE zipCode = tiger_geocode_roads.zip - AND soundex(streetName) = soundex(tiger_geocode_roads.fename) - ) AS subquery, tiger_geocode_join, roads_local - WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, - roads_local.fraddr, roads_local.toaddr) - AND subquery.id = tiger_geocode_join.id - AND tiger_geocode_join.tlid = roads_local.tlid - ORDER BY subquery.rating; - return result; - END IF; - END IF; -END; -' LANGUAGE plpgsql; - - - --- Returns a string consisting of the last N words. Words are allowed --- to be seperated only by spaces, but multiple spaces between --- words are allowed. Words must be alphanumberic. --- If more words are requested than exist, the full input string is --- returned. -CREATE OR REPLACE FUNCTION get_last_words(VARCHAR, INTEGER) RETURNS VARCHAR -AS ' -DECLARE - inputString VARCHAR; - tempString VARCHAR; - count VARCHAR; - result VARCHAR := ''''; -BEGIN - IF $1 IS NULL THEN - return NULL; - ELSE - inputString := $1; - END IF; - IF $2 IS NULL THEN - RAISE EXCEPTION ''get_last_words() - word count is null!''; - ELSE - count := $2; - END IF; - FOR i IN 1..count LOOP - tempString := substring(inputString from ''((?: )+[a-zA-Z0-9_]*)'' || result || ''$''); - IF tempString IS NULL THEN - return inputString; - END IF; - result := tempString || result; - END LOOP; - result := trim(both from result); - return result; -END; -' LANGUAGE plpgsql; - - - --- This function converts the string addresses to integers and passes them --- to the other includes_address function. -CREATE OR REPLACE FUNCTION includes_address(INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS BOOLEAN -AS ' -DECLARE - given_address INTEGER; - addr1 INTEGER; - addr2 INTEGER; - addr3 INTEGER; - addr4 INTEGER; - result BOOLEAN; -BEGIN - given_address = $1; - addr1 = to_number($2, ''999999''); - addr2 = to_number($3, ''999999''); - addr3 = to_number($4, ''999999''); - addr4 = to_number($5, ''999999''); - result = includes_address(given_address, addr1, addr2, addr3, addr4); - RETURN result; -END -' LANGUAGE plpgsql; - - - --- This function requires the addresses to be grouped, such that the second and --- third arguments are from one side of the street, and the fourth and fifth --- from the other. -CREATE OR REPLACE FUNCTION includes_address(INTEGER, INTEGER, INTEGER, INTEGER, INTEGER) RETURNS BOOLEAN -AS ' -DECLARE - given_address INTEGER; - addr1 INTEGER; - addr2 INTEGER; - addr3 INTEGER; - addr4 INTEGER; - lmaxaddr INTEGER := -1; - rmaxaddr INTEGER := -1; - lminaddr INTEGER := -1; - rminaddr INTEGER := -1; - maxaddr INTEGER := -1; - minaddr INTEGER := -1; -BEGIN - IF $1 IS NULL THEN - RAISE EXCEPTION ''includes_address() - local address is NULL!''; - ELSE - given_address := $1; - END IF; - - IF $2 IS NOT NULL THEN - addr1 := $2; - maxaddr := addr1; - minaddr := addr1; - lmaxaddr := addr1; - lminaddr := addr1; - END IF; - - IF $3 IS NOT NULL THEN - addr2 := $3; - IF addr2 < minaddr OR minaddr = -1 THEN - minaddr := addr2; - END IF; - IF addr2 > maxaddr OR maxaddr = -1 THEN - maxaddr := addr2; - END IF; - IF addr2 > lmaxaddr OR lmaxaddr = -1 THEN - lmaxaddr := addr2; - END IF; - IF addr2 < lminaddr OR lminaddr = -1 THEN - lminaddr := addr2; - END IF; - END IF; - - IF $4 IS NOT NULL THEN - addr3 := $4; - IF addr3 < minaddr OR minaddr = -1 THEN - minaddr := addr3; - END IF; - IF addr3 > maxaddr OR maxaddr = -1 THEN - maxaddr := addr3; - END IF; - rmaxaddr := addr3; - rminaddr := addr3; - END IF; - - IF $5 IS NOT NULL THEN - addr4 := $5; - IF addr4 < minaddr OR minaddr = -1 THEN - minaddr := addr4; - END IF; - IF addr4 > maxaddr OR maxaddr = -1 THEN - maxaddr := addr4; - END IF; - IF addr4 > rmaxaddr OR rmaxaddr = -1 THEN - rmaxaddr := addr4; - END IF; - IF addr4 < rminaddr OR rminaddr = -1 THEN - rminaddr := addr4; - END IF; - END IF; - - IF minaddr = -1 OR maxaddr = -1 THEN - -- No addresses were non-null, return FALSE (arbitrary) - RETURN FALSE; - ELSIF given_address >= minaddr AND given_address <= maxaddr THEN - -- The address is within the given range - IF given_address >= lminaddr AND given_address <= lmaxaddr THEN - -- This checks to see if the address is on this side of the - -- road, ie if the address is even, the street range must be even - IF (given_address % 2) = (lminaddr % 2) - OR (given_address % 2) = (lmaxaddr % 2) THEN - RETURN TRUE; - END IF; - END IF; - IF given_address >= rminaddr AND given_address <= rmaxaddr THEN - -- See above - IF (given_address % 2) = (rminaddr % 2) - OR (given_address % 2) = (rmaxaddr % 2) THEN - RETURN TRUE; - END IF; - END IF; - END IF; - -- The address is not within the range - RETURN FALSE; -END; - -' LANGUAGE plpgsql; - - - --- This function converts string addresses to integers and passes them to --- the other interpolate_from_address function. -CREATE OR REPLACE FUNCTION interpolate_from_address(INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, GEOMETRY) RETURNS GEOMETRY -AS ' -DECLARE - given_address INTEGER; - addr1 INTEGER; - addr2 INTEGER; - addr3 INTEGER; - addr4 INTEGER; - road GEOMETRY; - result GEOMETRY; -BEGIN - given_address := $1; - addr1 := to_number($2, ''999999''); - addr2 := to_number($3, ''999999''); - addr3 := to_number($4, ''999999''); - addr4 := to_number($5, ''999999''); - road := $6; - result = interpolate_from_address(given_address, addr1, addr2, addr3, addr4, road); - RETURN result; -END -' LANGUAGE plpgsql; - --- interpolate_from_address(local_address, from_address_l, to_address_l, from_address_r, to_address_r, local_road) --- This function returns a point along the given geometry (must be linestring) --- corresponding to the given address. If the given address is not within --- the address range of the road, null is returned. --- This function requires that the address be grouped, such that the second and --- third arguments are from one side of the street, while the fourth and --- fifth are from the other. -CREATE OR REPLACE FUNCTION interpolate_from_address(INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, GEOMETRY) RETURNS GEOMETRY -AS ' -DECLARE - given_address INTEGER; - lmaxaddr INTEGER := -1; - rmaxaddr INTEGER := -1; - lminaddr INTEGER := -1; - rminaddr INTEGER := -1; - lfrgreater BOOLEAN; - rfrgreater BOOLEAN; - frgreater BOOLEAN; - addrwidth INTEGER; - part DOUBLE PRECISION; - road GEOMETRY; - result GEOMETRY; -BEGIN - IF $1 IS NULL THEN - RAISE EXCEPTION ''interpolate_from_address() - local address is NULL!''; - ELSE - given_address := $1; - END IF; - - IF $6 IS NULL THEN - RAISE EXCEPTION ''interpolate_from_address() - local road is NULL!''; - ELSE - IF geometrytype($6) = ''LINESTRING'' THEN - road := $6; - ELSIF geometrytype($6) = ''MULTILINESTRING'' THEN - road := geometryn($6,1); - ELSE - RAISE EXCEPTION ''interpolate_from_address() - local road is not a line!''; - END IF; - END IF; - - IF $2 IS NOT NULL THEN - lfrgreater := TRUE; - lmaxaddr := $2; - lminaddr := $2; - END IF; - - IF $3 IS NOT NULL THEN - IF $3 > lmaxaddr OR lmaxaddr = -1 THEN - lmaxaddr := $3; - lfrgreater := FALSE; - END IF; - IF $3 < lminaddr OR lminaddr = -1 THEN - lminaddr := $3; - END IF; - END IF; - - IF $4 IS NOT NULL THEN - rmaxaddr := $4; - rminaddr := $4; - rfrgreater := TRUE; - END IF; - - IF $5 IS NOT NULL THEN - IF $5 > rmaxaddr OR rmaxaddr = -1 THEN - rmaxaddr := $5; - rfrgreater := FALSE; - END IF; - IF $5 < rminaddr OR rminaddr = -1 THEN - rminaddr := $5; - END IF; - END IF; - - IF given_address >= lminaddr AND given_address <= lmaxaddr THEN - IF (given_address % 2) = (lminaddr % 2) - OR (given_address % 2) = (lmaxaddr % 2) THEN - addrwidth := lmaxaddr - lminaddr; - part := (given_address - lminaddr) / trunc(addrwidth, 1); - frgreater := lfrgreater; - END IF; - END IF; - IF given_address >= rminaddr AND given_address <= rmaxaddr THEN - IF (given_address % 2) = (rminaddr % 2) - OR (given_address % 2) = (rmaxaddr % 2) THEN - addrwidth := rmaxaddr - rminaddr; - part := (given_address - rminaddr) / trunc(addrwidth, 1); - frgreater := rfrgreater; - END IF; - ELSE - RETURN null; - END IF; - - IF frgreater THEN - part := 1 - part; - END IF; - - result = line_interpolate_point(road, part); - RETURN result; -END; -' LANGUAGE plpgsql; - - --- This function determines the levenshtein distance irespective of case. -CREATE OR REPLACE FUNCTION levenshtein_ignore_case(VARCHAR, VARCHAR) RETURNS INTEGER -AS ' -DECLARE - result INTEGER; -BEGIN - result := levenshtein(upper($1), upper($2)); - RETURN result; -END -' LANGUAGE plpgsql; - --- This function take two arguements. The first is the "given string" and --- must not be null. The second arguement is the "compare string" and may --- or may not be null. If the second string is null, the value returned is --- 3, otherwise it is the levenshtein difference between the two. -CREATE OR REPLACE FUNCTION nullable_levenshtein(VARCHAR, VARCHAR) RETURNS INTEGER -AS ' -DECLARE - given_string VARCHAR; - result INTEGER := 3; -BEGIN - IF $1 IS NULL THEN - RAISE EXCEPTION ''nullable_levenshtein - given string is NULL!''; - ELSE - given_string := $1; - END IF; - - IF $2 IS NOT NULL AND $2 != '''' THEN - result := levenshtein_ignore_case(given_string, $2); - END IF; - - RETURN result; -END -' LANGUAGE plpgsql; - - - --- location_extract(streetAddressString, stateAbbreviation) --- This function extracts a location name from the end of the given string. --- The first attempt is to find an exact match against the place_lookup --- table. If this fails, a word-by-word soundex match is tryed against the --- same table. If multiple candidates are found, the one with the smallest --- levenshtein distance from the given string is assumed the correct one. --- If no match is found against the place_lookup table, the same tests are --- run against the countysub_lookup table. --- --- The section of the given string corresponding to the location found is --- returned, rather than the string found from the tables. All the searching --- is done largely to determine the length (words) of the location, to allow --- the intended street name to be correctly identified. -CREATE OR REPLACE FUNCTION location_extract(VARCHAR, VARCHAR) RETURNS VARCHAR -AS ' -DECLARE - fullStreet VARCHAR; - stateAbbrev VARCHAR; - location VARCHAR; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''location_extract()''; - END IF; - IF $1 IS NULL THEN - RAISE EXCEPTION ''location_extract() - No input given!''; - ELSE - fullStreet := $1; - END IF; - IF $2 IS NULL THEN - ELSE - stateAbbrev := $2; - END IF; - location := location_extract_place_exact(fullStreet, stateAbbrev); - IF location IS NULL THEN - location := location_extract_countysub_exact(fullStreet, stateAbbrev); - IF location IS NULL THEN - location := location_extract_place_fuzzy(fullStreet, stateAbbrev); - IF location IS NULL THEN - location := location_extract_countysub_fuzzy(fullStreet, stateAbbrev); - END IF; - END IF; - END IF; - return location; -END; -' LANGUAGE plpgsql; - - - --- location_extract_countysub_exact(string, stateAbbrev) --- This function checks the place_lookup table to find a potential match to --- the location described at the end of the given string. If an exact match --- fails, a fuzzy match is performed. The location as found in the given --- string is returned. -CREATE OR REPLACE FUNCTION location_extract_countysub_exact(VARCHAR, VARCHAR) RETURNS VARCHAR -AS ' -DECLARE - fullStreet VARCHAR; - ws VARCHAR; - tempString VARCHAR; - location VARCHAR; - tempInt INTEGER; - word_count INTEGER; - stateAbbrev VARCHAR; - rec RECORD; - test BOOLEAN; - result VARCHAR; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''location_extract_countysub_exact()''; - END IF; - IF $1 IS NULL THEN - RAISE EXCEPTION ''location_extract_countysub_exact() - No input given!''; - ELSE - fullStreet := $1; - END IF; - IF $2 IS NOT NULL THEN - stateAbbrev := $2; - END IF; - ws := ''[ ,\.\n\f\t]''; - -- No hope of determining the location from place. Try countysub. - IF stateAbbrev IS NOT NULL THEN - SELECT INTO tempInt count(*) FROM countysub_lookup - WHERE countysub_lookup.state = stateAbbrev - AND texticregexeq(fullStreet, ''(?i)'' || name || ''$''); - ELSE - SELECT INTO tempInt count(*) FROM countysub_lookup - WHERE texticregexeq(fullStreet, ''(?i)'' || name || ''$''); - END IF; - IF tempInt > 0 THEN - IF stateAbbrev IS NOT NULL THEN - FOR rec IN SELECT substring(fullStreet, ''(?i)('' - || name || '')$'') AS value, name FROM countysub_lookup - WHERE countysub_lookup.state = stateAbbrev - AND texticregexeq(fullStreet, ''(?i)'' || ws || name || - ''$'') ORDER BY length(name) DESC LOOP - -- Only the first result is needed. - location := rec.value; - EXIT; - END LOOP; - ELSE - FOR rec IN SELECT substring(fullStreet, ''(?i)('' - || name || '')$'') AS value, name FROM countysub_lookup - WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name || - ''$'') ORDER BY length(name) DESC LOOP - -- again, only the first is needed. - location := rec.value; - EXIT; - END LOOP; - END IF; - END IF; - RETURN location; -END; -' LANGUAGE plpgsql; - - --- location_extract_countysub_fuzzy(string, stateAbbrev) --- This function checks the place_lookup table to find a potential match to --- the location described at the end of the given string. If an exact match --- fails, a fuzzy match is performed. The location as found in the given --- string is returned. -CREATE OR REPLACE FUNCTION location_extract_countysub_fuzzy(VARCHAR, VARCHAR) RETURNS VARCHAR -AS ' -DECLARE - fullStreet VARCHAR; - ws VARCHAR; - tempString VARCHAR; - location VARCHAR; - tempInt INTEGER; - word_count INTEGER; - stateAbbrev VARCHAR; - rec RECORD; - test BOOLEAN; - result VARCHAR; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''location_extract_countysub_fuzzy()''; - END IF; - IF $1 IS NULL THEN - RAISE EXCEPTION ''location_extract_countysub_fuzzy() - No input given!''; - ELSE - fullStreet := $1; - END IF; - IF $2 IS NOT NULL THEN - stateAbbrev := $2; - END IF; - ws := ''[ ,\.\n\f\t]''; - - -- Fuzzy matching. - tempString := substring(fullStreet, ''(?i)'' || ws || - ''([a-zA-Z0-9]+)$''); - IF tempString IS NULL THEN - tempString := fullStreet; - END IF; - IF stateAbbrev IS NOT NULL THEN - SELECT INTO tempInt count(*) FROM countysub_lookup - WHERE countysub_lookup.state = stateAbbrev - AND soundex(tempString) = end_soundex(name); - ELSE - SELECT INTO tempInt count(*) FROM countysub_lookup - WHERE soundex(tempString) = end_soundex(name); - END IF; - IF tempInt > 0 THEN - tempInt := 50; - -- Some potentials were found. Begin a word-by-word soundex on each. - IF stateAbbrev IS NOT NULL THEN - FOR rec IN SELECT name FROM countysub_lookup - WHERE countysub_lookup.state = stateAbbrev - AND soundex(tempString) = end_soundex(name) LOOP - word_count := count_words(rec.name); - test := TRUE; - tempString := get_last_words(fullStreet, word_count); - FOR i IN 1..word_count LOOP - IF soundex(split_part(tempString, '' '', i)) != - soundex(split_part(rec.name, '' '', i)) THEN - test := FALSE; - END IF; - END LOOP; - IF test THEN - -- The soundex matched, determine if the distance is better. - IF levenshtein_ignore_case(rec.name, tempString) < tempInt THEN - location := tempString; - tempInt := levenshtein_ignore_case(rec.name, tempString); - END IF; - END IF; - END LOOP; - ELSE - FOR rec IN SELECT name FROM countysub_lookup - WHERE soundex(tempString) = end_soundex(name) LOOP - word_count := count_words(rec.name); - test := TRUE; - tempString := get_last_words(fullStreet, word_count); - FOR i IN 1..word_count LOOP - IF soundex(split_part(tempString, '' '', i)) != - soundex(split_part(rec.name, '' '', i)) THEN - test := FALSE; - END IF; - END LOOP; - IF test THEN - -- The soundex matched, determine if the distance is better. - IF levenshtein_ignore_case(rec.name, tempString) < tempInt THEN - location := tempString; - tempInt := levenshtein_ignore_case(rec.name, tempString); - END IF; - END IF; - END LOOP; - END IF; - END IF; -- If no fuzzys were found, leave location null. - RETURN location; -END; -' LANGUAGE plpgsql; - - - --- location_extract_place_exact(string, stateAbbrev) --- This function checks the place_lookup table to find a potential match to --- the location described at the end of the given string. If an exact match --- fails, a fuzzy match is performed. The location as found in the given --- string is returned. -CREATE OR REPLACE FUNCTION location_extract_place_exact(VARCHAR, VARCHAR) RETURNS VARCHAR -AS ' -DECLARE - fullStreet VARCHAR; - ws VARCHAR; - tempString VARCHAR; - location VARCHAR; - tempInt INTEGER; - word_count INTEGER; - stateAbbrev VARCHAR; - rec RECORD; - test BOOLEAN; - result VARCHAR; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''location_extract_place_exact()''; - END IF; - IF $1 IS NULL THEN - RAISE EXCEPTION ''location_extract_place_exact() - No input given!''; - ELSE - fullStreet := $1; - END IF; - IF verbose THEN - RAISE NOTICE ''location_extract_place_exact() - input: "%"'', fullStreet; - END IF; - IF $2 IS NOT NULL THEN - stateAbbrev := $2; - END IF; - ws := ''[ ,\.\n\f\t]''; - -- Try for an exact match against places - IF stateAbbrev IS NOT NULL THEN - SELECT INTO tempInt count(*) FROM place_lookup - WHERE place_lookup.state = stateAbbrev - AND texticregexeq(fullStreet, ''(?i)'' || name || ''$''); - ELSE - SELECT INTO tempInt count(*) FROM place_lookup - WHERE texticregexeq(fullStreet, ''(?i)'' || name || ''$''); - END IF; - IF verbose THEN - RAISE NOTICE ''location_extract_place_exact() - Exact Matches %'', tempInt; - END IF; - IF tempInt > 0 THEN - -- Some matches were found. Look for the last one in the string. - IF stateAbbrev IS NOT NULL THEN - FOR rec IN SELECT substring(fullStreet, ''(?i)('' - || name || '')$'') AS value, name FROM place_lookup - WHERE place_lookup.state = stateAbbrev - AND texticregexeq(fullStreet, ''(?i)'' - || name || ''$'') ORDER BY length(name) DESC LOOP - -- Since the regex is end of string, only the longest (first) result - -- is useful. - location := rec.value; - EXIT; - END LOOP; - ELSE - FOR rec IN SELECT substring(fullStreet, ''(?i)('' - || name || '')$'') AS value, name FROM place_lookup - WHERE texticregexeq(fullStreet, ''(?i)'' - || name || ''$'') ORDER BY length(name) DESC LOOP - -- Since the regex is end of string, only the longest (first) result - -- is useful. - location := rec.value; - EXIT; - END LOOP; - END IF; - END IF; - RETURN location; -END; -' LANGUAGE plpgsql; - - - --- location_extract_place_fuzzy(string, stateAbbrev) --- This function checks the place_lookup table to find a potential match to --- the location described at the end of the given string. If an exact match --- fails, a fuzzy match is performed. The location as found in the given --- string is returned. -CREATE OR REPLACE FUNCTION location_extract_place_fuzzy(VARCHAR, VARCHAR) RETURNS VARCHAR -AS ' -DECLARE - fullStreet VARCHAR; - ws VARCHAR; - tempString VARCHAR; - location VARCHAR; - tempInt INTEGER; - word_count INTEGER; - stateAbbrev VARCHAR; - rec RECORD; - test BOOLEAN; - result VARCHAR; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''location_extract_place_fuzzy()''; - END IF; - IF $1 IS NULL THEN - RAISE EXCEPTION ''location_extract_place_fuzzy() - No input given!''; - ELSE - fullStreet := $1; - END IF; - IF verbose THEN - RAISE NOTICE ''location_extract_place_fuzzy() - input: "%"'', fullStreet; - END IF; - IF $2 IS NOT NULL THEN - stateAbbrev := $2; - END IF; - ws := ''[ ,\.\n\f\t]''; - - tempString := substring(fullStreet, ''(?i)'' || ws - || ''([a-zA-Z0-9]+)$''); - IF tempString IS NULL THEN - tempString := fullStreet; - END IF; - IF stateAbbrev IS NOT NULL THEN - SELECT into tempInt count(*) FROM place_lookup - WHERE place_lookup.state = stateAbbrev - AND soundex(tempString) = end_soundex(name); - ELSE - SELECT into tempInt count(*) FROM place_lookup - WHERE soundex(tempString) = end_soundex(name); - END IF; - IF verbose THEN - RAISE NOTICE ''location_extract_place_fuzzy() - Fuzzy matches %'', tempInt; - END IF; - IF tempInt > 0 THEN - -- Some potentials were found. Begin a word-by-word soundex on each. - tempInt := 50; - IF stateAbbrev IS NOT NULL THEN - FOR rec IN SELECT name FROM place_lookup - WHERE place_lookup.state = stateAbbrev - AND soundex(tempString) = end_soundex(name) LOOP - IF verbose THEN - RAISE NOTICE ''location_extract_place_fuzzy() - Fuzzy: "%"'', rec.name; - END IF; - word_count := count_words(rec.name); - test := TRUE; - tempString := get_last_words(fullStreet, word_count); - FOR i IN 1..word_count LOOP - IF soundex(split_part(tempString, '' '', i)) != - soundex(split_part(rec.name, '' '', i)) THEN - IF verbose THEN - RAISE NOTICE ''location_extract_place_fuzzy() - No Match.''; - END IF; - test := FALSE; - END IF; - END LOOP; - IF test THEN - -- The soundex matched, determine if the distance is better. - IF levenshtein_ignore_case(rec.name, tempString) < tempInt THEN - location := tempString; - tempInt := levenshtein_ignore_case(rec.name, tempString); - END IF; - END IF; - END LOOP; - ELSE - FOR rec IN SELECT name FROM place_lookup - WHERE soundex(tempString) = end_soundex(name) LOOP - word_count := count_words(rec.name); - test := TRUE; - tempString := get_last_words(fullStreet, word_count); - FOR i IN 1..word_count LOOP - IF soundex(split_part(tempString, '' '', i)) != - soundex(split_part(rec.name, '' '', i)) THEN - test := FALSE; - END IF; - END LOOP; - IF test THEN - -- The soundex matched, determine if the distance is better. - IF levenshtein_ignore_case(rec.name, tempString) < tempInt THEN - location := tempString; - tempInt := levenshtein_ignore_case(rec.name, tempString); - END IF; - END IF; - END LOOP; - END IF; - END IF; - RETURN location; -END; -' LANGUAGE plpgsql; - - - --- normalize_address(addressString) --- This takes an address string and parses it into address (internal/street) --- street name, type, direction prefix and suffix, location, state and --- zip code, depending on what can be found in the string. --- --- The US postal address standard is used: --- --- --- --- State is assumed to be included in the string, and MUST be matchable to --- something in the state_lookup table. Fuzzy matching is used if no direct --- match is found. --- --- Two formats of zip code are acceptable: five digit, and five + 4. --- --- The internal addressing indicators are looked up from the --- secondary_unit_lookup table. A following identifier is accepted --- but it must start with a digit. --- --- The location is parsed from the string using other indicators, such --- as street type, direction suffix or internal address, if available. --- If these are not, the location is extracted using comparisons against --- the places_lookup table, then the countysub_lookup table to determine --- what, in the original string, is intended to be the location. In both --- cases, an exact match is first pursued, then a word-by-word fuzzy match. --- The result is not the name of the location from the tables, but the --- section of the given string that corresponds to the name from the tables. --- --- Zip codes and street names are not validated. --- --- Direction indicators are extracted by comparison with the direction_lookup --- table. --- --- Street addresses are assumed to be a single word, starting with a number. --- Address is manditory; if no address is given, and the street is numbered, --- the resulting address will be the street name, and the street name --- will be an empty string. --- --- In some cases, the street type is part of the street name. --- eg State Hwy 22a. As long as the word following the type starts with a --- number (this is usually the case) this will be caught. Some street names --- include a type name, and have a street type that differs. This will be --- handled properly, so long as both are given. If the street type is --- omitted, the street names included type will be parsed as the street type. --- --- The output is currently a colon seperated list of values: --- InternalAddress:StreetAddress:DirectionPrefix:StreetName:StreetType: --- DirectionSuffix:Location:State:ZipCode --- This returns each element as entered. It's mainly meant for debugging. --- There is also another option that returns: --- StreetAddress:DirectionPrefixAbbreviation:StreetName:StreetTypeAbbreviation: --- DirectionSuffixAbbreviation:Location:StateAbbreviation:ZipCode --- This is more standardized and better for use with a geocoder. -CREATE OR REPLACE FUNCTION normalize_address(VARCHAR) RETURNS VARCHAR -AS ' -DECLARE - rawInput VARCHAR; - address VARCHAR; - preDir VARCHAR; - preDirAbbrev VARCHAR; - postDir VARCHAR; - postDirAbbrev VARCHAR; - fullStreet VARCHAR; - reducedStreet VARCHAR; - streetName VARCHAR; - streetType VARCHAR; - streetTypeAbbrev VARCHAR; - internal VARCHAR; - location VARCHAR; - state VARCHAR; - stateAbbrev VARCHAR; - tempString VARCHAR; - tempInt INTEGER; - result VARCHAR; - zip VARCHAR; - test BOOLEAN; - working REFCURSOR; - rec RECORD; - ws VARCHAR; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''normalize_address()''; - END IF; - IF $1 IS NULL THEN - RAISE EXCEPTION ''normalise_address() - address string is null!''; - ELSE - rawInput := $1; - END IF; - ws := ''[ ,\.\t\n\f\r]''; - - -- Assume that the address begins with a digit, and extract it from - -- the input string. - address := substring(rawInput from ''^([0-9].*?)[ ,/.]''); - - -- There are two formats for zip code, the normal 5 digit, and - -- the nine digit zip-4. It may also not exist. - zip := substring(rawInput from ws || ''([0-9]{5})$''); - IF zip IS NULL THEN - zip := substring(rawInput from ws || ''([0-9]{5})-[0-9]{4}$''); - END IF; - - IF zip IS NOT NULL THEN - fullStreet := substring(rawInput from ''(.*)'' - || ws || ''+'' || cull_null(zip) || ''[- ]?([0-9]{4})?$''); - ELSE - fullStreet := rawInput; - END IF; - IF verbose THEN - RAISE NOTICE ''normalize_address() - after zip extract "%"'', fullStreet; - END IF; - tempString := state_extract(fullStreet); - IF tempString IS NOT NULL THEN - state := split_part(tempString, '':'', 1); - stateAbbrev := split_part(tempString, '':'', 2); - END IF; - - -- The easiest case is if the address is comma delimited. There are some - -- likely cases: - -- street level, location, state - -- street level, location state - -- street level, location - -- street level, internal address, location, state - -- street level, internal address, location state - -- street level, internal address location state - -- street level, internal address, location - -- street level, internal address location - -- The first three are useful. - tempString := substring(fullStreet, ''(?i),'' || ws || ''+(.*)(,?'' || ws || - ''+'' || cull_null(state) || ''|$)''); - IF tempString IS NOT NULL THEN - location := tempString; - IF address IS NOT NULL THEN - fullStreet := substring(fullStreet, ''(?i)'' || address || ws || - ''+(.*),'' || ws || ''+'' || location); - ELSE - fullStreet := substring(fullStreet, ''(?i)(.*),'' || ws || ''+'' || - location); - END IF; - IF verbose THEN - RAISE NOTICE ''normalize_address() - Parsed by punctuation.''; - RAISE NOTICE ''normalize_address() - Location "%"'', location; - RAISE NOTICE ''normalize_address() - FullStreet "%"'', fullStreet; - END IF; - END IF; - - -- Pull out the full street information, defined as everything between the - -- address and the state. This includes the location. - -- This doesnt need to be done if location has already been found. - IF location IS NULL THEN - IF address IS NOT NULL THEN - IF state IS NOT NULL THEN - fullStreet := substring(fullStreet, ''(?i)'' || address || - ws || ''+(.*?)'' || ws || ''+'' || state); - ELSE - fullStreet := substring(fullStreet, ''(?i)'' || address || - ws || ''+(.*?)''); - END IF; - ELSE - IF state IS NOT NULL THEN - fullStreet := substring(fullStreet, ''(?i)(.*?)'' || ws || - ''+'' || state); - ELSE - fullStreet := substring(fullStreet, ''(?i)(.*?)''); - END IF; - END IF; - END IF; - IF verbose THEN - RAISE NOTICE ''normalize_address() - after addy extract "%"'', fullStreet; - END IF; - - -- Determine if any internal address is included, such as apartment - -- or suite number. - SELECT INTO tempInt count(*) FROM secondary_unit_lookup - WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name || ''('' - || ws || ''|$)''); - IF tempInt = 1 THEN - SELECT INTO internal substring(fullStreet, ''(?i)'' || ws || ''('' - || name || ws || ''*#?'' || ws - || ''*(?:[0-9][0-9a-zA-Z\-]*)?'' || '')(?:'' || ws || ''|$)'') - FROM secondary_unit_lookup - WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name || ''('' - || ws || ''|$)''); - ELSIF tempInt > 1 THEN - -- In the event of multiple matches to a secondary unit designation, we - -- will assume that the last one is the true one. - tempInt := 0; - FOR rec in SELECT trim(substring(fullStreet, ''(?i)'' || ws || ''('' - || name || ''(?:'' || ws || ''*#?'' || ws - || ''*(?:[0-9][0-9a-zA-Z\-]*)?)'' || ws || ''?|$)'')) as value - FROM secondary_unit_lookup - WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name || ''('' - || ws || ''|$)'') LOOP - IF tempInt < position(rec.value in fullStreet) THEN - tempInt := position(rec.value in fullStreet); - internal := rec.value; - END IF; - END LOOP; - END IF; - - IF verbose THEN - RAISE NOTICE ''normalize_address() - internal: "%"'', internal; - END IF; - - IF location IS NULL THEN - -- If the internal address is given, the location is everything after it. - location := substring(fullStreet, internal || ws || ''+(.*)$''); - END IF; - - -- Pull potential street types from the full street information - SELECT INTO tempInt count(*) FROM street_type_lookup - WHERE texticregexeq(fullStreet, ''(?i)'' || ws || ''('' || name - || '')(?:'' || ws || ''|$)''); - IF tempInt = 1 THEN - SELECT INTO rec abbrev, substring(fullStreet, ''(?i)'' || ws || ''('' - || name || '')(?:'' || ws || ''|$)'') AS given FROM street_type_lookup - WHERE texticregexeq(fullStreet, ''(?i)'' || ws || ''('' || name - || '')(?:'' || ws || ''|$)''); - streetType := rec.given; - streetTypeAbbrev := rec.abbrev; - ELSIF tempInt > 1 THEN - tempInt := 0; - FOR rec IN SELECT abbrev, substring(fullStreet, ''(?i)'' || ws || ''('' - || name || '')(?:'' || ws || ''|$)'') AS given FROM street_type_lookup - WHERE texticregexeq(fullStreet, ''(?i)'' || ws || ''('' || name - || '')(?:'' || ws || ''|$)'') LOOP - -- If we have found an internal address, make sure the type - -- precedes it. - IF internal IS NOT NULL THEN - IF position(rec.given IN fullStreet) < - position(internal IN fullStreet) THEN - IF tempInt < position(rec.given IN fullStreet) THEN - streetType := rec.given; - streetTypeAbbrev := rec.abbrev; - tempInt := position(rec.given IN fullStreet); - END IF; - END IF; - ELSIF tempInt < position(rec.given IN fullStreet) THEN - streetType := rec.given; - streetTypeAbbrev := rec.abbrev; - tempInt := position(rec.given IN fullStreet); - END IF; - END LOOP; - END IF; - IF verbose THEN - RAISE NOTICE ''normalize_address() - street Type: "%"'', streetType; - END IF; - - -- There is a little more processing required now. If the word after the - -- street type begins with a number, the street type should be considered - -- part of the name, as well as the next word. eg, State Route 225a. If - -- the next word starts with a char, then everything after the street type - -- will be considered location. If there is no street type, then Im sad. - IF streetType IS NOT NULL THEN - tempString := substring(fullStreet, streetType || ws || - ''+([0-9][^ ,\.\t\r\n\f]*?)'' || ws); - IF tempString IS NOT NULL THEN - IF location IS NULL THEN - location := substring(fullStreet, streetType || ws || ''+'' - || tempString || ws || ''+(.*)$''); - END IF; - reducedStreet := substring(fullStreet, ''(.*)'' || ws || ''+'' - || location || ''$''); - streetType := NULL; - streetTypeAbbrev := NULL; - ELSE - IF location IS NULL THEN - location := substring(fullStreet, streetType || ws || ''+(.*)$''); - END IF; - reducedStreet := substring(fullStreet, ''^(.*)'' || ws || ''+'' - || streetType); - END IF; - - -- The pre direction should be at the beginning of the fullStreet string. - -- The post direction should be at the beginning of the location string - -- if there is no internal address - SELECT INTO tempString substring(reducedStreet, ''(?i)(^'' || name - || '')'' || ws) FROM direction_lookup WHERE - texticregexeq(reducedStreet, ''(?i)(^'' || name || '')'' || ws) - ORDER BY length(name) DESC; - IF tempString IS NOT NULL THEN - preDir := tempString; - SELECT INTO preDirAbbrev abbrev FROM direction_lookup - where texticregexeq(reducedStreet, ''(?i)(^'' || name || '')'' || ws) - ORDER BY length(name) DESC; - streetName := substring(reducedStreet, ''^'' || preDir || ws || ''(.*)''); - ELSE - streetName := reducedStreet; - END IF; - - IF texticregexeq(location, ''(?i)'' || internal || ''$'') THEN - -- If the internal address is at the end of the location, then no - -- location was given. We still need to look for post direction. - SELECT INTO rec abbrev, - substring(location, ''(?i)^('' || name || '')'' || ws) as value - FROM direction_lookup WHERE texticregexeq(location, ''(?i)^'' - || name || ws) ORDER BY length(name) desc; - IF rec.value IS NOT NULL THEN - postDir := rec.value; - postDirAbbrev := rec.abbrev; - END IF; - location := null; - ELSIF internal IS NULL THEN - -- If no location is given, the location string will be the post direction - SELECT INTO tempInt count(*) FROM direction_lookup WHERE - upper(location) = upper(name); - IF tempInt != 0 THEN - postDir := location; - SELECT INTO postDirAbbrev abbrev FROM direction_lookup WHERE - upper(postDir) = upper(name); - location := NULL; - ELSE - -- postDirection is not equal location, but may be contained in it. - SELECT INTO tempString substring(location, ''(?i)(^'' || name - || '')'' || ws) FROM direction_lookup WHERE - texticregexeq(location, ''(?i)(^'' || name || '')'' || ws) - ORDER BY length(name) desc; - IF tempString IS NOT NULL THEN - postDir := tempString; - SELECT INTO postDirAbbrev abbrev FROM direction_lookup - where texticregexeq(location, ''(?i)(^'' || name || '')'' || ws); - location := substring(location, ''^'' || postDir || ws || ''+(.*)''); - END IF; - END IF; - ELSE - -- internal is not null, but is not at the end of the location string - -- look for post direction before the internal address - SELECT INTO tempString substring(fullStreet, ''(?i)'' || streetType - || ws || ''+('' || name || '')'' || ws || ''+'' || internal) - FROM direction_lookup WHERE texticregexeq(fullStreet, ''(?i)'' - || ws || name || ws || ''+'' || internal) ORDER BY length(name) desc; - IF tempString IS NOT NULL THEN - postDir := tempString; - SELECT INTO postDirAbbrev abbrev FROM direction_lookup - WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name || ws); - END IF; - END IF; - ELSE - -- No street type was found - - -- If an internal address was given, then the split becomes easy, and the - -- street name is everything before it, without directions. - IF internal IS NOT NULL THEN - reducedStreet := substring(fullStreet, ''(?i)^(.*?)'' || ws || ''+'' - || internal); - SELECT INTO tempInt count(*) FROM direction_lookup WHERE - texticregexeq(reducedStreet, ''(?i)'' || ws || name || ''$''); - IF tempInt > 0 THEN - SELECT INTO postDir substring(reducedStreet, ''(?i)'' || ws || ''('' - || name || '')'' || ''$'') FROM direction_lookup - WHERE texticregexeq(reducedStreet, ''(?i)'' || ws || name || ''$''); - SELECT INTO postDirAbbrev abbrev FROM direction_lookup - WHERE texticregexeq(reducedStreet, ''(?i)'' || ws || name || ''$''); - END IF; - SELECT INTO tempString substring(reducedStreet, ''(?i)^('' || name - || '')'' || ws) FROM direction_lookup WHERE - texticregexeq(reducedStreet, ''(?i)^('' || name || '')'' || ws) - ORDER BY length(name) DESC; - IF tempString IS NOT NULL THEN - preDir := tempString; - SELECT INTO preDirAbbrev abbrev FROM direction_lookup WHERE - texticregexeq(reducedStreet, ''(?i)(^'' || name || '')'' || ws) - ORDER BY length(name) DESC; - streetName := substring(reducedStreet, ''(?i)^'' || preDir || ws - || ''+(.*?)(?:'' || ws || ''+'' || cull_null(postDir) || ''|$)''); - ELSE - streetName := substring(reducedStreet, ''(?i)^(.*?)(?:'' || ws - || ''+'' || cull_null(postDir) || ''|$)''); - END IF; - ELSE - - -- If a post direction is given, then the location is everything after, - -- the street name is everything before, less any pre direction. - SELECT INTO tempInt count(*) FROM direction_lookup - WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name || ''(?:'' - || ws || ''|$)''); - - IF tempInt = 1 THEN - -- A single postDir candidate was found. This makes it easier. - SELECT INTO postDir substring(fullStreet, ''(?i)'' || ws || ''('' - || name || '')(?:'' || ws || ''|$)'') FROM direction_lookup WHERE - texticregexeq(fullStreet, ''(?i)'' || ws || name || ''(?:'' - || ws || ''|$)''); - SELECT INTO postDirAbbrev abbrev FROM direction_lookup - WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name - || ''(?:'' || ws || ''|$)''); - IF location IS NULL THEN - location := substring(fullStreet, ''(?i)'' || ws || postDir - || ws || ''+(.*?)$''); - END IF; - reducedStreet := substring(fullStreet, ''^(.*?)'' || ws || ''+'' - || postDir); - SELECT INTO tempString substring(reducedStreet, ''(?i)(^'' || name - || '')'' || ws) FROM direction_lookup WHERE - texticregexeq(reducedStreet, ''(?i)(^'' || name || '')'' || ws) - ORDER BY length(name) DESC; - IF tempString IS NOT NULL THEN - preDir := tempString; - SELECT INTO preDirAbbrev abbrev FROM direction_lookup WHERE - texticregexeq(reducedStreet, ''(?i)(^'' || name || '')'' || ws) - ORDER BY length(name) DESC; - streetName := substring(reducedStreet, ''^'' || preDir || ws - || ''+(.*)''); - ELSE - streetName := reducedStreet; - END IF; - ELSIF tempInt > 1 THEN - -- Multiple postDir candidates were found. We need to find the last - -- incident of a direction, but avoid getting the last word from - -- a two word direction. eg extracting "East" from "North East" - -- We do this by sorting by length, and taking the last direction - -- in the results that is not included in an earlier one. - -- This wont be a problem it preDir is North East and postDir is - -- East as the regex requires a space before the direction. Only - -- the East will return from the preDir. - tempInt := 0; - FOR rec IN SELECT abbrev, substring(fullStreet, ''(?i)'' || ws || ''('' - || name || '')(?:'' || ws || ''|$)'') AS value - FROM direction_lookup - WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name - || ''(?:'' || ws || ''|$)'') - ORDER BY length(name) desc LOOP - tempInt := 0; - IF tempInt < position(rec.value in fullStreet) THEN - IF postDir IS NULL THEN - tempInt := position(rec.value in fullStreet); - postDir := rec.value; - postDirAbbrev := rec.abbrev; - ELSIF NOT texticregexeq(postDir, ''(?i)'' || rec.value) THEN - tempInt := position(rec.value in fullStreet); - postDir := rec.value; - postDirAbbrev := rec.abbrev; - END IF; - END IF; - END LOOP; - IF location IS NULL THEN - location := substring(fullStreet, ''(?i)'' || ws || postDir || ws - || ''+(.*?)$''); - END IF; - reducedStreet := substring(fullStreet, ''(?i)^(.*?)'' || ws || ''+'' - || postDir); - SELECT INTO tempString substring(reducedStreet, ''(?i)(^'' || name - || '')'' || ws) FROM direction_lookup WHERE - texticregexeq(reducedStreet, ''(?i)(^'' || name || '')'' || ws) - ORDER BY length(name) DESC; - IF tempString IS NOT NULL THEN - preDir := tempString; - SELECT INTO preDirAbbrev abbrev FROM direction_lookup WHERE - texticregexeq(reducedStreet, ''(?i)(^'' || name || '')'' || ws) - ORDER BY length(name) DESC; - streetName := substring(reducedStreet, ''^'' || preDir || ws - || ''+(.*)''); - ELSE - streetName := reducedStreet; - END IF; - ELSE - - -- There is no street type, directional suffix or internal address - -- to allow distinction between street name and location. - IF location IS NULL THEN - location := location_extract(fullStreet, stateAbbrev); - END IF; - -- Check for a direction prefix. - SELECT INTO tempString substring(fullStreet, ''(?i)(^'' || name - || '')'' || ws) FROM direction_lookup WHERE - texticregexeq(fullStreet, ''(?i)(^'' || name || '')'' || ws) - ORDER BY length(name); - RAISE NOTICE ''DEBUG 1''; - IF tempString IS NOT NULL THEN - preDir := tempString; - SELECT INTO preDirAbbrev abbrev FROM direction_lookup WHERE - texticregexeq(fullStreet, ''(?i)(^'' || name || '')'' || ws) - ORDER BY length(name) DESC; - IF location IS NOT NULL THEN - -- The location may still be in the fullStreet, or may - -- have been removed already - streetName := substring(fullStreet, ''^'' || preDir || ws - || ''+(.*?)('' || ws || ''+'' || location || ''|$)''); - RAISE NOTICE ''DEBUG 2.1 "%", "%"'', streetName, fullStreet; - ELSE - streetName := substring(fullStreet, ''^'' || preDir || ws - || ''+(.*?)'' || ws || ''*''); - END IF; - ELSE - IF location IS NOT NULL THEN - -- The location may still be in the fullStreet, or may - -- have been removed already - streetName := substring(fullStreet, ''^(.*?)('' || ws - || ''+'' || location || ''|$)''); - RAISE NOTICE ''DEBUG 2.2 "%", "%"'', streetName, fullStreet; - ELSE - streetName := fullStreet; - END IF; - END IF; - END IF; - END IF; - END IF; - - - - RAISE NOTICE ''normalize_address() - final internal "%"'', internal; - RAISE NOTICE ''normalize_address() - prefix_direction "%"'', preDir; - RAISE NOTICE ''normalize_address() - street_type "%"'', streetType; - RAISE NOTICE ''normalize_address() - suffix_direction "%"'', postDir; - RAISE NOTICE ''normalize_address() - state "%"'', state; - - -- This is useful for scripted checking. It returns what was entered - -- for each field, rather than what should be used by the geocoder. - --result := cull_null(internal) || '':'' || cull_null(address) || '':'' - --|| cull_null(preDir) || '':'' || cull_null(streetName) || '':'' - --|| cull_null(streetType) || '':'' || cull_null(postDir) - --|| '':'' || cull_null(location) || '':'' || cull_null(state) || '':'' - --|| cull_null(zip); - - -- This is the standardized return. - result := cull_null(address) || '':'' || cull_null(preDirAbbrev) || '':'' - || cull_null(streetName) || '':'' || cull_null(streetTypeAbbrev) || '':'' - || cull_null(postDirAbbrev) || '':'' || cull_null(location) || '':'' - || cull_null(stateAbbrev) || '':'' || cull_null(zip); - return result; -END -' LANGUAGE plpgsql; - - - --- rate_attributes(dirpA, dirpB, streetNameA, streetNameB, streetTypeA, --- streetTypeB, dirsA, dirsB, locationA, locationB) --- Rates the street based on the given attributes. The locations must be --- non-null. The other eight values are handled by the other rate_attributes --- function, so it's requirements must also be met. -CREATE OR REPLACE FUNCTION rate_attributes(VARCHAR, VARCHAR, VARCHAR, VARCHAR, - VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS INTEGER -AS ' -DECLARE - result INTEGER := 0; - locationWeight INTEGER := 14; -BEGIN - IF $9 IS NOT NULL AND $10 IS NOT NULL THEN - result := levenshtein_ignore_case($9, $10); - ELSE - RAISE EXCEPTION ''rate_attributes() - Location names cannot be null!''; - END IF; - result := result + rate_attributes($1, $2, $3, $4, $5, $6, $7, $8); - RETURN result; -END; -' LANGUAGE plpgsql; - --- rate_attributes(dirpA, dirpB, streetNameA, streetNameB, streetTypeA, --- streetTypeB, dirsA, dirsB) --- Rates the street based on the given attributes. Only streetNames are --- required. If any others are null (either A or B) they are treated as --- empty strings. -CREATE OR REPLACE FUNCTION rate_attributes(VARCHAR, VARCHAR, VARCHAR, VARCHAR, - VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS INTEGER -AS ' -DECLARE - result INTEGER := 0; - directionWeight INTEGER := 2; - nameWeight INTEGER := 10; - typeWeight INTEGER := 5; -BEGIN - result := result + levenshtein_ignore_case(cull_null($1), cull_null($2)) * - directionWeight; - IF $3 IS NOT NULL AND $4 IS NOT NULL THEN - result := result + levenshtein_ignore_case($3, $4) * nameWeight; - ELSE - RAISE EXCEPTION ''rate_attributes() - Street names cannot be null!''; - END IF; - result := result + levenshtein_ignore_case(cull_null($5), cull_null($6)) * - typeWeight; - result := result + levenshtein_ignore_case(cull_null($7), cull_null($7)) * - directionWeight; - return result; -END; -' LANGUAGE plpgsql; - - - --- state_extract(addressStringLessZipCode) --- Extracts the state from end of the given string. --- --- This function uses the state_lookup table to determine which state --- the input string is indicating. First, an exact match is pursued, --- and in the event of failure, a word-by-word fuzzy match is attempted. --- --- The result is the state as given in the input string, and the approved --- state abbreviation, seperated by a colon. -CREATE OR REPLACE FUNCTION state_extract(VARCHAR) RETURNS VARCHAR -AS ' -DECLARE - tempInt INTEGER; - tempString VARCHAR; - rawInput VARCHAR; - state VARCHAR; - stateAbbrev VARCHAR; - result VARCHAR; - rec RECORD; - test BOOLEAN; - ws VARCHAR; - verbose BOOLEAN := TRUE; -BEGIN - IF verbose THEN - RAISE NOTICE ''state_extract()''; - END IF; - IF $1 IS NULL THEN - RAISE EXCEPTION ''state_extract() - no input''; - ELSE - rawInput := $1; - END IF; - ws := ''[ ,\.\t\n\f\r]''; - - -- Separate out the last word of the state, and use it to compare to - -- the state lookup table to determine the entire name, as well as the - -- abbreviation associated with it. The zip code may or may not have - -- been found. - tempString := substring(rawInput from ws || ''+([^ ,\.\t\n\f\r0-9]*?)$''); - SELECT INTO tempInt count(*) FROM (select distinct abbrev from state_lookup - WHERE upper(abbrev) = upper(tempString)) as blah; - IF tempInt = 1 THEN - state := tempString; - SELECT INTO stateAbbrev abbrev FROM (select distinct abbrev from - state_lookup WHERE upper(abbrev) = upper(tempString)) as blah; - ELSE - SELECT INTO tempInt count(*) FROM state_lookup WHERE upper(name) - like upper(''%'' || tempString); - IF tempInt >= 1 THEN - FOR rec IN SELECT name from state_lookup WHERE upper(name) - like upper(''%'' || tempString) LOOP - SELECT INTO test texticregexeq(rawInput, name) FROM state_lookup - WHERE rec.name = name; - IF test THEN - SELECT INTO stateAbbrev abbrev FROM state_lookup - WHERE rec.name = name; - state := substring(rawInput, ''(?i)'' || rec.name); - EXIT; - END IF; - END LOOP; - ELSE - -- No direct match for state, so perform fuzzy match. - SELECT INTO tempInt count(*) FROM state_lookup - WHERE soundex(tempString) = end_soundex(name); - IF tempInt >= 1 THEN - FOR rec IN SELECT name, abbrev FROM state_lookup - WHERE soundex(tempString) = end_soundex(name) LOOP - tempInt := count_words(rec.name); - tempString := get_last_words(rawInput, tempInt); - test := TRUE; - FOR i IN 1..tempInt LOOP - IF soundex(split_part(tempString, '' '', i)) != - soundex(split_part(rec.name, '' '', i)) THEN - test := FALSE; - END IF; - END LOOP; - IF test THEN - state := tempString; - stateAbbrev := rec.abbrev; - EXIT; - END IF; - END LOOP; - END IF; - END IF; - END IF; - IF state IS NOT NULL AND stateAbbrev IS NOT NULL THEN - result := state || '':'' || stateAbbrev; - END IF; - return result; -END; -' LANGUAGE plpgsql; +-- Runs the soundex function on the last word in the string provided. +-- Words are allowed to be seperated by space, comma, period, new-line +-- tab or form feed. +CREATE OR REPLACE FUNCTION end_soundex(VARCHAR) RETURNS VARCHAR +AS ' +DECLARE + tempString VARCHAR; +BEGIN + tempString := substring($1, ''[ ,\.\n\t\f]([a-zA-Z0-9]*)$''); + IF tempString IS NOT NULL THEN + tempString := soundex(tempString); + ELSE + tempString := soundex($1); + END IF; + return tempString; +END; +' LANGUAGE plpgsql; + +-- Returns the value passed, or an empty string if null. +-- This is used to concatinate values that may be null. +CREATE OR REPLACE FUNCTION cull_null(VARCHAR) RETURNS VARCHAR +AS ' +BEGIN + IF $1 IS NULL THEN + return ''''; + ELSE + return $1; + END IF; +END; +' LANGUAGE plpgsql; + +-- Determine the number of words in a string. Words are allowed to +-- be seperated only by spaces, but multiple spaces between +-- words are allowed. +CREATE OR REPLACE FUNCTION count_words(VARCHAR) RETURNS INTEGER +AS ' +DECLARE + tempString VARCHAR; + tempInt INTEGER; + count INTEGER := 1; + lastSpace BOOLEAN := FALSE; +BEGIN + IF $1 IS NULL THEN + return -1; + END IF; + tempInt := length($1); + IF tempInt = 0 THEN + return 0; + END IF; + FOR i IN 1..tempInt LOOP + tempString := substring($1 from i for 1); + IF tempString = '' '' THEN + IF NOT lastSpace THEN + count := count + 1; + END IF; + lastSpace := TRUE; + ELSE + lastSpace := FALSE; + END IF; + END LOOP; + return count; +END; +' LANGUAGE plpgsql; + + + +CREATE OR REPLACE FUNCTION geocode(VARCHAR) RETURNS REFCURSOR +AS ' +BEGIN + return geocode(NULL, $1); +END; +' LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION geocode(REFCURSOR, VARCHAR) RETURNS REFCURSOR +AS ' +DECLARE + result REFCURSOR; + input VARCHAR; + parsed VARCHAR; + addressString VARCHAR; + address INTEGER; + directionPrefix VARCHAR; + streetName VARCHAR; + streetType VARCHAR; + directionSuffix VARCHAR; + location VARCHAR; + state VARCHAR; + zipCodeString VARCHAR; + zipCode INTEGER; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''geocode()''; + END IF; + -- Check inputs. + IF $1 IS NOT NULL THEN + result := $1; + END IF; + IF $2 IS NULL THEN + -- The address string is manditory. + RAISE EXCEPTION ''geocode() - No address string provided.''; + ELSE + input := $2; + END IF; + + -- Pass the input string into the address normalizer + parsed := normalize_address(input); + IF parsed IS NULL THEN + RAISE EXCEPTION ''geocode() - address string failed to parse.''; + END IF; + + addressString := split_part(parsed, '':'', 1); + directionPrefix := split_part(parsed, '':'', 2); + streetName := split_part(parsed, '':'', 3); + streetType := split_part(parsed, '':'', 4); + directionSuffix := split_part(parsed, '':'', 5); + location := split_part(parsed, '':'', 6); + state := split_part(parsed, '':'', 7); + zipCodeString := split_part(parsed, '':'', 8); + + -- Empty strings must be converted to nulls; + IF addressString = '''' THEN + addressString := NULL; + END IF; + IF directionPrefix = '''' THEN + directionPrefix := NULL; + END IF; + IF streetName = '''' THEN + streetName := NULL; + END IF; + IF streetType = '''' THEN + streetType := NULL; + END IF; + IF directionSuffix = '''' THEN + directionSuffix := NULL; + END IF; + IF location = '''' THEN + location := NULL; + END IF; + IF state = '''' THEN + state := NULL; + END IF; + IF zipCodeString = '''' THEN + zipCodeString := NULL; + END IF; + + -- address and zipCode must be integers + IF addressString IS NOT NULL THEN + address := to_number(addressString, ''99999999999''); + END IF; + IF zipCodeString IS NOT NULL THEN + zipCode := to_number(zipCodeString, ''99999''); + END IF; + + IF verbose THEN + RAISE NOTICE ''geocode() - address %'', address; + RAISE NOTICE ''geocode() - directionPrefix %'', directionPrefix; + RAISE NOTICE ''geocode() - streetName "%"'', streetName; + RAISE NOTICE ''geocode() - streetType %'', streetType; + RAISE NOTICE ''geocode() - directionSuffix %'', directionSuffix; + RAISE NOTICE ''geocode() - location "%"'', location; + RAISE NOTICE ''geocode() - state %'', state; + RAISE NOTICE ''geocode() - zipCode %'', zipCode; + END IF; + -- This is where any validation above the geocode_address functions would go. + + -- Call geocode_address + result := geocode_address(result, address, directionPrefix, streetName, + streetType, directionSuffix, location, state, zipCode); + RETURN result; +END; +' LANGUAGE plpgsql; + + + +-- geocode(cursor, address, directionPrefix, streetName, +-- streetTypeAbbreviation, directionSuffix, location, stateAbbreviation, +-- zipCode) +CREATE OR REPLACE FUNCTION geocode_address(refcursor, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, INTEGER) RETURNS REFCURSOR +AS ' +DECLARE + result REFCURSOR; + address INTEGER; + directionPrefix VARCHAR; + streetName VARCHAR; + streetTypeAbbrev VARCHAR; + directionSuffix VARCHAR; + location VARCHAR; + stateAbbrev VARCHAR; + state VARCHAR; + zipCode INTEGER; + tempString VARCHAR; + tempInt VARCHAR; + locationPlaceExact BOOLEAN := FALSE; + locationPlaceFuzzy BOOLEAN := FALSE; + locationCountySubExact BOOLEAN := FALSE; + locationCountySubFuzzy BOOLEAN := FALSE; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''geocode_address()''; + END IF; + -- The first step is to determine what weve been given, and if its enough. + IF $1 IS NOT NULL THEN + -- The result was not provided. No matter, we can use an unnamed one. + result := $1; + END IF; + IF $2 IS NULL THEN + -- The address is manditory. + -- Without it, wed be wandering into strangers homes all the time. + RAISE EXCEPTION ''geocode_address() - No address provided!''; + ELSE + address := $2; + END IF; + IF $3 IS NOT NULL THEN + -- The direction prefix really isnt important. + -- It will be used for rating if provided. + directionPrefix := $3; + END IF; + IF $4 IS NULL THEN + -- A street name must be given. Think about it. + RAISE EXCEPTION ''geocode_address() - No street name provided!''; + ELSE + streetName := $4; + END IF; + IF $5 IS NOT NULL THEN + -- A street type will be used for rating if provided, but isnt required. + streetTypeAbbrev := $5; + END IF; + IF $6 IS NOT NULL THEN + -- Same as direction prefix, only later. + directionSuffix := $6; + END IF; + IF $7 IS NOT NULL THEN + -- Location is not needed iff a zip is given. The check occurs after + -- the geocode_address_zip call. + location := $7; + END IF; + IF $8 IS NULL THEN + -- State abbreviation is manditory. It is also assumed to be valid. + ELSE + stateAbbrev := $8; + END IF; + IF $9 IS NOT NULL THEN + -- Zip code is optional, but nice. + zipCode := $9; + END IF; + + -- The geocoding tables store the state name rather than the abbreviation. + -- We can validate the abbreviation while retrieving the name. + IF stateAbbrev IS NOT NULL THEN + SELECT INTO state name FROM state_lookup + WHERE state_lookup.abbrev = stateAbbrev; + IF state IS NULL THEN + END IF; + END IF; + + IF zipCode IS NOT NULL THEN + IF verbose THEN + RAISE NOTICE ''geocode_address() - calling geocode_address_zip()''; + END IF; + -- If the zip code is given, it is the most useful way to narrow the + -- search. We will try it first, and if no results match, we will move + -- on to a location search. There is no fuzzy searching on zip codes. + result := geocode_address_zip(result, address, directionPrefix, streetName, + streetTypeAbbrev, directionSuffix, zipCode); + IF result IS NOT NULL THEN + RETURN result; + ELSE + result := $1; + END IF; + END IF; + -- After now, the location becomes manditory. + IF location IS NOT NULL THEN + -- location may be useful, it may not. The first step is to determine if + -- there are any potenial matches in the place and countysub fields. + -- This is done against the lookup tables, and will save us time on much + -- larger queries if they dont match. + IF verbose THEN + RAISE NOTICE ''geocode_address() - calling location_extract_place_*()''; + END IF; + tempString := location_extract_place_exact(location, stateAbbrev); + IF tempString IS NOT NULL THEN + locationPlaceExact := TRUE; + ELSE + locationPlaceExact := FALSE; + END IF; + tempString := location_extract_place_fuzzy(location, stateAbbrev); + IF tempString IS NOT NULL THEN + locationPlaceFuzzy := true; + ELSE + locationPlaceFuzzy := false; + END IF; + IF verbose THEN + RAISE NOTICE ''geocode_address() - calling location_extract_countysub_*()''; + END IF; + tempString := location_extract_countysub_exact(location, stateAbbrev); + IF tempString IS NOT NULL THEN + locationCountySubExact := TRUE; + ELSE + locationCountySubExact := FALSE; + END IF; + tempString := location_extract_countysub_fuzzy(location, stateAbbrev); + IF tempString IS NOT NULL THEN + locationCountySubFuzzy := true; + ELSE + locationCountySubFuzzy := false; + END IF; + END IF; + IF locationPlaceExact THEN + IF verbose THEN + RAISE NOTICE ''geocode_address() - calling geocode_address_place_exact()''; + END IF; + result := geocode_address_place_exact(result, address, directionPrefix, + streetName, streetTypeAbbrev, directionSuffix, location, state); + IF result IS NOT NULL THEN + RETURN result; + ELSE + result := $1; + END IF; + END IF; + IF locationCountySubExact THEN + IF verbose THEN + RAISE NOTICE ''geocode_address() - calling geocode_address_countysub_exact()''; + END IF; + result := geocode_address_countysub_exact(result, address, directionPrefix, + streetName, streetTypeAbbrev, directionSuffix, location, state); + IF result IS NOT NULL THEN + RETURN result; + ELSE + result := $1; + END IF; + END IF; + IF locationPlaceFuzzy THEN + IF verbose THEN + RAISE NOTICE ''geocode_address() - calling geocode_address_place_fuzzy()''; + END IF; + result := geocode_address_place_fuzzy(result, address, directionPrefix, + streetName, streetTypeAbbrev, directionSuffix, location, state); + IF result IS NOT NULL THEN + RETURN result; + ELSE + result := $1; + END IF; + END IF; + IF locationCountySubFuzzy THEN + IF verbose THEN + RAISE NOTICE ''geocode_address() - calling geocode_address_countysub_fuzzy()''; + END IF; + result := geocode_address_countysub_fuzzy(result, address, directionPrefix, + streetName, streetTypeAbbrev, directionSuffix, location, state); + IF result IS NOT NULL THEN + RETURN result; + ELSE + result := $1; + END IF; + END IF; + IF state IS NOT NULL THEN + IF verbose THEN + RAISE NOTICE ''geocode_address() - calling geocode_address_state()''; + END IF; + result := geocode_address_state(result, address, directionPrefix, + streetName, streetTypeAbbrev, directionSuffix, state); + IF result IS NOT NULL THEN + RETURN result; + ELSE + result := $1; + END IF; + END IF; + RETURN NULL; +END; +' LANGUAGE plpgsql; + + + +CREATE OR REPLACE FUNCTION geocode_address_countysub_exact(REFCURSOR, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS REFCURSOR +AS ' +DECLARE + result REFCURSOR; + address INTEGER; + directionPrefix VARCHAR; + streetName VARCHAR; + streetTypeAbbrev VARCHAR; + directionSuffix VARCHAR; + state VARCHAR; + location VARCHAR; + tempString VARCHAR; + tempInt VARCHAR; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''geocode_address_countysub_exact()''; + END IF; + -- The first step is to determine what weve been given, and if its enough. + IF $1 IS NOT NULL THEN + -- The cursor was not provided. No matter, we can use an unnamed one. + result := $1; + END IF; + IF $2 IS NULL THEN + -- The address is manditory. + -- Without it, wed be wandering into strangers homes all the time. + RAISE EXCEPTION ''geocode_address_countysub_exact() - No address provided!''; + ELSE + address := $2; + END IF; + IF $3 IS NOT NULL THEN + -- The direction prefix really isnt important. + -- It will be used for rating if provided. + directionPrefix := $3; + END IF; + IF $4 IS NULL THEN + -- A street name must be given. Think about it. + RAISE EXCEPTION ''geocode_address_countysub_exact() - No street name provided!''; + ELSE + streetName := $4; + END IF; + IF $5 IS NOT NULL THEN + -- A street type will be used for rating if provided, but isnt required. + streetTypeAbbrev := $5; + END IF; + IF $6 IS NOT NULL THEN + -- Same as direction prefix, only later. + directionSuffix := $6; + END IF; + IF $7 IS NULL THEN + -- location is manditory. This is the location geocoder after all. + RAISE EXCEPTION ''geocode_address_countysub_exact() - No location provided!''; + ELSE + location := $7; + END IF; + IF $8 IS NOT NULL THEN + state := $8; + END IF; + + -- Check to see if the road name can be matched. + IF state IS NOT NULL THEN + SELECT INTO tempInt count(*) FROM tiger_geocode_roads + WHERE location = tiger_geocode_roads.cousub + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state; + ELSE + SELECT INTO tempInt count(*) FROM tiger_geocode_roads + WHERE location = tiger_geocode_roads.cousub + AND soundex(streetName) = soundex(tiger_geocode_roads.fename); + END IF; + IF verbose THEN + RAISE NOTICE ''geocode_address_countysub_exact() - % potential matches.'', tempInt; + END IF; + IF tempInt = 0 THEN + RETURN NULL; + ELSE + -- The road name matches, now we check to see if the addresses match + IF state IS NOT NULL THEN + SELECT INTO tempInt count(*) + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs) as rating + FROM tiger_geocode_roads + WHERE location = tiger_geocode_roads.cousub + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid; + ELSE + SELECT INTO tempInt count(*) + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs) as rating + FROM tiger_geocode_roads + WHERE location = tiger_geocode_roads.cousub + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid; + END IF; + IF verbose THEN + RAISE NOTICE ''geocode_address_countysub_exact() - % address matches.'', tempInt; + END IF; + IF tempInt = 0 THEN + return NULL; + ELSE + IF state IS NOT NULL THEN + OPEN result FOR + SELECT *, interpolate_from_address(address, roads_local.fraddl, + roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, + roads_local.geom) as address_geom + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs, location, + tiger_geocode_roads.cousub) as rating + FROM tiger_geocode_roads + WHERE location = tiger_geocode_roads.cousub + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid + ORDER BY subquery.rating; + return result; + ELSE + OPEN result FOR + SELECT *, interpolate_from_address(address, roads_local.fraddl, + roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, + roads_local.geom) as address_geom + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs, location, + tiger_geocode_roads.cousub) as rating + FROM tiger_geocode_roads + WHERE location = tiger_geocode_roads.cousub + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid + ORDER BY subquery.rating; + RETURN result; + END IF; + END IF; + END IF; +END; +' LANGUAGE plpgsql; + + +CREATE OR REPLACE FUNCTION geocode_address_countysub_fuzzy(REFCURSOR, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS REFCURSOR +AS ' +DECLARE + result REFCURSOR; + address INTEGER; + directionPrefix VARCHAR; + streetName VARCHAR; + streetTypeAbbrev VARCHAR; + directionSuffix VARCHAR; + state VARCHAR; + location VARCHAR; + tempString VARCHAR; + tempInt VARCHAR; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''geocode_address_countysub_fuzzy()''; + END IF; + -- The first step is to determine what weve been given, and if its enough. + IF $1 IS NOT NULL THEN + -- The cursor was not provided. No matter, we can use an unnamed one. + result := $1; + END IF; + IF $2 IS NULL THEN + -- The address is manditory. + -- Without it, wed be wandering into strangers homes all the time. + RAISE EXCEPTION ''geocode_address_countysub_fuzzy() - No address provided!''; + ELSE + address := $2; + END IF; + IF $3 IS NOT NULL THEN + -- The direction prefix really isnt important. + -- It will be used for rating if provided. + directionPrefix := $3; + END IF; + IF $4 IS NULL THEN + -- A street name must be given. Think about it. + RAISE EXCEPTION ''geocode_address_countysub_fuzzy() - No street name provided!''; + ELSE + streetName := $4; + END IF; + IF $5 IS NOT NULL THEN + -- A street type will be used for rating if provided, but isnt required. + streetTypeAbbrev := $5; + END IF; + IF $6 IS NOT NULL THEN + -- Same as direction prefix, only later. + directionSuffix := $6; + END IF; + IF $7 IS NULL THEN + -- location is manditory. This is the location geocoder after all. + RAISE EXCEPTION ''geocode_address_countysub_fuzzy() - No location provided!''; + ELSE + location := $7; + END IF; + IF $8 IS NOT NULL THEN + state := $8; + END IF; + + -- Check to see if the road name can be matched. + IF state IS NOT NULL THEN + SELECT INTO tempInt count(*) FROM tiger_geocode_roads + WHERE soundex(location) = soundex(tiger_geocode_roads.cousub) + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state; + ELSE + SELECT INTO tempInt count(*) FROM tiger_geocode_roads + WHERE soundex(location) = soundex(tiger_geocode_roads.cousub) + AND soundex(streetName) = soundex(tiger_geocode_roads.fename); + END IF; + IF verbose THEN + RAISE NOTICE ''geocode_address_countysub_fuzzy() - % potential matches.'', tempInt; + END IF; + IF tempInt = 0 THEN + RETURN NULL; + ELSE + -- The road name matches, now we check to see if the addresses match + IF state IS NOT NULL THEN + SELECT INTO tempInt count(*) + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs) as rating + FROM tiger_geocode_roads + WHERE soundex(location) = soundex(tiger_geocode_roads.cousub) + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid; + ELSE + SELECT INTO tempInt count(*) + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs) as rating + FROM tiger_geocode_roads + WHERE soundex(location) = soundex(tiger_geocode_roads.cousub) + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid; + END IF; + IF verbose THEN + RAISE NOTICE ''geocode_address_countysub_fuzzy() - % address matches.'', tempInt; + END IF; + IF tempInt = 0 THEN + return NULL; + ELSE + IF state IS NOT NULL THEN + OPEN result FOR + SELECT *, interpolate_from_address(address, roads_local.fraddl, + roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, + roads_local.geom) as address_geom + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs, location, + tiger_geocode_roads.cousub) as rating + FROM tiger_geocode_roads + WHERE soundex(location) = soundex(tiger_geocode_roads.cousub) + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid + ORDER BY subquery.rating; + return result; + ELSE + OPEN result FOR + SELECT *, interpolate_from_address(address, roads_local.fraddl, + roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, + roads_local.geom) as address_geom + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs, location, + tiger_geocode_roads.cousub) as rating + FROM tiger_geocode_roads + WHERE soundex(location) = soundex(tiger_geocode_roads.cousub) + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid + ORDER BY subquery.rating; + RETURN result; + END IF; + END IF; + END IF; +END; +' LANGUAGE plpgsql; + + +CREATE OR REPLACE FUNCTION geocode_address_place_exact(REFCURSOR, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS REFCURSOR +AS ' +DECLARE + result REFCURSOR; + address INTEGER; + directionPrefix VARCHAR; + streetName VARCHAR; + streetTypeAbbrev VARCHAR; + directionSuffix VARCHAR; + state VARCHAR; + location VARCHAR; + tempString VARCHAR; + tempInt VARCHAR; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''geocode_address_place_exact()''; + END IF; + -- The first step is to determine what weve been given, and if its enough. + IF $1 IS NOT NULL THEN + -- The cursor was not provided. No matter, we can use an unnamed one. + result := $1; + END IF; + IF $2 IS NULL THEN + -- The address is manditory. + -- Without it, wed be wandering into strangers homes all the time. + RAISE EXCEPTION ''geocode_address_place_exact() - No address provided!''; + ELSE + address := $2; + END IF; + IF $3 IS NOT NULL THEN + -- The direction prefix really isnt important. + -- It will be used for rating if provided. + directionPrefix := $3; + END IF; + IF $4 IS NULL THEN + -- A street name must be given. Think about it. + RAISE EXCEPTION ''geocode_address_place_exact() - No street name provided!''; + ELSE + streetName := $4; + END IF; + IF $5 IS NOT NULL THEN + -- A street type will be used for rating if provided, but isnt required. + streetTypeAbbrev := $5; + END IF; + IF $6 IS NOT NULL THEN + -- Same as direction prefix, only later. + directionSuffix := $6; + END IF; + IF $7 IS NULL THEN + -- location is manditory. This is the location geocoder after all. + RAISE EXCEPTION ''geocode_address_place_exact() - No location provided!''; + ELSE + location := $7; + END IF; + IF $8 IS NOT NULL THEN + state := $8; + END IF; + + -- Check to see if the road name can be matched. + IF state IS NOT NULL THEN + SELECT INTO tempInt count(*) FROM tiger_geocode_roads + WHERE location = tiger_geocode_roads.place + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state; + ELSE + SELECT INTO tempInt count(*) FROM tiger_geocode_roads + WHERE location = tiger_geocode_roads.place + AND soundex(streetName) = soundex(tiger_geocode_roads.fename); + END IF; + IF verbose THEN + RAISE NOTICE ''geocode_address_place_exact() - % potential matches.'', tempInt; + END IF; + IF tempInt = 0 THEN + RETURN NULL; + ELSE + -- The road name matches, now we check to see if the addresses match + IF state IS NOT NULL THEN + SELECT INTO tempInt count(*) + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs) as rating + FROM tiger_geocode_roads + WHERE location = tiger_geocode_roads.place + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid; + ELSE + SELECT INTO tempInt count(*) + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs) as rating + FROM tiger_geocode_roads + WHERE location = tiger_geocode_roads.place + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid; + END IF; + IF verbose THEN + RAISE NOTICE ''geocode_address_place_exact() - % address matches.'', tempInt; + END IF; + IF tempInt = 0 THEN + return NULL; + ELSE + IF state IS NOT NULL THEN + OPEN result FOR + SELECT *, interpolate_from_address(address, roads_local.fraddl, + roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, + roads_local.geom) as address_geom + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs, location, + tiger_geocode_roads.place) as rating + FROM tiger_geocode_roads + WHERE location = tiger_geocode_roads.place + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid + ORDER BY subquery.rating; + return result; + ELSE + OPEN result FOR + SELECT *, interpolate_from_address(address, roads_local.fraddl, + roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, + roads_local.geom) as address_geom + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs, location, + tiger_geocode_roads.place) as rating + FROM tiger_geocode_roads + WHERE location = tiger_geocode_roads.place + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid + ORDER BY subquery.rating; + RETURN result; + END IF; + END IF; + END IF; +END; +' LANGUAGE plpgsql; + + + +CREATE OR REPLACE FUNCTION geocode_address_place_fuzzy(REFCURSOR, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS REFCURSOR +AS ' +DECLARE + result REFCURSOR; + address INTEGER; + directionPrefix VARCHAR; + streetName VARCHAR; + streetTypeAbbrev VARCHAR; + directionSuffix VARCHAR; + state VARCHAR; + location VARCHAR; + tempString VARCHAR; + tempInt VARCHAR; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''geocode_address_place_fuzzy()''; + END IF; + -- The first step is to determine what weve been given, and if its enough. + IF $1 IS NOT NULL THEN + -- The cursor was not provided. No matter, we can use an unnamed one. + result := $1; + END IF; + IF $2 IS NULL THEN + -- The address is manditory. + -- Without it, wed be wandering into strangers homes all the time. + RAISE EXCEPTION ''geocode_address_place_fuzzy() - No address provided!''; + ELSE + address := $2; + END IF; + IF $3 IS NOT NULL THEN + -- The direction prefix really isnt important. + -- It will be used for rating if provided. + directionPrefix := $3; + END IF; + IF $4 IS NULL THEN + -- A street name must be given. Think about it. + RAISE EXCEPTION ''geocode_address_place_fuzzy() - No street name provided!''; + ELSE + streetName := $4; + END IF; + IF $5 IS NOT NULL THEN + -- A street type will be used for rating if provided, but isnt required. + streetTypeAbbrev := $5; + END IF; + IF $6 IS NOT NULL THEN + -- Same as direction prefix, only later. + directionSuffix := $6; + END IF; + IF $7 IS NULL THEN + -- location is manditory. This is the location geocoder after all. + RAISE EXCEPTION ''geocode_address_place_fuzzy() - No location provided!''; + ELSE + location := $7; + END IF; + IF $8 IS NOT NULL THEN + state := $8; + END IF; + + -- Check to see if the road name can be matched. + IF state IS NOT NULL THEN + SELECT INTO tempInt count(*) FROM tiger_geocode_roads + WHERE soundex(location) = soundex(tiger_geocode_roads.place) + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state; + ELSE + SELECT INTO tempInt count(*) FROM tiger_geocode_roads + WHERE soundex(location) = soundex(tiger_geocode_roads.place) + AND soundex(streetName) = soundex(tiger_geocode_roads.fename); + END IF; + IF verbose THEN + RAISE NOTICE ''geocode_address_place_fuzzy() - % potential matches.'', tempInt; + END IF; + IF tempInt = 0 THEN + RETURN NULL; + ELSE + -- The road name matches, now we check to see if the addresses match + IF state IS NOT NULL THEN + SELECT INTO tempInt count(*) + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs) as rating + FROM tiger_geocode_roads + WHERE soundex(location) = soundex(tiger_geocode_roads.place) + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid; + ELSE + SELECT INTO tempInt count(*) + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs) as rating + FROM tiger_geocode_roads + WHERE soundex(location) = soundex(tiger_geocode_roads.place) + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid; + END IF; + IF verbose THEN + RAISE NOTICE ''geocode_address_place_fuzzy() - % address matches.'', tempInt; + END IF; + IF tempInt = 0 THEN + return NULL; + ELSE + IF state IS NOT NULL THEN + OPEN result FOR + SELECT *, interpolate_from_address(address, roads_local.fraddl, + roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, + roads_local.geom) as address_geom + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs, location, + tiger_geocode_roads.place) as rating + FROM tiger_geocode_roads + WHERE soundex(location) = soundex(tiger_geocode_roads.place) + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid + ORDER BY subquery.rating; + return result; + ELSE + OPEN result FOR + SELECT *, interpolate_from_address(address, roads_local.fraddl, + roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, + roads_local.geom) as address_geom + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs, location, + tiger_geocode_roads.place) as rating + FROM tiger_geocode_roads + WHERE soundex(location) = soundex(tiger_geocode_roads.place) + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid + ORDER BY subquery.rating; + RETURN result; + END IF; + END IF; + END IF; +END; +' LANGUAGE plpgsql; + + + +CREATE OR REPLACE FUNCTION geocode_address_state(REFCURSOR, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS REFCURSOR +AS ' +DECLARE + result REFCURSOR; + address INTEGER; + directionPrefix VARCHAR; + streetName VARCHAR; + streetTypeAbbrev VARCHAR; + directionSuffix VARCHAR; + state VARCHAR; + tempString VARCHAR; + tempInt VARCHAR; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''geocode_address_state()''; + END IF; + -- The first step is to determine what weve been given, and if its enough. + IF $1 IS NOT NULL THEN + -- The cursor was not provided. No matter, we can use an unnamed one. + result := $1; + END IF; + IF $2 IS NULL THEN + -- The address is manditory. + -- Without it, wed be wandering into strangers homes all the time. + RAISE EXCEPTION ''geocode_address_state() - No address provided!''; + ELSE + address := $2; + END IF; + IF $3 IS NOT NULL THEN + -- The direction prefix really isnt important. + -- It will be used for rating if provided. + directionPrefix := $3; + END IF; + IF $4 IS NULL THEN + -- A street name must be given. Think about it. + RAISE EXCEPTION ''geocode_address_state() - No street name provided!''; + ELSE + streetName := $4; + END IF; + IF $5 IS NOT NULL THEN + -- A street type will be used for rating if provided, but isnt required. + streetTypeAbbrev := $5; + END IF; + IF $6 IS NOT NULL THEN + -- Same as direction prefix, only later. + directionSuffix := $6; + END IF; + IF $7 IS NOT NULL THEN + state := $7; + ELSE + -- It is unreasonable to do a country wide search. State is already + -- pretty sketchy. No state, no search. + RAISE EXCEPTION ''geocode_address_state() - No state name provided!''; + END IF; + + -- Check to see if the road name can be matched. + SELECT INTO tempInt count(*) FROM tiger_geocode_roads + WHERE soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state; + IF verbose THEN + RAISE NOTICE ''geocode_address_state() - % potential matches.'', tempInt; + END IF; + IF tempInt = 0 THEN + RETURN NULL; + ELSE + -- The road name matches, now we check to see if the addresses match + SELECT INTO tempInt count(*) + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs) as rating + FROM tiger_geocode_roads + WHERE soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid; + IF verbose THEN + RAISE NOTICE ''geocode_address_state() - % address matches.'', tempInt; + END IF; + IF tempInt = 0 THEN + return NULL; + ELSE + OPEN result FOR + SELECT *, interpolate_from_address(address, roads_local.fraddl, + roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, + roads_local.geom) as address_geom + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs) as rating + FROM tiger_geocode_roads + WHERE soundex(streetName) = soundex(tiger_geocode_roads.fename) + AND state = tiger_geocode_roads.state + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid + ORDER BY subquery.rating; + return result; + END IF; + END IF; +END; +' LANGUAGE plpgsql; + + + +CREATE OR REPLACE FUNCTION geocode_address_zip(REFCURSOR, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, INTEGER) RETURNS REFCURSOR +AS ' +DECLARE + result REFCURSOR; + address INTEGER; + directionPrefix VARCHAR; + streetName VARCHAR; + streetTypeAbbrev VARCHAR; + directionSuffix VARCHAR; + zipCode INTEGER; + tempString VARCHAR; + tempInt VARCHAR; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''geocode_address_zip()''; + END IF; + -- The first step is to determine what weve been given, and if its enough. + IF $1 IS NOT NULL THEN + -- The cursor was not provided. No matter, we can use an unnamed one. + result := $1; + END IF; + IF $2 IS NULL THEN + -- The address is manditory. + -- Without it, wed be wandering into strangers homes all the time. + RAISE EXCEPTION ''geocode_address_zip() - No address provided!''; + ELSE + address := $2; + END IF; + IF $3 IS NOT NULL THEN + -- The direction prefix really isnt important. + -- It will be used for rating if provided. + directionPrefix := $3; + END IF; + IF $4 IS NULL THEN + -- A street name must be given. Think about it. + RAISE EXCEPTION ''geocode_address_zip() - No street name provided!''; + ELSE + streetName := $4; + END IF; + IF $5 IS NOT NULL THEN + -- A street type will be used for rating if provided, but isnt required. + streetTypeAbbrev := $5; + END IF; + IF $6 IS NOT NULL THEN + -- Same as direction prefix, only later. + directionSuffix := $6; + END IF; + IF $7 IS NULL THEN + -- Zip code is not optional. + RAISE EXCEPTION ''geocode_address_zip() - No zip provided!''; + ELSE + zipCode := $7; + END IF; + + -- Check to see if the road name can be matched. + SELECT INTO tempInt count(*) FROM tiger_geocode_roads + WHERE zipCode = tiger_geocode_roads.zip + AND soundex(streetName) = soundex(tiger_geocode_roads.fename); + IF tempInt = 0 THEN + return NULL; + ELSE + -- The road name matches, now we check to see if the addresses match + SELECT INTO tempInt count(*) + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs) as rating + FROM tiger_geocode_roads + WHERE zipCode = tiger_geocode_roads.zip + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid; + IF tempInt = 0 THEN + return NULL; + ELSE + OPEN result FOR + SELECT *, interpolate_from_address(address, roads_local.fraddl, + roads_local.toaddl, roads_local.fraddr, roads_local.toaddr, + roads_local.geom) as address_geom + FROM ( + SELECT *, rate_attributes(directionPrefix, tiger_geocode_roads.fedirp, + streetName, tiger_geocode_roads.fename, streetTypeAbbrev, + tiger_geocode_roads.fetype, directionSuffix, + tiger_geocode_roads.fedirs) as rating + FROM tiger_geocode_roads + WHERE zipCode = tiger_geocode_roads.zip + AND soundex(streetName) = soundex(tiger_geocode_roads.fename) + ) AS subquery, tiger_geocode_join, roads_local + WHERE includes_address(address, roads_local.fraddl, roads_local.toaddl, + roads_local.fraddr, roads_local.toaddr) + AND subquery.id = tiger_geocode_join.id + AND tiger_geocode_join.tlid = roads_local.tlid + ORDER BY subquery.rating; + return result; + END IF; + END IF; +END; +' LANGUAGE plpgsql; + + + +-- Returns a string consisting of the last N words. Words are allowed +-- to be seperated only by spaces, but multiple spaces between +-- words are allowed. Words must be alphanumberic. +-- If more words are requested than exist, the full input string is +-- returned. +CREATE OR REPLACE FUNCTION get_last_words(VARCHAR, INTEGER) RETURNS VARCHAR +AS ' +DECLARE + inputString VARCHAR; + tempString VARCHAR; + count VARCHAR; + result VARCHAR := ''''; +BEGIN + IF $1 IS NULL THEN + return NULL; + ELSE + inputString := $1; + END IF; + IF $2 IS NULL THEN + RAISE EXCEPTION ''get_last_words() - word count is null!''; + ELSE + count := $2; + END IF; + FOR i IN 1..count LOOP + tempString := substring(inputString from ''((?: )+[a-zA-Z0-9_]*)'' || result || ''$''); + IF tempString IS NULL THEN + return inputString; + END IF; + result := tempString || result; + END LOOP; + result := trim(both from result); + return result; +END; +' LANGUAGE plpgsql; + + + +-- This function converts the string addresses to integers and passes them +-- to the other includes_address function. +CREATE OR REPLACE FUNCTION includes_address(INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS BOOLEAN +AS ' +DECLARE + given_address INTEGER; + addr1 INTEGER; + addr2 INTEGER; + addr3 INTEGER; + addr4 INTEGER; + result BOOLEAN; +BEGIN + given_address = $1; + addr1 = to_number($2, ''999999''); + addr2 = to_number($3, ''999999''); + addr3 = to_number($4, ''999999''); + addr4 = to_number($5, ''999999''); + result = includes_address(given_address, addr1, addr2, addr3, addr4); + RETURN result; +END +' LANGUAGE plpgsql; + + + +-- This function requires the addresses to be grouped, such that the second and +-- third arguments are from one side of the street, and the fourth and fifth +-- from the other. +CREATE OR REPLACE FUNCTION includes_address(INTEGER, INTEGER, INTEGER, INTEGER, INTEGER) RETURNS BOOLEAN +AS ' +DECLARE + given_address INTEGER; + addr1 INTEGER; + addr2 INTEGER; + addr3 INTEGER; + addr4 INTEGER; + lmaxaddr INTEGER := -1; + rmaxaddr INTEGER := -1; + lminaddr INTEGER := -1; + rminaddr INTEGER := -1; + maxaddr INTEGER := -1; + minaddr INTEGER := -1; +BEGIN + IF $1 IS NULL THEN + RAISE EXCEPTION ''includes_address() - local address is NULL!''; + ELSE + given_address := $1; + END IF; + + IF $2 IS NOT NULL THEN + addr1 := $2; + maxaddr := addr1; + minaddr := addr1; + lmaxaddr := addr1; + lminaddr := addr1; + END IF; + + IF $3 IS NOT NULL THEN + addr2 := $3; + IF addr2 < minaddr OR minaddr = -1 THEN + minaddr := addr2; + END IF; + IF addr2 > maxaddr OR maxaddr = -1 THEN + maxaddr := addr2; + END IF; + IF addr2 > lmaxaddr OR lmaxaddr = -1 THEN + lmaxaddr := addr2; + END IF; + IF addr2 < lminaddr OR lminaddr = -1 THEN + lminaddr := addr2; + END IF; + END IF; + + IF $4 IS NOT NULL THEN + addr3 := $4; + IF addr3 < minaddr OR minaddr = -1 THEN + minaddr := addr3; + END IF; + IF addr3 > maxaddr OR maxaddr = -1 THEN + maxaddr := addr3; + END IF; + rmaxaddr := addr3; + rminaddr := addr3; + END IF; + + IF $5 IS NOT NULL THEN + addr4 := $5; + IF addr4 < minaddr OR minaddr = -1 THEN + minaddr := addr4; + END IF; + IF addr4 > maxaddr OR maxaddr = -1 THEN + maxaddr := addr4; + END IF; + IF addr4 > rmaxaddr OR rmaxaddr = -1 THEN + rmaxaddr := addr4; + END IF; + IF addr4 < rminaddr OR rminaddr = -1 THEN + rminaddr := addr4; + END IF; + END IF; + + IF minaddr = -1 OR maxaddr = -1 THEN + -- No addresses were non-null, return FALSE (arbitrary) + RETURN FALSE; + ELSIF given_address >= minaddr AND given_address <= maxaddr THEN + -- The address is within the given range + IF given_address >= lminaddr AND given_address <= lmaxaddr THEN + -- This checks to see if the address is on this side of the + -- road, ie if the address is even, the street range must be even + IF (given_address % 2) = (lminaddr % 2) + OR (given_address % 2) = (lmaxaddr % 2) THEN + RETURN TRUE; + END IF; + END IF; + IF given_address >= rminaddr AND given_address <= rmaxaddr THEN + -- See above + IF (given_address % 2) = (rminaddr % 2) + OR (given_address % 2) = (rmaxaddr % 2) THEN + RETURN TRUE; + END IF; + END IF; + END IF; + -- The address is not within the range + RETURN FALSE; +END; + +' LANGUAGE plpgsql; + + + +-- This function converts string addresses to integers and passes them to +-- the other interpolate_from_address function. +CREATE OR REPLACE FUNCTION interpolate_from_address(INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, GEOMETRY) RETURNS GEOMETRY +AS ' +DECLARE + given_address INTEGER; + addr1 INTEGER; + addr2 INTEGER; + addr3 INTEGER; + addr4 INTEGER; + road GEOMETRY; + result GEOMETRY; +BEGIN + given_address := $1; + addr1 := to_number($2, ''999999''); + addr2 := to_number($3, ''999999''); + addr3 := to_number($4, ''999999''); + addr4 := to_number($5, ''999999''); + road := $6; + result = interpolate_from_address(given_address, addr1, addr2, addr3, addr4, road); + RETURN result; +END +' LANGUAGE plpgsql; + +-- interpolate_from_address(local_address, from_address_l, to_address_l, from_address_r, to_address_r, local_road) +-- This function returns a point along the given geometry (must be linestring) +-- corresponding to the given address. If the given address is not within +-- the address range of the road, null is returned. +-- This function requires that the address be grouped, such that the second and +-- third arguments are from one side of the street, while the fourth and +-- fifth are from the other. +CREATE OR REPLACE FUNCTION interpolate_from_address(INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, GEOMETRY) RETURNS GEOMETRY +AS ' +DECLARE + given_address INTEGER; + lmaxaddr INTEGER := -1; + rmaxaddr INTEGER := -1; + lminaddr INTEGER := -1; + rminaddr INTEGER := -1; + lfrgreater BOOLEAN; + rfrgreater BOOLEAN; + frgreater BOOLEAN; + addrwidth INTEGER; + part DOUBLE PRECISION; + road GEOMETRY; + result GEOMETRY; +BEGIN + IF $1 IS NULL THEN + RAISE EXCEPTION ''interpolate_from_address() - local address is NULL!''; + ELSE + given_address := $1; + END IF; + + IF $6 IS NULL THEN + RAISE EXCEPTION ''interpolate_from_address() - local road is NULL!''; + ELSE + IF geometrytype($6) = ''LINESTRING'' THEN + road := $6; + ELSIF geometrytype($6) = ''MULTILINESTRING'' THEN + road := geometryn($6,1); + ELSE + RAISE EXCEPTION ''interpolate_from_address() - local road is not a line!''; + END IF; + END IF; + + IF $2 IS NOT NULL THEN + lfrgreater := TRUE; + lmaxaddr := $2; + lminaddr := $2; + END IF; + + IF $3 IS NOT NULL THEN + IF $3 > lmaxaddr OR lmaxaddr = -1 THEN + lmaxaddr := $3; + lfrgreater := FALSE; + END IF; + IF $3 < lminaddr OR lminaddr = -1 THEN + lminaddr := $3; + END IF; + END IF; + + IF $4 IS NOT NULL THEN + rmaxaddr := $4; + rminaddr := $4; + rfrgreater := TRUE; + END IF; + + IF $5 IS NOT NULL THEN + IF $5 > rmaxaddr OR rmaxaddr = -1 THEN + rmaxaddr := $5; + rfrgreater := FALSE; + END IF; + IF $5 < rminaddr OR rminaddr = -1 THEN + rminaddr := $5; + END IF; + END IF; + + IF given_address >= lminaddr AND given_address <= lmaxaddr THEN + IF (given_address % 2) = (lminaddr % 2) + OR (given_address % 2) = (lmaxaddr % 2) THEN + addrwidth := lmaxaddr - lminaddr; + part := (given_address - lminaddr) / trunc(addrwidth, 1); + frgreater := lfrgreater; + END IF; + END IF; + IF given_address >= rminaddr AND given_address <= rmaxaddr THEN + IF (given_address % 2) = (rminaddr % 2) + OR (given_address % 2) = (rmaxaddr % 2) THEN + addrwidth := rmaxaddr - rminaddr; + part := (given_address - rminaddr) / trunc(addrwidth, 1); + frgreater := rfrgreater; + END IF; + ELSE + RETURN null; + END IF; + + IF frgreater THEN + part := 1 - part; + END IF; + + result = line_interpolate_point(road, part); + RETURN result; +END; +' LANGUAGE plpgsql; + + +-- This function determines the levenshtein distance irespective of case. +CREATE OR REPLACE FUNCTION levenshtein_ignore_case(VARCHAR, VARCHAR) RETURNS INTEGER +AS ' +DECLARE + result INTEGER; +BEGIN + result := levenshtein(upper($1), upper($2)); + RETURN result; +END +' LANGUAGE plpgsql; + +-- This function take two arguements. The first is the "given string" and +-- must not be null. The second arguement is the "compare string" and may +-- or may not be null. If the second string is null, the value returned is +-- 3, otherwise it is the levenshtein difference between the two. +CREATE OR REPLACE FUNCTION nullable_levenshtein(VARCHAR, VARCHAR) RETURNS INTEGER +AS ' +DECLARE + given_string VARCHAR; + result INTEGER := 3; +BEGIN + IF $1 IS NULL THEN + RAISE EXCEPTION ''nullable_levenshtein - given string is NULL!''; + ELSE + given_string := $1; + END IF; + + IF $2 IS NOT NULL AND $2 != '''' THEN + result := levenshtein_ignore_case(given_string, $2); + END IF; + + RETURN result; +END +' LANGUAGE plpgsql; + + + +-- location_extract(streetAddressString, stateAbbreviation) +-- This function extracts a location name from the end of the given string. +-- The first attempt is to find an exact match against the place_lookup +-- table. If this fails, a word-by-word soundex match is tryed against the +-- same table. If multiple candidates are found, the one with the smallest +-- levenshtein distance from the given string is assumed the correct one. +-- If no match is found against the place_lookup table, the same tests are +-- run against the countysub_lookup table. +-- +-- The section of the given string corresponding to the location found is +-- returned, rather than the string found from the tables. All the searching +-- is done largely to determine the length (words) of the location, to allow +-- the intended street name to be correctly identified. +CREATE OR REPLACE FUNCTION location_extract(VARCHAR, VARCHAR) RETURNS VARCHAR +AS ' +DECLARE + fullStreet VARCHAR; + stateAbbrev VARCHAR; + location VARCHAR; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''location_extract()''; + END IF; + IF $1 IS NULL THEN + RAISE EXCEPTION ''location_extract() - No input given!''; + ELSE + fullStreet := $1; + END IF; + IF $2 IS NULL THEN + ELSE + stateAbbrev := $2; + END IF; + location := location_extract_place_exact(fullStreet, stateAbbrev); + IF location IS NULL THEN + location := location_extract_countysub_exact(fullStreet, stateAbbrev); + IF location IS NULL THEN + location := location_extract_place_fuzzy(fullStreet, stateAbbrev); + IF location IS NULL THEN + location := location_extract_countysub_fuzzy(fullStreet, stateAbbrev); + END IF; + END IF; + END IF; + return location; +END; +' LANGUAGE plpgsql; + + + +-- location_extract_countysub_exact(string, stateAbbrev) +-- This function checks the place_lookup table to find a potential match to +-- the location described at the end of the given string. If an exact match +-- fails, a fuzzy match is performed. The location as found in the given +-- string is returned. +CREATE OR REPLACE FUNCTION location_extract_countysub_exact(VARCHAR, VARCHAR) RETURNS VARCHAR +AS ' +DECLARE + fullStreet VARCHAR; + ws VARCHAR; + tempString VARCHAR; + location VARCHAR; + tempInt INTEGER; + word_count INTEGER; + stateAbbrev VARCHAR; + rec RECORD; + test BOOLEAN; + result VARCHAR; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''location_extract_countysub_exact()''; + END IF; + IF $1 IS NULL THEN + RAISE EXCEPTION ''location_extract_countysub_exact() - No input given!''; + ELSE + fullStreet := $1; + END IF; + IF $2 IS NOT NULL THEN + stateAbbrev := $2; + END IF; + ws := ''[ ,\.\n\f\t]''; + -- No hope of determining the location from place. Try countysub. + IF stateAbbrev IS NOT NULL THEN + SELECT INTO tempInt count(*) FROM countysub_lookup + WHERE countysub_lookup.state = stateAbbrev + AND texticregexeq(fullStreet, ''(?i)'' || name || ''$''); + ELSE + SELECT INTO tempInt count(*) FROM countysub_lookup + WHERE texticregexeq(fullStreet, ''(?i)'' || name || ''$''); + END IF; + IF tempInt > 0 THEN + IF stateAbbrev IS NOT NULL THEN + FOR rec IN SELECT substring(fullStreet, ''(?i)('' + || name || '')$'') AS value, name FROM countysub_lookup + WHERE countysub_lookup.state = stateAbbrev + AND texticregexeq(fullStreet, ''(?i)'' || ws || name || + ''$'') ORDER BY length(name) DESC LOOP + -- Only the first result is needed. + location := rec.value; + EXIT; + END LOOP; + ELSE + FOR rec IN SELECT substring(fullStreet, ''(?i)('' + || name || '')$'') AS value, name FROM countysub_lookup + WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name || + ''$'') ORDER BY length(name) DESC LOOP + -- again, only the first is needed. + location := rec.value; + EXIT; + END LOOP; + END IF; + END IF; + RETURN location; +END; +' LANGUAGE plpgsql; + + +-- location_extract_countysub_fuzzy(string, stateAbbrev) +-- This function checks the place_lookup table to find a potential match to +-- the location described at the end of the given string. If an exact match +-- fails, a fuzzy match is performed. The location as found in the given +-- string is returned. +CREATE OR REPLACE FUNCTION location_extract_countysub_fuzzy(VARCHAR, VARCHAR) RETURNS VARCHAR +AS ' +DECLARE + fullStreet VARCHAR; + ws VARCHAR; + tempString VARCHAR; + location VARCHAR; + tempInt INTEGER; + word_count INTEGER; + stateAbbrev VARCHAR; + rec RECORD; + test BOOLEAN; + result VARCHAR; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''location_extract_countysub_fuzzy()''; + END IF; + IF $1 IS NULL THEN + RAISE EXCEPTION ''location_extract_countysub_fuzzy() - No input given!''; + ELSE + fullStreet := $1; + END IF; + IF $2 IS NOT NULL THEN + stateAbbrev := $2; + END IF; + ws := ''[ ,\.\n\f\t]''; + + -- Fuzzy matching. + tempString := substring(fullStreet, ''(?i)'' || ws || + ''([a-zA-Z0-9]+)$''); + IF tempString IS NULL THEN + tempString := fullStreet; + END IF; + IF stateAbbrev IS NOT NULL THEN + SELECT INTO tempInt count(*) FROM countysub_lookup + WHERE countysub_lookup.state = stateAbbrev + AND soundex(tempString) = end_soundex(name); + ELSE + SELECT INTO tempInt count(*) FROM countysub_lookup + WHERE soundex(tempString) = end_soundex(name); + END IF; + IF tempInt > 0 THEN + tempInt := 50; + -- Some potentials were found. Begin a word-by-word soundex on each. + IF stateAbbrev IS NOT NULL THEN + FOR rec IN SELECT name FROM countysub_lookup + WHERE countysub_lookup.state = stateAbbrev + AND soundex(tempString) = end_soundex(name) LOOP + word_count := count_words(rec.name); + test := TRUE; + tempString := get_last_words(fullStreet, word_count); + FOR i IN 1..word_count LOOP + IF soundex(split_part(tempString, '' '', i)) != + soundex(split_part(rec.name, '' '', i)) THEN + test := FALSE; + END IF; + END LOOP; + IF test THEN + -- The soundex matched, determine if the distance is better. + IF levenshtein_ignore_case(rec.name, tempString) < tempInt THEN + location := tempString; + tempInt := levenshtein_ignore_case(rec.name, tempString); + END IF; + END IF; + END LOOP; + ELSE + FOR rec IN SELECT name FROM countysub_lookup + WHERE soundex(tempString) = end_soundex(name) LOOP + word_count := count_words(rec.name); + test := TRUE; + tempString := get_last_words(fullStreet, word_count); + FOR i IN 1..word_count LOOP + IF soundex(split_part(tempString, '' '', i)) != + soundex(split_part(rec.name, '' '', i)) THEN + test := FALSE; + END IF; + END LOOP; + IF test THEN + -- The soundex matched, determine if the distance is better. + IF levenshtein_ignore_case(rec.name, tempString) < tempInt THEN + location := tempString; + tempInt := levenshtein_ignore_case(rec.name, tempString); + END IF; + END IF; + END LOOP; + END IF; + END IF; -- If no fuzzys were found, leave location null. + RETURN location; +END; +' LANGUAGE plpgsql; + + + +-- location_extract_place_exact(string, stateAbbrev) +-- This function checks the place_lookup table to find a potential match to +-- the location described at the end of the given string. If an exact match +-- fails, a fuzzy match is performed. The location as found in the given +-- string is returned. +CREATE OR REPLACE FUNCTION location_extract_place_exact(VARCHAR, VARCHAR) RETURNS VARCHAR +AS ' +DECLARE + fullStreet VARCHAR; + ws VARCHAR; + tempString VARCHAR; + location VARCHAR; + tempInt INTEGER; + word_count INTEGER; + stateAbbrev VARCHAR; + rec RECORD; + test BOOLEAN; + result VARCHAR; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''location_extract_place_exact()''; + END IF; + IF $1 IS NULL THEN + RAISE EXCEPTION ''location_extract_place_exact() - No input given!''; + ELSE + fullStreet := $1; + END IF; + IF verbose THEN + RAISE NOTICE ''location_extract_place_exact() - input: "%"'', fullStreet; + END IF; + IF $2 IS NOT NULL THEN + stateAbbrev := $2; + END IF; + ws := ''[ ,\.\n\f\t]''; + -- Try for an exact match against places + IF stateAbbrev IS NOT NULL THEN + SELECT INTO tempInt count(*) FROM place_lookup + WHERE place_lookup.state = stateAbbrev + AND texticregexeq(fullStreet, ''(?i)'' || name || ''$''); + ELSE + SELECT INTO tempInt count(*) FROM place_lookup + WHERE texticregexeq(fullStreet, ''(?i)'' || name || ''$''); + END IF; + IF verbose THEN + RAISE NOTICE ''location_extract_place_exact() - Exact Matches %'', tempInt; + END IF; + IF tempInt > 0 THEN + -- Some matches were found. Look for the last one in the string. + IF stateAbbrev IS NOT NULL THEN + FOR rec IN SELECT substring(fullStreet, ''(?i)('' + || name || '')$'') AS value, name FROM place_lookup + WHERE place_lookup.state = stateAbbrev + AND texticregexeq(fullStreet, ''(?i)'' + || name || ''$'') ORDER BY length(name) DESC LOOP + -- Since the regex is end of string, only the longest (first) result + -- is useful. + location := rec.value; + EXIT; + END LOOP; + ELSE + FOR rec IN SELECT substring(fullStreet, ''(?i)('' + || name || '')$'') AS value, name FROM place_lookup + WHERE texticregexeq(fullStreet, ''(?i)'' + || name || ''$'') ORDER BY length(name) DESC LOOP + -- Since the regex is end of string, only the longest (first) result + -- is useful. + location := rec.value; + EXIT; + END LOOP; + END IF; + END IF; + RETURN location; +END; +' LANGUAGE plpgsql; + + + +-- location_extract_place_fuzzy(string, stateAbbrev) +-- This function checks the place_lookup table to find a potential match to +-- the location described at the end of the given string. If an exact match +-- fails, a fuzzy match is performed. The location as found in the given +-- string is returned. +CREATE OR REPLACE FUNCTION location_extract_place_fuzzy(VARCHAR, VARCHAR) RETURNS VARCHAR +AS ' +DECLARE + fullStreet VARCHAR; + ws VARCHAR; + tempString VARCHAR; + location VARCHAR; + tempInt INTEGER; + word_count INTEGER; + stateAbbrev VARCHAR; + rec RECORD; + test BOOLEAN; + result VARCHAR; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''location_extract_place_fuzzy()''; + END IF; + IF $1 IS NULL THEN + RAISE EXCEPTION ''location_extract_place_fuzzy() - No input given!''; + ELSE + fullStreet := $1; + END IF; + IF verbose THEN + RAISE NOTICE ''location_extract_place_fuzzy() - input: "%"'', fullStreet; + END IF; + IF $2 IS NOT NULL THEN + stateAbbrev := $2; + END IF; + ws := ''[ ,\.\n\f\t]''; + + tempString := substring(fullStreet, ''(?i)'' || ws + || ''([a-zA-Z0-9]+)$''); + IF tempString IS NULL THEN + tempString := fullStreet; + END IF; + IF stateAbbrev IS NOT NULL THEN + SELECT into tempInt count(*) FROM place_lookup + WHERE place_lookup.state = stateAbbrev + AND soundex(tempString) = end_soundex(name); + ELSE + SELECT into tempInt count(*) FROM place_lookup + WHERE soundex(tempString) = end_soundex(name); + END IF; + IF verbose THEN + RAISE NOTICE ''location_extract_place_fuzzy() - Fuzzy matches %'', tempInt; + END IF; + IF tempInt > 0 THEN + -- Some potentials were found. Begin a word-by-word soundex on each. + tempInt := 50; + IF stateAbbrev IS NOT NULL THEN + FOR rec IN SELECT name FROM place_lookup + WHERE place_lookup.state = stateAbbrev + AND soundex(tempString) = end_soundex(name) LOOP + IF verbose THEN + RAISE NOTICE ''location_extract_place_fuzzy() - Fuzzy: "%"'', rec.name; + END IF; + word_count := count_words(rec.name); + test := TRUE; + tempString := get_last_words(fullStreet, word_count); + FOR i IN 1..word_count LOOP + IF soundex(split_part(tempString, '' '', i)) != + soundex(split_part(rec.name, '' '', i)) THEN + IF verbose THEN + RAISE NOTICE ''location_extract_place_fuzzy() - No Match.''; + END IF; + test := FALSE; + END IF; + END LOOP; + IF test THEN + -- The soundex matched, determine if the distance is better. + IF levenshtein_ignore_case(rec.name, tempString) < tempInt THEN + location := tempString; + tempInt := levenshtein_ignore_case(rec.name, tempString); + END IF; + END IF; + END LOOP; + ELSE + FOR rec IN SELECT name FROM place_lookup + WHERE soundex(tempString) = end_soundex(name) LOOP + word_count := count_words(rec.name); + test := TRUE; + tempString := get_last_words(fullStreet, word_count); + FOR i IN 1..word_count LOOP + IF soundex(split_part(tempString, '' '', i)) != + soundex(split_part(rec.name, '' '', i)) THEN + test := FALSE; + END IF; + END LOOP; + IF test THEN + -- The soundex matched, determine if the distance is better. + IF levenshtein_ignore_case(rec.name, tempString) < tempInt THEN + location := tempString; + tempInt := levenshtein_ignore_case(rec.name, tempString); + END IF; + END IF; + END LOOP; + END IF; + END IF; + RETURN location; +END; +' LANGUAGE plpgsql; + + + +-- normalize_address(addressString) +-- This takes an address string and parses it into address (internal/street) +-- street name, type, direction prefix and suffix, location, state and +-- zip code, depending on what can be found in the string. +-- +-- The US postal address standard is used: +-- +-- +-- +-- State is assumed to be included in the string, and MUST be matchable to +-- something in the state_lookup table. Fuzzy matching is used if no direct +-- match is found. +-- +-- Two formats of zip code are acceptable: five digit, and five + 4. +-- +-- The internal addressing indicators are looked up from the +-- secondary_unit_lookup table. A following identifier is accepted +-- but it must start with a digit. +-- +-- The location is parsed from the string using other indicators, such +-- as street type, direction suffix or internal address, if available. +-- If these are not, the location is extracted using comparisons against +-- the places_lookup table, then the countysub_lookup table to determine +-- what, in the original string, is intended to be the location. In both +-- cases, an exact match is first pursued, then a word-by-word fuzzy match. +-- The result is not the name of the location from the tables, but the +-- section of the given string that corresponds to the name from the tables. +-- +-- Zip codes and street names are not validated. +-- +-- Direction indicators are extracted by comparison with the direction_lookup +-- table. +-- +-- Street addresses are assumed to be a single word, starting with a number. +-- Address is manditory; if no address is given, and the street is numbered, +-- the resulting address will be the street name, and the street name +-- will be an empty string. +-- +-- In some cases, the street type is part of the street name. +-- eg State Hwy 22a. As long as the word following the type starts with a +-- number (this is usually the case) this will be caught. Some street names +-- include a type name, and have a street type that differs. This will be +-- handled properly, so long as both are given. If the street type is +-- omitted, the street names included type will be parsed as the street type. +-- +-- The output is currently a colon seperated list of values: +-- InternalAddress:StreetAddress:DirectionPrefix:StreetName:StreetType: +-- DirectionSuffix:Location:State:ZipCode +-- This returns each element as entered. It's mainly meant for debugging. +-- There is also another option that returns: +-- StreetAddress:DirectionPrefixAbbreviation:StreetName:StreetTypeAbbreviation: +-- DirectionSuffixAbbreviation:Location:StateAbbreviation:ZipCode +-- This is more standardized and better for use with a geocoder. +CREATE OR REPLACE FUNCTION normalize_address(VARCHAR) RETURNS VARCHAR +AS ' +DECLARE + rawInput VARCHAR; + address VARCHAR; + preDir VARCHAR; + preDirAbbrev VARCHAR; + postDir VARCHAR; + postDirAbbrev VARCHAR; + fullStreet VARCHAR; + reducedStreet VARCHAR; + streetName VARCHAR; + streetType VARCHAR; + streetTypeAbbrev VARCHAR; + internal VARCHAR; + location VARCHAR; + state VARCHAR; + stateAbbrev VARCHAR; + tempString VARCHAR; + tempInt INTEGER; + result VARCHAR; + zip VARCHAR; + test BOOLEAN; + working REFCURSOR; + rec RECORD; + ws VARCHAR; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''normalize_address()''; + END IF; + IF $1 IS NULL THEN + RAISE EXCEPTION ''normalise_address() - address string is null!''; + ELSE + rawInput := $1; + END IF; + ws := ''[ ,\.\t\n\f\r]''; + + -- Assume that the address begins with a digit, and extract it from + -- the input string. + address := substring(rawInput from ''^([0-9].*?)[ ,/.]''); + + -- There are two formats for zip code, the normal 5 digit, and + -- the nine digit zip-4. It may also not exist. + zip := substring(rawInput from ws || ''([0-9]{5})$''); + IF zip IS NULL THEN + zip := substring(rawInput from ws || ''([0-9]{5})-[0-9]{4}$''); + END IF; + + IF zip IS NOT NULL THEN + fullStreet := substring(rawInput from ''(.*)'' + || ws || ''+'' || cull_null(zip) || ''[- ]?([0-9]{4})?$''); + ELSE + fullStreet := rawInput; + END IF; + IF verbose THEN + RAISE NOTICE ''normalize_address() - after zip extract "%"'', fullStreet; + END IF; + tempString := state_extract(fullStreet); + IF tempString IS NOT NULL THEN + state := split_part(tempString, '':'', 1); + stateAbbrev := split_part(tempString, '':'', 2); + END IF; + + -- The easiest case is if the address is comma delimited. There are some + -- likely cases: + -- street level, location, state + -- street level, location state + -- street level, location + -- street level, internal address, location, state + -- street level, internal address, location state + -- street level, internal address location state + -- street level, internal address, location + -- street level, internal address location + -- The first three are useful. + tempString := substring(fullStreet, ''(?i),'' || ws || ''+(.*)(,?'' || ws || + ''+'' || cull_null(state) || ''|$)''); + IF tempString IS NOT NULL THEN + location := tempString; + IF address IS NOT NULL THEN + fullStreet := substring(fullStreet, ''(?i)'' || address || ws || + ''+(.*),'' || ws || ''+'' || location); + ELSE + fullStreet := substring(fullStreet, ''(?i)(.*),'' || ws || ''+'' || + location); + END IF; + IF verbose THEN + RAISE NOTICE ''normalize_address() - Parsed by punctuation.''; + RAISE NOTICE ''normalize_address() - Location "%"'', location; + RAISE NOTICE ''normalize_address() - FullStreet "%"'', fullStreet; + END IF; + END IF; + + -- Pull out the full street information, defined as everything between the + -- address and the state. This includes the location. + -- This doesnt need to be done if location has already been found. + IF location IS NULL THEN + IF address IS NOT NULL THEN + IF state IS NOT NULL THEN + fullStreet := substring(fullStreet, ''(?i)'' || address || + ws || ''+(.*?)'' || ws || ''+'' || state); + ELSE + fullStreet := substring(fullStreet, ''(?i)'' || address || + ws || ''+(.*?)''); + END IF; + ELSE + IF state IS NOT NULL THEN + fullStreet := substring(fullStreet, ''(?i)(.*?)'' || ws || + ''+'' || state); + ELSE + fullStreet := substring(fullStreet, ''(?i)(.*?)''); + END IF; + END IF; + END IF; + IF verbose THEN + RAISE NOTICE ''normalize_address() - after addy extract "%"'', fullStreet; + END IF; + + -- Determine if any internal address is included, such as apartment + -- or suite number. + SELECT INTO tempInt count(*) FROM secondary_unit_lookup + WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name || ''('' + || ws || ''|$)''); + IF tempInt = 1 THEN + SELECT INTO internal substring(fullStreet, ''(?i)'' || ws || ''('' + || name || ws || ''*#?'' || ws + || ''*(?:[0-9][0-9a-zA-Z\-]*)?'' || '')(?:'' || ws || ''|$)'') + FROM secondary_unit_lookup + WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name || ''('' + || ws || ''|$)''); + ELSIF tempInt > 1 THEN + -- In the event of multiple matches to a secondary unit designation, we + -- will assume that the last one is the true one. + tempInt := 0; + FOR rec in SELECT trim(substring(fullStreet, ''(?i)'' || ws || ''('' + || name || ''(?:'' || ws || ''*#?'' || ws + || ''*(?:[0-9][0-9a-zA-Z\-]*)?)'' || ws || ''?|$)'')) as value + FROM secondary_unit_lookup + WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name || ''('' + || ws || ''|$)'') LOOP + IF tempInt < position(rec.value in fullStreet) THEN + tempInt := position(rec.value in fullStreet); + internal := rec.value; + END IF; + END LOOP; + END IF; + + IF verbose THEN + RAISE NOTICE ''normalize_address() - internal: "%"'', internal; + END IF; + + IF location IS NULL THEN + -- If the internal address is given, the location is everything after it. + location := substring(fullStreet, internal || ws || ''+(.*)$''); + END IF; + + -- Pull potential street types from the full street information + SELECT INTO tempInt count(*) FROM street_type_lookup + WHERE texticregexeq(fullStreet, ''(?i)'' || ws || ''('' || name + || '')(?:'' || ws || ''|$)''); + IF tempInt = 1 THEN + SELECT INTO rec abbrev, substring(fullStreet, ''(?i)'' || ws || ''('' + || name || '')(?:'' || ws || ''|$)'') AS given FROM street_type_lookup + WHERE texticregexeq(fullStreet, ''(?i)'' || ws || ''('' || name + || '')(?:'' || ws || ''|$)''); + streetType := rec.given; + streetTypeAbbrev := rec.abbrev; + ELSIF tempInt > 1 THEN + tempInt := 0; + FOR rec IN SELECT abbrev, substring(fullStreet, ''(?i)'' || ws || ''('' + || name || '')(?:'' || ws || ''|$)'') AS given FROM street_type_lookup + WHERE texticregexeq(fullStreet, ''(?i)'' || ws || ''('' || name + || '')(?:'' || ws || ''|$)'') LOOP + -- If we have found an internal address, make sure the type + -- precedes it. + IF internal IS NOT NULL THEN + IF position(rec.given IN fullStreet) < + position(internal IN fullStreet) THEN + IF tempInt < position(rec.given IN fullStreet) THEN + streetType := rec.given; + streetTypeAbbrev := rec.abbrev; + tempInt := position(rec.given IN fullStreet); + END IF; + END IF; + ELSIF tempInt < position(rec.given IN fullStreet) THEN + streetType := rec.given; + streetTypeAbbrev := rec.abbrev; + tempInt := position(rec.given IN fullStreet); + END IF; + END LOOP; + END IF; + IF verbose THEN + RAISE NOTICE ''normalize_address() - street Type: "%"'', streetType; + END IF; + + -- There is a little more processing required now. If the word after the + -- street type begins with a number, the street type should be considered + -- part of the name, as well as the next word. eg, State Route 225a. If + -- the next word starts with a char, then everything after the street type + -- will be considered location. If there is no street type, then Im sad. + IF streetType IS NOT NULL THEN + tempString := substring(fullStreet, streetType || ws || + ''+([0-9][^ ,\.\t\r\n\f]*?)'' || ws); + IF tempString IS NOT NULL THEN + IF location IS NULL THEN + location := substring(fullStreet, streetType || ws || ''+'' + || tempString || ws || ''+(.*)$''); + END IF; + reducedStreet := substring(fullStreet, ''(.*)'' || ws || ''+'' + || location || ''$''); + streetType := NULL; + streetTypeAbbrev := NULL; + ELSE + IF location IS NULL THEN + location := substring(fullStreet, streetType || ws || ''+(.*)$''); + END IF; + reducedStreet := substring(fullStreet, ''^(.*)'' || ws || ''+'' + || streetType); + END IF; + + -- The pre direction should be at the beginning of the fullStreet string. + -- The post direction should be at the beginning of the location string + -- if there is no internal address + SELECT INTO tempString substring(reducedStreet, ''(?i)(^'' || name + || '')'' || ws) FROM direction_lookup WHERE + texticregexeq(reducedStreet, ''(?i)(^'' || name || '')'' || ws) + ORDER BY length(name) DESC; + IF tempString IS NOT NULL THEN + preDir := tempString; + SELECT INTO preDirAbbrev abbrev FROM direction_lookup + where texticregexeq(reducedStreet, ''(?i)(^'' || name || '')'' || ws) + ORDER BY length(name) DESC; + streetName := substring(reducedStreet, ''^'' || preDir || ws || ''(.*)''); + ELSE + streetName := reducedStreet; + END IF; + + IF texticregexeq(location, ''(?i)'' || internal || ''$'') THEN + -- If the internal address is at the end of the location, then no + -- location was given. We still need to look for post direction. + SELECT INTO rec abbrev, + substring(location, ''(?i)^('' || name || '')'' || ws) as value + FROM direction_lookup WHERE texticregexeq(location, ''(?i)^'' + || name || ws) ORDER BY length(name) desc; + IF rec.value IS NOT NULL THEN + postDir := rec.value; + postDirAbbrev := rec.abbrev; + END IF; + location := null; + ELSIF internal IS NULL THEN + -- If no location is given, the location string will be the post direction + SELECT INTO tempInt count(*) FROM direction_lookup WHERE + upper(location) = upper(name); + IF tempInt != 0 THEN + postDir := location; + SELECT INTO postDirAbbrev abbrev FROM direction_lookup WHERE + upper(postDir) = upper(name); + location := NULL; + ELSE + -- postDirection is not equal location, but may be contained in it. + SELECT INTO tempString substring(location, ''(?i)(^'' || name + || '')'' || ws) FROM direction_lookup WHERE + texticregexeq(location, ''(?i)(^'' || name || '')'' || ws) + ORDER BY length(name) desc; + IF tempString IS NOT NULL THEN + postDir := tempString; + SELECT INTO postDirAbbrev abbrev FROM direction_lookup + where texticregexeq(location, ''(?i)(^'' || name || '')'' || ws); + location := substring(location, ''^'' || postDir || ws || ''+(.*)''); + END IF; + END IF; + ELSE + -- internal is not null, but is not at the end of the location string + -- look for post direction before the internal address + SELECT INTO tempString substring(fullStreet, ''(?i)'' || streetType + || ws || ''+('' || name || '')'' || ws || ''+'' || internal) + FROM direction_lookup WHERE texticregexeq(fullStreet, ''(?i)'' + || ws || name || ws || ''+'' || internal) ORDER BY length(name) desc; + IF tempString IS NOT NULL THEN + postDir := tempString; + SELECT INTO postDirAbbrev abbrev FROM direction_lookup + WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name || ws); + END IF; + END IF; + ELSE + -- No street type was found + + -- If an internal address was given, then the split becomes easy, and the + -- street name is everything before it, without directions. + IF internal IS NOT NULL THEN + reducedStreet := substring(fullStreet, ''(?i)^(.*?)'' || ws || ''+'' + || internal); + SELECT INTO tempInt count(*) FROM direction_lookup WHERE + texticregexeq(reducedStreet, ''(?i)'' || ws || name || ''$''); + IF tempInt > 0 THEN + SELECT INTO postDir substring(reducedStreet, ''(?i)'' || ws || ''('' + || name || '')'' || ''$'') FROM direction_lookup + WHERE texticregexeq(reducedStreet, ''(?i)'' || ws || name || ''$''); + SELECT INTO postDirAbbrev abbrev FROM direction_lookup + WHERE texticregexeq(reducedStreet, ''(?i)'' || ws || name || ''$''); + END IF; + SELECT INTO tempString substring(reducedStreet, ''(?i)^('' || name + || '')'' || ws) FROM direction_lookup WHERE + texticregexeq(reducedStreet, ''(?i)^('' || name || '')'' || ws) + ORDER BY length(name) DESC; + IF tempString IS NOT NULL THEN + preDir := tempString; + SELECT INTO preDirAbbrev abbrev FROM direction_lookup WHERE + texticregexeq(reducedStreet, ''(?i)(^'' || name || '')'' || ws) + ORDER BY length(name) DESC; + streetName := substring(reducedStreet, ''(?i)^'' || preDir || ws + || ''+(.*?)(?:'' || ws || ''+'' || cull_null(postDir) || ''|$)''); + ELSE + streetName := substring(reducedStreet, ''(?i)^(.*?)(?:'' || ws + || ''+'' || cull_null(postDir) || ''|$)''); + END IF; + ELSE + + -- If a post direction is given, then the location is everything after, + -- the street name is everything before, less any pre direction. + SELECT INTO tempInt count(*) FROM direction_lookup + WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name || ''(?:'' + || ws || ''|$)''); + + IF tempInt = 1 THEN + -- A single postDir candidate was found. This makes it easier. + SELECT INTO postDir substring(fullStreet, ''(?i)'' || ws || ''('' + || name || '')(?:'' || ws || ''|$)'') FROM direction_lookup WHERE + texticregexeq(fullStreet, ''(?i)'' || ws || name || ''(?:'' + || ws || ''|$)''); + SELECT INTO postDirAbbrev abbrev FROM direction_lookup + WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name + || ''(?:'' || ws || ''|$)''); + IF location IS NULL THEN + location := substring(fullStreet, ''(?i)'' || ws || postDir + || ws || ''+(.*?)$''); + END IF; + reducedStreet := substring(fullStreet, ''^(.*?)'' || ws || ''+'' + || postDir); + SELECT INTO tempString substring(reducedStreet, ''(?i)(^'' || name + || '')'' || ws) FROM direction_lookup WHERE + texticregexeq(reducedStreet, ''(?i)(^'' || name || '')'' || ws) + ORDER BY length(name) DESC; + IF tempString IS NOT NULL THEN + preDir := tempString; + SELECT INTO preDirAbbrev abbrev FROM direction_lookup WHERE + texticregexeq(reducedStreet, ''(?i)(^'' || name || '')'' || ws) + ORDER BY length(name) DESC; + streetName := substring(reducedStreet, ''^'' || preDir || ws + || ''+(.*)''); + ELSE + streetName := reducedStreet; + END IF; + ELSIF tempInt > 1 THEN + -- Multiple postDir candidates were found. We need to find the last + -- incident of a direction, but avoid getting the last word from + -- a two word direction. eg extracting "East" from "North East" + -- We do this by sorting by length, and taking the last direction + -- in the results that is not included in an earlier one. + -- This wont be a problem it preDir is North East and postDir is + -- East as the regex requires a space before the direction. Only + -- the East will return from the preDir. + tempInt := 0; + FOR rec IN SELECT abbrev, substring(fullStreet, ''(?i)'' || ws || ''('' + || name || '')(?:'' || ws || ''|$)'') AS value + FROM direction_lookup + WHERE texticregexeq(fullStreet, ''(?i)'' || ws || name + || ''(?:'' || ws || ''|$)'') + ORDER BY length(name) desc LOOP + tempInt := 0; + IF tempInt < position(rec.value in fullStreet) THEN + IF postDir IS NULL THEN + tempInt := position(rec.value in fullStreet); + postDir := rec.value; + postDirAbbrev := rec.abbrev; + ELSIF NOT texticregexeq(postDir, ''(?i)'' || rec.value) THEN + tempInt := position(rec.value in fullStreet); + postDir := rec.value; + postDirAbbrev := rec.abbrev; + END IF; + END IF; + END LOOP; + IF location IS NULL THEN + location := substring(fullStreet, ''(?i)'' || ws || postDir || ws + || ''+(.*?)$''); + END IF; + reducedStreet := substring(fullStreet, ''(?i)^(.*?)'' || ws || ''+'' + || postDir); + SELECT INTO tempString substring(reducedStreet, ''(?i)(^'' || name + || '')'' || ws) FROM direction_lookup WHERE + texticregexeq(reducedStreet, ''(?i)(^'' || name || '')'' || ws) + ORDER BY length(name) DESC; + IF tempString IS NOT NULL THEN + preDir := tempString; + SELECT INTO preDirAbbrev abbrev FROM direction_lookup WHERE + texticregexeq(reducedStreet, ''(?i)(^'' || name || '')'' || ws) + ORDER BY length(name) DESC; + streetName := substring(reducedStreet, ''^'' || preDir || ws + || ''+(.*)''); + ELSE + streetName := reducedStreet; + END IF; + ELSE + + -- There is no street type, directional suffix or internal address + -- to allow distinction between street name and location. + IF location IS NULL THEN + location := location_extract(fullStreet, stateAbbrev); + END IF; + -- Check for a direction prefix. + SELECT INTO tempString substring(fullStreet, ''(?i)(^'' || name + || '')'' || ws) FROM direction_lookup WHERE + texticregexeq(fullStreet, ''(?i)(^'' || name || '')'' || ws) + ORDER BY length(name); + RAISE NOTICE ''DEBUG 1''; + IF tempString IS NOT NULL THEN + preDir := tempString; + SELECT INTO preDirAbbrev abbrev FROM direction_lookup WHERE + texticregexeq(fullStreet, ''(?i)(^'' || name || '')'' || ws) + ORDER BY length(name) DESC; + IF location IS NOT NULL THEN + -- The location may still be in the fullStreet, or may + -- have been removed already + streetName := substring(fullStreet, ''^'' || preDir || ws + || ''+(.*?)('' || ws || ''+'' || location || ''|$)''); + RAISE NOTICE ''DEBUG 2.1 "%", "%"'', streetName, fullStreet; + ELSE + streetName := substring(fullStreet, ''^'' || preDir || ws + || ''+(.*?)'' || ws || ''*''); + END IF; + ELSE + IF location IS NOT NULL THEN + -- The location may still be in the fullStreet, or may + -- have been removed already + streetName := substring(fullStreet, ''^(.*?)('' || ws + || ''+'' || location || ''|$)''); + RAISE NOTICE ''DEBUG 2.2 "%", "%"'', streetName, fullStreet; + ELSE + streetName := fullStreet; + END IF; + END IF; + END IF; + END IF; + END IF; + + + + RAISE NOTICE ''normalize_address() - final internal "%"'', internal; + RAISE NOTICE ''normalize_address() - prefix_direction "%"'', preDir; + RAISE NOTICE ''normalize_address() - street_type "%"'', streetType; + RAISE NOTICE ''normalize_address() - suffix_direction "%"'', postDir; + RAISE NOTICE ''normalize_address() - state "%"'', state; + + -- This is useful for scripted checking. It returns what was entered + -- for each field, rather than what should be used by the geocoder. + --result := cull_null(internal) || '':'' || cull_null(address) || '':'' + --|| cull_null(preDir) || '':'' || cull_null(streetName) || '':'' + --|| cull_null(streetType) || '':'' || cull_null(postDir) + --|| '':'' || cull_null(location) || '':'' || cull_null(state) || '':'' + --|| cull_null(zip); + + -- This is the standardized return. + result := cull_null(address) || '':'' || cull_null(preDirAbbrev) || '':'' + || cull_null(streetName) || '':'' || cull_null(streetTypeAbbrev) || '':'' + || cull_null(postDirAbbrev) || '':'' || cull_null(location) || '':'' + || cull_null(stateAbbrev) || '':'' || cull_null(zip); + return result; +END +' LANGUAGE plpgsql; + + + +-- rate_attributes(dirpA, dirpB, streetNameA, streetNameB, streetTypeA, +-- streetTypeB, dirsA, dirsB, locationA, locationB) +-- Rates the street based on the given attributes. The locations must be +-- non-null. The other eight values are handled by the other rate_attributes +-- function, so it's requirements must also be met. +CREATE OR REPLACE FUNCTION rate_attributes(VARCHAR, VARCHAR, VARCHAR, VARCHAR, + VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS INTEGER +AS ' +DECLARE + result INTEGER := 0; + locationWeight INTEGER := 14; +BEGIN + IF $9 IS NOT NULL AND $10 IS NOT NULL THEN + result := levenshtein_ignore_case($9, $10); + ELSE + RAISE EXCEPTION ''rate_attributes() - Location names cannot be null!''; + END IF; + result := result + rate_attributes($1, $2, $3, $4, $5, $6, $7, $8); + RETURN result; +END; +' LANGUAGE plpgsql; + +-- rate_attributes(dirpA, dirpB, streetNameA, streetNameB, streetTypeA, +-- streetTypeB, dirsA, dirsB) +-- Rates the street based on the given attributes. Only streetNames are +-- required. If any others are null (either A or B) they are treated as +-- empty strings. +CREATE OR REPLACE FUNCTION rate_attributes(VARCHAR, VARCHAR, VARCHAR, VARCHAR, + VARCHAR, VARCHAR, VARCHAR, VARCHAR) RETURNS INTEGER +AS ' +DECLARE + result INTEGER := 0; + directionWeight INTEGER := 2; + nameWeight INTEGER := 10; + typeWeight INTEGER := 5; +BEGIN + result := result + levenshtein_ignore_case(cull_null($1), cull_null($2)) * + directionWeight; + IF $3 IS NOT NULL AND $4 IS NOT NULL THEN + result := result + levenshtein_ignore_case($3, $4) * nameWeight; + ELSE + RAISE EXCEPTION ''rate_attributes() - Street names cannot be null!''; + END IF; + result := result + levenshtein_ignore_case(cull_null($5), cull_null($6)) * + typeWeight; + result := result + levenshtein_ignore_case(cull_null($7), cull_null($7)) * + directionWeight; + return result; +END; +' LANGUAGE plpgsql; + + + +-- state_extract(addressStringLessZipCode) +-- Extracts the state from end of the given string. +-- +-- This function uses the state_lookup table to determine which state +-- the input string is indicating. First, an exact match is pursued, +-- and in the event of failure, a word-by-word fuzzy match is attempted. +-- +-- The result is the state as given in the input string, and the approved +-- state abbreviation, seperated by a colon. +CREATE OR REPLACE FUNCTION state_extract(VARCHAR) RETURNS VARCHAR +AS ' +DECLARE + tempInt INTEGER; + tempString VARCHAR; + rawInput VARCHAR; + state VARCHAR; + stateAbbrev VARCHAR; + result VARCHAR; + rec RECORD; + test BOOLEAN; + ws VARCHAR; + verbose BOOLEAN := TRUE; +BEGIN + IF verbose THEN + RAISE NOTICE ''state_extract()''; + END IF; + IF $1 IS NULL THEN + RAISE EXCEPTION ''state_extract() - no input''; + ELSE + rawInput := $1; + END IF; + ws := ''[ ,\.\t\n\f\r]''; + + -- Separate out the last word of the state, and use it to compare to + -- the state lookup table to determine the entire name, as well as the + -- abbreviation associated with it. The zip code may or may not have + -- been found. + tempString := substring(rawInput from ws || ''+([^ ,\.\t\n\f\r0-9]*?)$''); + SELECT INTO tempInt count(*) FROM (select distinct abbrev from state_lookup + WHERE upper(abbrev) = upper(tempString)) as blah; + IF tempInt = 1 THEN + state := tempString; + SELECT INTO stateAbbrev abbrev FROM (select distinct abbrev from + state_lookup WHERE upper(abbrev) = upper(tempString)) as blah; + ELSE + SELECT INTO tempInt count(*) FROM state_lookup WHERE upper(name) + like upper(''%'' || tempString); + IF tempInt >= 1 THEN + FOR rec IN SELECT name from state_lookup WHERE upper(name) + like upper(''%'' || tempString) LOOP + SELECT INTO test texticregexeq(rawInput, name) FROM state_lookup + WHERE rec.name = name; + IF test THEN + SELECT INTO stateAbbrev abbrev FROM state_lookup + WHERE rec.name = name; + state := substring(rawInput, ''(?i)'' || rec.name); + EXIT; + END IF; + END LOOP; + ELSE + -- No direct match for state, so perform fuzzy match. + SELECT INTO tempInt count(*) FROM state_lookup + WHERE soundex(tempString) = end_soundex(name); + IF tempInt >= 1 THEN + FOR rec IN SELECT name, abbrev FROM state_lookup + WHERE soundex(tempString) = end_soundex(name) LOOP + tempInt := count_words(rec.name); + tempString := get_last_words(rawInput, tempInt); + test := TRUE; + FOR i IN 1..tempInt LOOP + IF soundex(split_part(tempString, '' '', i)) != + soundex(split_part(rec.name, '' '', i)) THEN + test := FALSE; + END IF; + END LOOP; + IF test THEN + state := tempString; + stateAbbrev := rec.abbrev; + EXIT; + END IF; + END LOOP; + END IF; + END IF; + END IF; + IF state IS NOT NULL AND stateAbbrev IS NOT NULL THEN + result := state || '':'' || stateAbbrev; + END IF; + return result; +END; +' LANGUAGE plpgsql; diff --git a/extras/tiger_geocoder/tiger_2010/legacy_import/tiger2008/import_tiger_shps.sh b/extras/tiger_geocoder/tiger_2010/legacy_import/tiger2008/import_tiger_shps.sh index 7a9806515..e4e23efeb 100755 --- a/extras/tiger_geocoder/tiger_2010/legacy_import/tiger2008/import_tiger_shps.sh +++ b/extras/tiger_geocoder/tiger_2010/legacy_import/tiger2008/import_tiger_shps.sh @@ -1,486 +1,486 @@ -#!/bin/bash - -shopt -s nullglob - -# This is the root directory of the TIGER data. -BASE="TIGER2008" - -# This is the set base specified by Census -SETBASE="tl_2008" - -# This is the schema prefix, all schemas will be created using this prefix. -SCHEMA_PREFIX="tiger" - -# Skip Census 2000 data if there is current data? -SKIP00="false" - -# First, handle the national data -TMPDIR=`mktemp -d tiger_tmpXXXX` - -# SRID to load the data with -SRID=4269 -DEFAULT_SRID=4269 -# Host to connect to - -if [ -z "${PGHOST}" ]; then - HOST="localhost" -else - HOST=${PGHOST} -fi -# Database to use -if [ -z "${PGDATABASE}" ];then - DB="tiger" -else - DB=${PGDATABASE} -fi - -# postgres username -if [ -z ${PGUSER} ]; then - DBUSER=`whoami` -else - DBUSER=${PGUSER} -fi - -# postgres port -if [ -z ${PGPORT} ]; then - DBPORT=5432 -else - DBPORT=${PGPORT} -fi - -# rm command -RM="/bin/rm" - -# PSQL location -PSQL="psql" - -# Encoding to use -ENCODING="LATIN1" - -# If we are processing national-level data -NATIONAL="false" - -# If we are processing state-level data -STATELVL="true" - -# If we are processing a specific state -STATES='' - -# If we are processing county-level data -COUNTYLVL="true" - -# If we are processing a specific county -COUNTIES='*' - -# If we are dropping tables before loading them -DROP="false" - -# If we are dropping the schema before loading -DROP_SCHEMA="false" - -# how verbose -DEBUG='false' -QUIET='false' - -function table_from_filename () { - local FILE="$1" - TBL=`basename $FILE .shp` - TBL=`basename ${TBL} .dbf` - TBL=`echo ${TBL} | cut -d_ -f4` - -} - -function error () { - echo '' >&2 - echo "$1" >&2 - echo '' >&2 -} - -function debug () { - if [ ${DEBUG} = "true" ]; then - echo "\* $@" >&2 - fi -} -function note () { - if [ ! ${QUIET} = 'true' ]; then - echo "$@" - fi -} -function unzip_files_matching () { - local PAT=$1 - local ZIPFILES="${PAT}*.zip" - if [ -z "${ZIPFILES}" ]; then - error "$BASE/${FILEBASE}_${NATLAYERS}.zip did not match anything!" - else - for zipfile in ${ZIPFILES}; do - local BASENAME=`basename $zipfile .zip` - if [ ${SKIP00} = 'true' ]; then - echo ${BASENAME}| egrep -q '00$' - if [ $? -eq 0 ]; then - continue - fi - fi - note "Unzipping $BASENAME..." - unzip -q -d $TMPDIR $zipfile - done - fi -} - -function reproject () { - FILE="$1" - local DIRNAME=`dirname ${FILE}` - local BASE=`basename ${FILE}` - SRID="$2" - which ogr2ogr > /dev/null 2>&1 - if [ $? -ne 0 ]; then - error "ogr2ogr not found. You may not specify -r" - exit 1 - fi - NEWFILE="${DIRNAME}/${SRID}_${BASE}" - ogr2ogr \ - -overwrite -t_srs "EPSG:${SRID}" \ - -f 'ESRI Shapefile' \ - "${NEWFILE}" "${FILE}" - if [ $? -ne 0 ]; then - error "error reprojecting file ${FILE} into ${NEWFILE}" - exit 1; - fi -} - -function addcols () { - local SCHEMA=$1 - local TABLE=$2 - local FIPS=`echo ${SCHEMA} | awk -F_ '/_[0-9][0-9]$/ {print $NF}'` - - if [ -z "${FIPS}" ]; then - error "cannot find fips code for ${SCHEMA} - that is probably not good" - return 1 - fi - echo ${TABLE}| egrep -q '00$' - if [ $? -eq 0 ]; then - STATEFP='statefp00' - else - STATEFP='statefp' - fi - # add statefp where needed - ${PSQL_CMD} -t -c "\d ${SCHEMA}.${TABLE}"| egrep -q "^ +${STATEFP} " - if [ $? -eq 1 ]; then - ${PSQL_CMD_NULL} -c "ALTER TABLE ${SCHEMA}.${TABLE} ADD COLUMN ${STATEFP} varchar(2) not null DEFAULT ('${FIPS}');" - fi - # add statefp check everywhere - ${PSQL_CMD_NULL} -c "ALTER TABLE ${SCHEMA}.${TABLE} ADD CHECK (${STATEFP} = '${FIPS}');" - #${PSQL_CMD_NULL} -c "CREATE INDEX ${TABLE}_${STATEFP}_idx ON ${SCHEMA}.${TABLE} USING btree($STATEFP);" - -} - -function loadshp () { - local FILE="$1" - local TABLE="$2" - local BASESHP=`basename $FILE .shp` - local DROPTBL="" - local CMD_EXTRAS='' - local NEWFILE='' - - if [ "$DROP" = "true" ]; then - DROPTBL="-d" - fi - note Loading ${FILE} into ${SCHEMA}.${TABLE} - if [ "${DEBUG}" = 'true' ]; then - : - else - CMD_EXTRAS='' - fi - - if [ ${DEFAULT_SRID} = ${SRID} ]; then - NEWFILE=${FILE} - else - reproject "${FILE}" ${SRID} - note "using reprojected file: ${NEWFILE}" - fi - shp2pgsql \ - $DROPTBL \ - -I \ - -s $SRID \ - -W ${ENCODING} \ - "${NEWFILE}" \ - "${SCHEMA}.${TABLE}"\ - ${CMD_EXTRAS} \ - | (echo set client_min_messages=fatal\; ;cat -) \ - | ${PSQL_CMD_NULL} \ - | egrep -v '^(INSERT INTO|BEGIN;|END;)' # you really don't want to see a zillion insert statements - addcols "$SCHEMA" "$TABLE" -} - -function loaddbf () { - local FILE="$1" - local TABLE="$2" - local BASESHP=`basename $FILE .dbf` - local DROPTBL="" - if [ "$DROP" = "true" ]; then - DROPTBL="-d" - fi - note Loading ${FILE} into ${SCHEMA}.${TABLE} - shp2pgsql \ - $DROPTBL \ - -W ${ENCODING} \ - -n \ - "${FILE}" \ - "${SCHEMA}.${TABLE}" \ - | (echo set client_min_messages=fatal\; ;cat -) \ - | ${PSQL_CMD_NULL} \ - | egrep -v '^(INSERT INTO|BEGIN;|END;)' # you really don't want to see a zillion insert statements - addcols "$SCHEMA" "$TABLE" -} - -function create_schema () { - local SCHEMA="$1" - local EXT='' - if [ "${DROP_SCHEMA}" = "true" ]; then - EXT="drop schema if exists $SCHEMA cascade;" - fi - cat<&2 < /dev/null - cat<&2 + echo "$1" >&2 + echo '' >&2 +} + +function debug () { + if [ ${DEBUG} = "true" ]; then + echo "\* $@" >&2 + fi +} +function note () { + if [ ! ${QUIET} = 'true' ]; then + echo "$@" + fi +} +function unzip_files_matching () { + local PAT=$1 + local ZIPFILES="${PAT}*.zip" + if [ -z "${ZIPFILES}" ]; then + error "$BASE/${FILEBASE}_${NATLAYERS}.zip did not match anything!" + else + for zipfile in ${ZIPFILES}; do + local BASENAME=`basename $zipfile .zip` + if [ ${SKIP00} = 'true' ]; then + echo ${BASENAME}| egrep -q '00$' + if [ $? -eq 0 ]; then + continue + fi + fi + note "Unzipping $BASENAME..." + unzip -q -d $TMPDIR $zipfile + done + fi +} + +function reproject () { + FILE="$1" + local DIRNAME=`dirname ${FILE}` + local BASE=`basename ${FILE}` + SRID="$2" + which ogr2ogr > /dev/null 2>&1 + if [ $? -ne 0 ]; then + error "ogr2ogr not found. You may not specify -r" + exit 1 + fi + NEWFILE="${DIRNAME}/${SRID}_${BASE}" + ogr2ogr \ + -overwrite -t_srs "EPSG:${SRID}" \ + -f 'ESRI Shapefile' \ + "${NEWFILE}" "${FILE}" + if [ $? -ne 0 ]; then + error "error reprojecting file ${FILE} into ${NEWFILE}" + exit 1; + fi +} + +function addcols () { + local SCHEMA=$1 + local TABLE=$2 + local FIPS=`echo ${SCHEMA} | awk -F_ '/_[0-9][0-9]$/ {print $NF}'` + + if [ -z "${FIPS}" ]; then + error "cannot find fips code for ${SCHEMA} - that is probably not good" + return 1 + fi + echo ${TABLE}| egrep -q '00$' + if [ $? -eq 0 ]; then + STATEFP='statefp00' + else + STATEFP='statefp' + fi + # add statefp where needed + ${PSQL_CMD} -t -c "\d ${SCHEMA}.${TABLE}"| egrep -q "^ +${STATEFP} " + if [ $? -eq 1 ]; then + ${PSQL_CMD_NULL} -c "ALTER TABLE ${SCHEMA}.${TABLE} ADD COLUMN ${STATEFP} varchar(2) not null DEFAULT ('${FIPS}');" + fi + # add statefp check everywhere + ${PSQL_CMD_NULL} -c "ALTER TABLE ${SCHEMA}.${TABLE} ADD CHECK (${STATEFP} = '${FIPS}');" + #${PSQL_CMD_NULL} -c "CREATE INDEX ${TABLE}_${STATEFP}_idx ON ${SCHEMA}.${TABLE} USING btree($STATEFP);" + +} + +function loadshp () { + local FILE="$1" + local TABLE="$2" + local BASESHP=`basename $FILE .shp` + local DROPTBL="" + local CMD_EXTRAS='' + local NEWFILE='' + + if [ "$DROP" = "true" ]; then + DROPTBL="-d" + fi + note Loading ${FILE} into ${SCHEMA}.${TABLE} + if [ "${DEBUG}" = 'true' ]; then + : + else + CMD_EXTRAS='' + fi + + if [ ${DEFAULT_SRID} = ${SRID} ]; then + NEWFILE=${FILE} + else + reproject "${FILE}" ${SRID} + note "using reprojected file: ${NEWFILE}" + fi + shp2pgsql \ + $DROPTBL \ + -I \ + -s $SRID \ + -W ${ENCODING} \ + "${NEWFILE}" \ + "${SCHEMA}.${TABLE}"\ + ${CMD_EXTRAS} \ + | (echo set client_min_messages=fatal\; ;cat -) \ + | ${PSQL_CMD_NULL} \ + | egrep -v '^(INSERT INTO|BEGIN;|END;)' # you really don't want to see a zillion insert statements + addcols "$SCHEMA" "$TABLE" +} + +function loaddbf () { + local FILE="$1" + local TABLE="$2" + local BASESHP=`basename $FILE .dbf` + local DROPTBL="" + if [ "$DROP" = "true" ]; then + DROPTBL="-d" + fi + note Loading ${FILE} into ${SCHEMA}.${TABLE} + shp2pgsql \ + $DROPTBL \ + -W ${ENCODING} \ + -n \ + "${FILE}" \ + "${SCHEMA}.${TABLE}" \ + | (echo set client_min_messages=fatal\; ;cat -) \ + | ${PSQL_CMD_NULL} \ + | egrep -v '^(INSERT INTO|BEGIN;|END;)' # you really don't want to see a zillion insert statements + addcols "$SCHEMA" "$TABLE" +} + +function create_schema () { + local SCHEMA="$1" + local EXT='' + if [ "${DROP_SCHEMA}" = "true" ]; then + EXT="drop schema if exists $SCHEMA cascade;" + fi + cat<&2 < /dev/null + cat< ant install-JDBC-driver -This command installs the PostgreSQL driver into JBoss - -> ant install-DataSource -This command installs the DataSource Connector into JBoss - -> ant javadoc -This command generates the application API documentation into the ./javadoc -directory (use index.html to start). - -> ant deploy -Installs the application into JBoss - -> ant run-client -Allows to test the installed application - - -6. Code Details ---------------- -The main components made available in the application are: - -- GeometryBean.java -It is an entity bean containing a geometrical attribute of org.postgis.Geometry -type which could contain every geometrical type (i.e. POINT, LINESTRING, etc.). -The user can choose wether to create a NON-OpenGIS or an OpenGIS-compliant -bean. The first ones can contain different geometric types in the same table -with undefined SRID (-1), while the second ones can only contain object of the -same type and SRID in one table; - -- PostgisGeometryDaoIml.java -A DAO (Data Access Object) implementing persistence operations for the -GeometryBean EJB in a PostGIS database; - -- GeometryFacadeBean.java -A stateless session bean implementing the interface between the geometric -entity beans and the client applications; - -- Client.java -It is a simple client executing some tests thus illustrating the use of the -provided API. - -Further informations could be gathered from the source code and by reading the -javadoc API documentation. +Using PostGIS Geometry Types with EJB2 -- Proof of Concept +---------------------------------------------------------- +Copyright (C) 2006 by the Geodetix s.r.l. Company. See +http://www.geodetix.it/ for further information. + +Version 1.0.0 (2006/08/29) + +Table of Contents +----------------- + +0. Licensing +1. Introduction +2. Directory Contents +3. Software Requirements +4. Installation +5. Running +6. Code Details + + +0. Licensing +------------ +The "Using PostGIS Geometry Types with EJB2 -- Proof of Concept" software is +a short collection of examples related to the use of PostGIS Java API with +the EJB 2.x technology. +Copyright (C) 2006 by the Geodetix s.r.l. Company. See +http://www.geodetix.it/ for further information. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +1. Introduction +--------------- +Our software is a simple proof-of-concept application illustrating how the +PostGIS provided Java geometric types could be integrated with a set of +Enterprise Java Bean 2.x components. + +To achieve such a goal, an attribute of type org.postgis.Geometry has been +added to a BMP (Bean managed Persistence) Entity Bean. Furthermore, by using +the DAO (Data Access Object) Pattern, the persistence code has been clearly +separated from the business logic. + +Not to add further complexity, some proper programming behaviours were omitted. +For example the use of PostGIS geometric types directly inside the Entity Bean +code could be avoided by using a WKT compliant string attribute. Another issue +is about security: table creational methods exposed in the +com.geodetix.geo.ejb.GeometryBean home interface should be protected by +a proper role-base security policy, to avoid normal users deleting database +tables. + +Nevertheless our application, even if quite simple, still holds a lot of +generality and some of the implemented patterns or components are readily +usable in real-world applications. + + +2. Directory Contents +--------------------- + + ./ Build scripts (build.*), README and licensing information + ./src Java source packages and files + ./resources EJB specific configuration files + ./lib JAR libraries needed to compile and run + + +3. Software Requirements +------------------------ +We here list all third-party libraries with their versions tested to work +with the application. + +PostGIS JDBC driver version 1.1.3 +http://www.postgis.org/ + +PostgreSQL JDBC driver version 8.1-404 jdbc3 +http://jdbc.postgresql.org/ + +XDoclet lib version 1.2.3 +http://xdoclet.sourceforge.net + +Apache ANT version 1.6.5 +http://ant.apache.org/ + +JBOSS Application Server version 4.0.4.GA-Patch1 +http://www.jboss.org/ + +Note that our tool is application server agnostic and could be easily ported +to any EJB 2.x compliant Container by modifying the provided deployment +ant file which is, in turn, written for the JBoss Application Server. + + +4. Installation +--------------- +After downloading (and compiling, if necessary) all of the required software, +follow these steps: + +- copy the PostGIS driver (postgis_1.1.3.jar) into the ./lib/commonlib +directory + +- copy the PostgreSQL driver (postgresql-8.1-404.jdbc3.jar) into the +./lib/compiletimelib directory + +- copy the XDoclet libraries (contained in xdoclet-lib-1.2.3.tgz) into the +./lib/xdocletlib directory + +- install Apache ANT (follow the installation istructions provided +with the tool) + +- install the JBoss Application Server + +- make sure that your JBOSS_HOME environment variable correctly points to +the JBoss installation directory (i.e. /opt/jboss-4.0.4.GA) + +- create a new PostGIS database according to what specified in the +./resources/build.properties with the "database.name", "database.login", +"database.password" properties (eventually change them to fit your needs). + + +5. Running +---------- +Start the JBoss application server with the provided scripts +(run.bat or run.sh). + +From the main application directory (./) execute these commands: + +> ant install-JDBC-driver +This command installs the PostgreSQL driver into JBoss + +> ant install-DataSource +This command installs the DataSource Connector into JBoss + +> ant javadoc +This command generates the application API documentation into the ./javadoc +directory (use index.html to start). + +> ant deploy +Installs the application into JBoss + +> ant run-client +Allows to test the installed application + + +6. Code Details +--------------- +The main components made available in the application are: + +- GeometryBean.java +It is an entity bean containing a geometrical attribute of org.postgis.Geometry +type which could contain every geometrical type (i.e. POINT, LINESTRING, etc.). +The user can choose wether to create a NON-OpenGIS or an OpenGIS-compliant +bean. The first ones can contain different geometric types in the same table +with undefined SRID (-1), while the second ones can only contain object of the +same type and SRID in one table; + +- PostgisGeometryDaoIml.java +A DAO (Data Access Object) implementing persistence operations for the +GeometryBean EJB in a PostGIS database; + +- GeometryFacadeBean.java +A stateless session bean implementing the interface between the geometric +entity beans and the client applications; + +- Client.java +It is a simple client executing some tests thus illustrating the use of the +provided API. + +Further informations could be gathered from the source code and by reading the +javadoc API documentation. diff --git a/java/ejb2/build.xml b/java/ejb2/build.xml index 0f0934578..beaf5066e 100644 --- a/java/ejb2/build.xml +++ b/java/ejb2/build.xml @@ -1,272 +1,272 @@ - - - - Using PostGIS Geometry Types with EJB2 - Proof of Concept - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Using PostGIS Geometry Types with EJB2
Proof of Concept]]>
- Copyright © 2006 Geodetix S.r.l. All Rights Reserved.]]> -
-
- -
+ + + + Using PostGIS Geometry Types with EJB2 - Proof of Concept + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Using PostGIS Geometry Types with EJB2
Proof of Concept]]>
+ Copyright © 2006 Geodetix S.r.l. All Rights Reserved.]]> +
+
+ +
diff --git a/java/ejb2/prepare-jboss.xml b/java/ejb2/prepare-jboss.xml index 07000cdae..16e9c4b7e 100644 --- a/java/ejb2/prepare-jboss.xml +++ b/java/ejb2/prepare-jboss.xml @@ -1,39 +1,39 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/ejb2/resources/application.xml b/java/ejb2/resources/application.xml index 90bb34c99..6f5654a8c 100644 --- a/java/ejb2/resources/application.xml +++ b/java/ejb2/resources/application.xml @@ -1,19 +1,19 @@ - - - - - - postgis-ejb2-poc - - Using PostGIS Geometry Types with EJB2 - Proof of Concept - - - ejb.jar - - - - common.jar - - - + + + + + + postgis-ejb2-poc + + Using PostGIS Geometry Types with EJB2 - Proof of Concept + + + ejb.jar + + + + common.jar + + + diff --git a/java/ejb2/resources/build.properties b/java/ejb2/resources/build.properties index 95a91dc71..9209cc07a 100644 --- a/java/ejb2/resources/build.properties +++ b/java/ejb2/resources/build.properties @@ -1,12 +1,12 @@ -# You can change these properties to fit your environment. -# This should be the only file to modify. -# Note that you should NOT leave spaces after a property value - -# Name of the created database -database.name=ejb2poc -# User owner of the database tables -database.login=CHANGEIT -# Password for the db user -database.password=CHANGEIT -# IP or hostname of the machine running the database server -database.host=127.0.0.1 +# You can change these properties to fit your environment. +# This should be the only file to modify. +# Note that you should NOT leave spaces after a property value + +# Name of the created database +database.name=ejb2poc +# User owner of the database tables +database.login=CHANGEIT +# Password for the db user +database.password=CHANGEIT +# IP or hostname of the machine running the database server +database.host=127.0.0.1 diff --git a/java/ejb2/resources/jndi/jndi.properties b/java/ejb2/resources/jndi/jndi.properties index a3face720..8e65c8677 100644 --- a/java/ejb2/resources/jndi/jndi.properties +++ b/java/ejb2/resources/jndi/jndi.properties @@ -1,3 +1,3 @@ -java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory -java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces -java.naming.provider.url=localhost +java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory +java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces +java.naming.provider.url=localhost diff --git a/java/ejb2/resources/postgis-ejb2-ds.xml b/java/ejb2/resources/postgis-ejb2-ds.xml index 19b1eea68..ec105499d 100644 --- a/java/ejb2/resources/postgis-ejb2-ds.xml +++ b/java/ejb2/resources/postgis-ejb2-ds.xml @@ -1,17 +1,17 @@ - - - - - - - - - - - @datasource.name@ - @database.connection.url@ - @database.driver@ - @database.login@ - @database.password@ - + + + + + + + + + + + @datasource.name@ + @database.connection.url@ + @database.driver@ + @database.login@ + @database.password@ + \ No newline at end of file diff --git a/java/ejb3/.settings/org.eclipse.jdt.core.prefs b/java/ejb3/.settings/org.eclipse.jdt.core.prefs index 1f70eeaab..65a57623d 100644 --- a/java/ejb3/.settings/org.eclipse.jdt.core.prefs +++ b/java/ejb3/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,7 @@ -#Mon Sep 18 15:14:48 BST 2006 -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.5 +#Mon Sep 18 15:14:48 BST 2006 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/java/ejb3/build.xml b/java/ejb3/build.xml index 479add9be..d7e9068f7 100644 --- a/java/ejb3/build.xml +++ b/java/ejb3/build.xml @@ -1,71 +1,71 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/ejb3/jboss/geodata-ds.xml b/java/ejb3/jboss/geodata-ds.xml index 789674889..f681e9ef6 100644 --- a/java/ejb3/jboss/geodata-ds.xml +++ b/java/ejb3/jboss/geodata-ds.xml @@ -1,13 +1,13 @@ - - - - GeoDataDS - jdbc:postgresql://127.0.0.1:5432/geotest - org.postgis.DriverWrapper - geo - geo - - PostgreSQL 8.1 - - - + + + + GeoDataDS + jdbc:postgresql://127.0.0.1:5432/geotest + org.postgis.DriverWrapper + geo + geo + + PostgreSQL 8.1 + + + diff --git a/java/ejb3/jboss/ingest-service.xml b/java/ejb3/jboss/ingest-service.xml index 266d1ddd8..2e6789da8 100644 --- a/java/ejb3/jboss/ingest-service.xml +++ b/java/ejb3/jboss/ingest-service.xml @@ -1,7 +1,7 @@ - - - - jboss.mq:service=DestinationManager - + + + + jboss.mq:service=DestinationManager + \ No newline at end of file diff --git a/java/ejb3/src/META-INF/persistence.xml b/java/ejb3/src/META-INF/persistence.xml index 0a45aadaf..bb06da6a7 100644 --- a/java/ejb3/src/META-INF/persistence.xml +++ b/java/ejb3/src/META-INF/persistence.xml @@ -1,5 +1,5 @@ - - - java:/GeoDataDS - + + + java:/GeoDataDS + \ No newline at end of file diff --git a/java/ejb3/src/org/postgis/hibernate/ContainsExpression.java b/java/ejb3/src/org/postgis/hibernate/ContainsExpression.java index f1b90f4c9..4904eb8f9 100644 --- a/java/ejb3/src/org/postgis/hibernate/ContainsExpression.java +++ b/java/ejb3/src/org/postgis/hibernate/ContainsExpression.java @@ -1,83 +1,83 @@ -/* - * ContainsExpression.java - * - * PostGIS extension for PostgreSQL JDBC driver - EJB3 Tutorial - * - * (C) 2006 Norman Barker - * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at - * http://www.gnu.org. - * - * $Id$ - */ -package org.postgis.hibernate; - -import java.util.ArrayList; -import java.util.List; - -import org.hibernate.Criteria; -import org.hibernate.EntityMode; -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; -import org.hibernate.criterion.CriteriaQuery; -import org.hibernate.criterion.Criterion; -import org.hibernate.dialect.Dialect; -import org.hibernate.dialect.function.StandardSQLFunction; -import org.hibernate.engine.TypedValue; -import org.postgis.Geometry; - -/** - * @author nbarker - * - */ -public class ContainsExpression implements Criterion{ - private static final long serialVersionUID = 1L; - private String propertyName; - private Geometry geom; - - public ContainsExpression(String propertyName, Geometry geom) - { - this.propertyName = propertyName; - this.geom = geom; - } - - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return new TypedValue[]{new TypedValue(Hibernate.custom(GeometryType.class), geom, EntityMode.POJO)}; - } - - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - Dialect dialect = criteriaQuery.getFactory().getDialect(); - String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName); - - if (columns.length != 1) throw new HibernateException("\"contains\" may only be used with single-column properties"); - if ( dialect instanceof PostGISDialect) { - StandardSQLFunction function = (StandardSQLFunction)dialect.getFunctions().get(PostGISDialect.NAMESPACE + "contains"); - List args = new ArrayList(); - args.add(columns[0]); - args.add("?"); - - return function.render(args, criteriaQuery.getFactory()); - } - else - { - throw new HibernateException("\"contains\" may only be used with a spatial hibernate dialect"); - } - } - - public String toString() - { - return propertyName + " contains " + geom; - } - -} +/* + * ContainsExpression.java + * + * PostGIS extension for PostgreSQL JDBC driver - EJB3 Tutorial + * + * (C) 2006 Norman Barker + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at + * http://www.gnu.org. + * + * $Id$ + */ +package org.postgis.hibernate; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.Criteria; +import org.hibernate.EntityMode; +import org.hibernate.Hibernate; +import org.hibernate.HibernateException; +import org.hibernate.criterion.CriteriaQuery; +import org.hibernate.criterion.Criterion; +import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.function.StandardSQLFunction; +import org.hibernate.engine.TypedValue; +import org.postgis.Geometry; + +/** + * @author nbarker + * + */ +public class ContainsExpression implements Criterion{ + private static final long serialVersionUID = 1L; + private String propertyName; + private Geometry geom; + + public ContainsExpression(String propertyName, Geometry geom) + { + this.propertyName = propertyName; + this.geom = geom; + } + + public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { + return new TypedValue[]{new TypedValue(Hibernate.custom(GeometryType.class), geom, EntityMode.POJO)}; + } + + public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { + Dialect dialect = criteriaQuery.getFactory().getDialect(); + String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName); + + if (columns.length != 1) throw new HibernateException("\"contains\" may only be used with single-column properties"); + if ( dialect instanceof PostGISDialect) { + StandardSQLFunction function = (StandardSQLFunction)dialect.getFunctions().get(PostGISDialect.NAMESPACE + "contains"); + List args = new ArrayList(); + args.add(columns[0]); + args.add("?"); + + return function.render(args, criteriaQuery.getFactory()); + } + else + { + throw new HibernateException("\"contains\" may only be used with a spatial hibernate dialect"); + } + } + + public String toString() + { + return propertyName + " contains " + geom; + } + +} diff --git a/java/ejb3/src/org/postgis/hibernate/IntersectsExpression.java b/java/ejb3/src/org/postgis/hibernate/IntersectsExpression.java index 29cad7d55..1ca240fc7 100644 --- a/java/ejb3/src/org/postgis/hibernate/IntersectsExpression.java +++ b/java/ejb3/src/org/postgis/hibernate/IntersectsExpression.java @@ -1,83 +1,83 @@ -/* - * IntersectsExpression.java - * - * PostGIS extension for PostgreSQL JDBC driver - EJB3 Tutorial - * - * (C) 2006 Norman Barker - * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at - * http://www.gnu.org. - * - * $Id$ - */ -package org.postgis.hibernate; - -import java.util.ArrayList; -import java.util.List; - -import org.hibernate.Criteria; -import org.hibernate.EntityMode; -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; -import org.hibernate.criterion.CriteriaQuery; -import org.hibernate.criterion.Criterion; -import org.hibernate.dialect.Dialect; -import org.hibernate.dialect.function.StandardSQLFunction; -import org.hibernate.engine.TypedValue; -import org.postgis.Geometry; - -/** - * @author nbarker - * - */ -public class IntersectsExpression implements Criterion{ - private static final long serialVersionUID = 1L; - private String propertyName; - private Geometry geom; - - public IntersectsExpression(String propertyName, Geometry geom) - { - this.propertyName = propertyName; - this.geom = geom; - } - - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return new TypedValue[]{new TypedValue(Hibernate.custom(GeometryType.class), geom, EntityMode.POJO)}; - } - - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - Dialect dialect = criteriaQuery.getFactory().getDialect(); - String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName); - - if (columns.length != 1) throw new HibernateException("\"intersects\" may only be used with single-column properties"); - if ( dialect instanceof PostGISDialect) { - StandardSQLFunction function = (StandardSQLFunction)dialect.getFunctions().get(PostGISDialect.NAMESPACE + "intersects"); - List args = new ArrayList(); - args.add(columns[0]); - args.add("?"); - - return function.render(args, criteriaQuery.getFactory()); - } - else - { - throw new HibernateException("\"intersects\" may only be used with a spatial hibernate dialect"); - } - } - - public String toString() - { - return propertyName + " intersects " + geom; - } - -} +/* + * IntersectsExpression.java + * + * PostGIS extension for PostgreSQL JDBC driver - EJB3 Tutorial + * + * (C) 2006 Norman Barker + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at + * http://www.gnu.org. + * + * $Id$ + */ +package org.postgis.hibernate; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.Criteria; +import org.hibernate.EntityMode; +import org.hibernate.Hibernate; +import org.hibernate.HibernateException; +import org.hibernate.criterion.CriteriaQuery; +import org.hibernate.criterion.Criterion; +import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.function.StandardSQLFunction; +import org.hibernate.engine.TypedValue; +import org.postgis.Geometry; + +/** + * @author nbarker + * + */ +public class IntersectsExpression implements Criterion{ + private static final long serialVersionUID = 1L; + private String propertyName; + private Geometry geom; + + public IntersectsExpression(String propertyName, Geometry geom) + { + this.propertyName = propertyName; + this.geom = geom; + } + + public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { + return new TypedValue[]{new TypedValue(Hibernate.custom(GeometryType.class), geom, EntityMode.POJO)}; + } + + public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { + Dialect dialect = criteriaQuery.getFactory().getDialect(); + String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName); + + if (columns.length != 1) throw new HibernateException("\"intersects\" may only be used with single-column properties"); + if ( dialect instanceof PostGISDialect) { + StandardSQLFunction function = (StandardSQLFunction)dialect.getFunctions().get(PostGISDialect.NAMESPACE + "intersects"); + List args = new ArrayList(); + args.add(columns[0]); + args.add("?"); + + return function.render(args, criteriaQuery.getFactory()); + } + else + { + throw new HibernateException("\"intersects\" may only be used with a spatial hibernate dialect"); + } + } + + public String toString() + { + return propertyName + " intersects " + geom; + } + +} diff --git a/java/ejb3/src/org/postgis/hibernate/PostGISDialect.java b/java/ejb3/src/org/postgis/hibernate/PostGISDialect.java index 7d1bb55ff..dabcb921a 100644 --- a/java/ejb3/src/org/postgis/hibernate/PostGISDialect.java +++ b/java/ejb3/src/org/postgis/hibernate/PostGISDialect.java @@ -1,76 +1,76 @@ -/* - * PostGISDialect.java - * - * PostGIS extension for PostgreSQL JDBC driver - EJB3 Tutorial - * - * (C) 2006 Norman Barker - * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at - * http://www.gnu.org. - * - * $Id$ - */ -package org.postgis.hibernate; - -import java.sql.Types; - -import org.hibernate.Hibernate; -import org.hibernate.dialect.PostgreSQLDialect; -import org.hibernate.dialect.function.StandardSQLFunction; -import org.postgis.hibernate.GeometryType; - -/** - * @author nbarker - * - */ -public class PostGISDialect extends PostgreSQLDialect{ - public static String NAMESPACE = "spatial."; - - - public PostGISDialect() - { - super(); - registerColumnType(Types.BLOB, "geometry"); - registerFunction( PostGISDialect.NAMESPACE + "dimension", new StandardSQLFunction("dimension", Hibernate.INTEGER)); - registerFunction( PostGISDialect.NAMESPACE + "geometrytype", new StandardSQLFunction("geometrytype", Hibernate.STRING)); - registerFunction( PostGISDialect.NAMESPACE + "srid", new StandardSQLFunction("srid", Hibernate.INTEGER)); - registerFunction( PostGISDialect.NAMESPACE + "envelope", new StandardSQLFunction("envelope", Hibernate.custom(GeometryType.class))); - registerFunction( PostGISDialect.NAMESPACE + "astext", new StandardSQLFunction("astext", Hibernate.STRING)); - registerFunction( PostGISDialect.NAMESPACE + "asbinary", new StandardSQLFunction("asbinary", Hibernate.BINARY)); - registerFunction( PostGISDialect.NAMESPACE + "isempty", new StandardSQLFunction("isempty", Hibernate.STRING)); - registerFunction( PostGISDialect.NAMESPACE + "issimple", new StandardSQLFunction("issimple", Hibernate.STRING)); - registerFunction( PostGISDialect.NAMESPACE + "boundary", new StandardSQLFunction("boundary", Hibernate.custom(GeometryType.class))); - registerFunction( PostGISDialect.NAMESPACE + "equals", new StandardSQLFunction("equals", Hibernate.STRING)); - registerFunction( PostGISDialect.NAMESPACE + "disjoint", new StandardSQLFunction("disjoint", Hibernate.STRING)); - registerFunction( PostGISDialect.NAMESPACE + "intersects", new StandardSQLFunction("intersects", Hibernate.STRING)); - registerFunction( PostGISDialect.NAMESPACE + "touches", new StandardSQLFunction("touches", Hibernate.STRING)); - registerFunction( PostGISDialect.NAMESPACE + "crosses", new StandardSQLFunction("crosses", Hibernate.STRING)); - registerFunction( PostGISDialect.NAMESPACE + "within", new StandardSQLFunction("within", Hibernate.BOOLEAN)); - registerFunction( PostGISDialect.NAMESPACE + "contains", new StandardSQLFunction("contains", Hibernate.STRING)); - registerFunction( PostGISDialect.NAMESPACE + "overlaps", new StandardSQLFunction("overlaps", Hibernate.STRING)); - registerFunction( PostGISDialect.NAMESPACE + "relate", new StandardSQLFunction("relate", Hibernate.STRING)); - registerFunction( PostGISDialect.NAMESPACE + "distance", new StandardSQLFunction("distance", Hibernate.DOUBLE)); - registerFunction( PostGISDialect.NAMESPACE + "buffer", new StandardSQLFunction("buffer", Hibernate.custom(GeometryType.class))); - registerFunction( PostGISDialect.NAMESPACE + "convexhull", new StandardSQLFunction("convexhull", Hibernate.custom(GeometryType.class))); - registerFunction( PostGISDialect.NAMESPACE + "intersection", new StandardSQLFunction("intersection", Hibernate.custom(GeometryType.class))); - registerFunction( PostGISDialect.NAMESPACE + "union", new StandardSQLFunction("geomunion", Hibernate.custom(GeometryType.class))); - registerFunction( PostGISDialect.NAMESPACE + "difference", new StandardSQLFunction("difference", Hibernate.custom(GeometryType.class))); - registerFunction( PostGISDialect.NAMESPACE + "symdifference", new StandardSQLFunction("symdifference", Hibernate.custom(GeometryType.class))); - registerFunction( PostGISDialect.NAMESPACE + "numgeometries", new StandardSQLFunction("numgeometries", Hibernate.custom(GeometryType.class))); - registerFunction( PostGISDialect.NAMESPACE + "geometryn", new StandardSQLFunction("geometryn", Hibernate.INTEGER)); - registerFunction( PostGISDialect.NAMESPACE + "x", new StandardSQLFunction("x", Hibernate.DOUBLE)); - registerFunction( PostGISDialect.NAMESPACE + "y", new StandardSQLFunction("y", Hibernate.DOUBLE)); - registerFunction( PostGISDialect.NAMESPACE + "geometryfromewtk", new StandardSQLFunction("geometryfromewtk", Hibernate.custom(GeometryType.class))); - } -} +/* + * PostGISDialect.java + * + * PostGIS extension for PostgreSQL JDBC driver - EJB3 Tutorial + * + * (C) 2006 Norman Barker + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at + * http://www.gnu.org. + * + * $Id$ + */ +package org.postgis.hibernate; + +import java.sql.Types; + +import org.hibernate.Hibernate; +import org.hibernate.dialect.PostgreSQLDialect; +import org.hibernate.dialect.function.StandardSQLFunction; +import org.postgis.hibernate.GeometryType; + +/** + * @author nbarker + * + */ +public class PostGISDialect extends PostgreSQLDialect{ + public static String NAMESPACE = "spatial."; + + + public PostGISDialect() + { + super(); + registerColumnType(Types.BLOB, "geometry"); + registerFunction( PostGISDialect.NAMESPACE + "dimension", new StandardSQLFunction("dimension", Hibernate.INTEGER)); + registerFunction( PostGISDialect.NAMESPACE + "geometrytype", new StandardSQLFunction("geometrytype", Hibernate.STRING)); + registerFunction( PostGISDialect.NAMESPACE + "srid", new StandardSQLFunction("srid", Hibernate.INTEGER)); + registerFunction( PostGISDialect.NAMESPACE + "envelope", new StandardSQLFunction("envelope", Hibernate.custom(GeometryType.class))); + registerFunction( PostGISDialect.NAMESPACE + "astext", new StandardSQLFunction("astext", Hibernate.STRING)); + registerFunction( PostGISDialect.NAMESPACE + "asbinary", new StandardSQLFunction("asbinary", Hibernate.BINARY)); + registerFunction( PostGISDialect.NAMESPACE + "isempty", new StandardSQLFunction("isempty", Hibernate.STRING)); + registerFunction( PostGISDialect.NAMESPACE + "issimple", new StandardSQLFunction("issimple", Hibernate.STRING)); + registerFunction( PostGISDialect.NAMESPACE + "boundary", new StandardSQLFunction("boundary", Hibernate.custom(GeometryType.class))); + registerFunction( PostGISDialect.NAMESPACE + "equals", new StandardSQLFunction("equals", Hibernate.STRING)); + registerFunction( PostGISDialect.NAMESPACE + "disjoint", new StandardSQLFunction("disjoint", Hibernate.STRING)); + registerFunction( PostGISDialect.NAMESPACE + "intersects", new StandardSQLFunction("intersects", Hibernate.STRING)); + registerFunction( PostGISDialect.NAMESPACE + "touches", new StandardSQLFunction("touches", Hibernate.STRING)); + registerFunction( PostGISDialect.NAMESPACE + "crosses", new StandardSQLFunction("crosses", Hibernate.STRING)); + registerFunction( PostGISDialect.NAMESPACE + "within", new StandardSQLFunction("within", Hibernate.BOOLEAN)); + registerFunction( PostGISDialect.NAMESPACE + "contains", new StandardSQLFunction("contains", Hibernate.STRING)); + registerFunction( PostGISDialect.NAMESPACE + "overlaps", new StandardSQLFunction("overlaps", Hibernate.STRING)); + registerFunction( PostGISDialect.NAMESPACE + "relate", new StandardSQLFunction("relate", Hibernate.STRING)); + registerFunction( PostGISDialect.NAMESPACE + "distance", new StandardSQLFunction("distance", Hibernate.DOUBLE)); + registerFunction( PostGISDialect.NAMESPACE + "buffer", new StandardSQLFunction("buffer", Hibernate.custom(GeometryType.class))); + registerFunction( PostGISDialect.NAMESPACE + "convexhull", new StandardSQLFunction("convexhull", Hibernate.custom(GeometryType.class))); + registerFunction( PostGISDialect.NAMESPACE + "intersection", new StandardSQLFunction("intersection", Hibernate.custom(GeometryType.class))); + registerFunction( PostGISDialect.NAMESPACE + "union", new StandardSQLFunction("geomunion", Hibernate.custom(GeometryType.class))); + registerFunction( PostGISDialect.NAMESPACE + "difference", new StandardSQLFunction("difference", Hibernate.custom(GeometryType.class))); + registerFunction( PostGISDialect.NAMESPACE + "symdifference", new StandardSQLFunction("symdifference", Hibernate.custom(GeometryType.class))); + registerFunction( PostGISDialect.NAMESPACE + "numgeometries", new StandardSQLFunction("numgeometries", Hibernate.custom(GeometryType.class))); + registerFunction( PostGISDialect.NAMESPACE + "geometryn", new StandardSQLFunction("geometryn", Hibernate.INTEGER)); + registerFunction( PostGISDialect.NAMESPACE + "x", new StandardSQLFunction("x", Hibernate.DOUBLE)); + registerFunction( PostGISDialect.NAMESPACE + "y", new StandardSQLFunction("y", Hibernate.DOUBLE)); + registerFunction( PostGISDialect.NAMESPACE + "geometryfromewtk", new StandardSQLFunction("geometryfromewtk", Hibernate.custom(GeometryType.class))); + } +} diff --git a/java/ejb3/src/org/postgis/hibernate/WithinExpression.java b/java/ejb3/src/org/postgis/hibernate/WithinExpression.java index a40e3636a..5fea03176 100644 --- a/java/ejb3/src/org/postgis/hibernate/WithinExpression.java +++ b/java/ejb3/src/org/postgis/hibernate/WithinExpression.java @@ -1,83 +1,83 @@ -/* - * WithinExpression.java - * - * PostGIS extension for PostgreSQL JDBC driver - EJB3 Tutorial - * - * (C) 2006 Norman Barker - * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at - * http://www.gnu.org. - * - * $Id$ - */ -package org.postgis.hibernate; - -import java.util.ArrayList; -import java.util.List; - -import org.hibernate.Criteria; -import org.hibernate.EntityMode; -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; -import org.hibernate.criterion.CriteriaQuery; -import org.hibernate.criterion.Criterion; -import org.hibernate.dialect.Dialect; -import org.hibernate.dialect.function.StandardSQLFunction; -import org.hibernate.engine.TypedValue; -import org.postgis.Geometry; - -/** - * @author nbarker - * - */ -public class WithinExpression implements Criterion{ - private static final long serialVersionUID = 1L; - private String propertyName; - private Geometry geom; - - public WithinExpression(String propertyName, Geometry geom) - { - this.propertyName = propertyName; - this.geom = geom; - } - - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return new TypedValue[]{new TypedValue(Hibernate.custom(GeometryType.class), geom, EntityMode.POJO)}; - } - - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - Dialect dialect = criteriaQuery.getFactory().getDialect(); - String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName); - - if (columns.length != 1) throw new HibernateException("\"within\" may only be used with single-column properties"); - if ( dialect instanceof PostGISDialect) { - StandardSQLFunction function = (StandardSQLFunction)dialect.getFunctions().get(PostGISDialect.NAMESPACE + "within"); - List args = new ArrayList(); - args.add(columns[0]); - args.add("?"); - - return function.render(args, criteriaQuery.getFactory()); - } - else - { - throw new HibernateException("\"within\" may only be used with a spatial hibernate dialect"); - } - } - - public String toString() - { - return propertyName + " within " + geom; - } - -} +/* + * WithinExpression.java + * + * PostGIS extension for PostgreSQL JDBC driver - EJB3 Tutorial + * + * (C) 2006 Norman Barker + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at + * http://www.gnu.org. + * + * $Id$ + */ +package org.postgis.hibernate; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.Criteria; +import org.hibernate.EntityMode; +import org.hibernate.Hibernate; +import org.hibernate.HibernateException; +import org.hibernate.criterion.CriteriaQuery; +import org.hibernate.criterion.Criterion; +import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.function.StandardSQLFunction; +import org.hibernate.engine.TypedValue; +import org.postgis.Geometry; + +/** + * @author nbarker + * + */ +public class WithinExpression implements Criterion{ + private static final long serialVersionUID = 1L; + private String propertyName; + private Geometry geom; + + public WithinExpression(String propertyName, Geometry geom) + { + this.propertyName = propertyName; + this.geom = geom; + } + + public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { + return new TypedValue[]{new TypedValue(Hibernate.custom(GeometryType.class), geom, EntityMode.POJO)}; + } + + public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { + Dialect dialect = criteriaQuery.getFactory().getDialect(); + String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName); + + if (columns.length != 1) throw new HibernateException("\"within\" may only be used with single-column properties"); + if ( dialect instanceof PostGISDialect) { + StandardSQLFunction function = (StandardSQLFunction)dialect.getFunctions().get(PostGISDialect.NAMESPACE + "within"); + List args = new ArrayList(); + args.add(columns[0]); + args.add("?"); + + return function.render(args, criteriaQuery.getFactory()); + } + else + { + throw new HibernateException("\"within\" may only be used with a spatial hibernate dialect"); + } + } + + public String toString() + { + return propertyName + " within " + geom; + } + +} diff --git a/java/jdbc/jtssrc/pom.xml b/java/jdbc/jtssrc/pom.xml index c5c6254e5..44f662703 100644 --- a/java/jdbc/jtssrc/pom.xml +++ b/java/jdbc/jtssrc/pom.xml @@ -1,165 +1,165 @@ - - - 4.0.0 - - org.postgis - postgis-jdbc-jtsparser - 2.0.0 - jar - - Postgis JDBC Driver JTS Parser - http://www.postgis.org - Parser between JTS and PostGIS geometry formats. - - - - GNU Lesser General Public License - http://www.gnu.org/licenses/lgpl-2.1.txt - repo - - - - - - Postgis Development Team - - - María Arias de Reyna - delawen en gmail.com - - - - - Hakan Tandogan - hakan@gurkensalat.com - http://www.gurkensalat.com/ - - Maven Packager - - - - - - User List - postgis-users-subscribe@postgis.refractions.net - postgis-users-unsubscribe@postgis.refractions.net - postgis-users@postgis.refractions.net - http://postgis.refractions.net/pipermail/postgis-users/ - - - Developer List - postgis-devel-subscribe@postgis.refractions.net - postgis-devel-unsubscribe@postgis.refractions.net - postgis-devel@postgis.refractions.net - http://postgis.refractions.net/pipermail/postgis-devel/ - - - - Trac - http://trac.osgeo.org/postgis/ - - - http://trac.osgeo.org/postgis/browser/tags/2.0.0 - scm:svn:http://svn.osgeo.org/postgis/tags/2.0.0/ - scm:svn:http://svn.osgeo.org/postgis/tags/2.0.0/ - - - - ${basedir}/org - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - verify - - jar - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - - attach-javadocs - verify - - jar - - - - - - - - - - - org.postgis - postgis-jdbc - 2.0.0 - - - com.vividsolutions - jts - 1.12 - - - - - - - maven-javadoc-plugin - - - maven-dependency-plugin - - - maven-project-info-reports-plugin - - - maven-surefire-report-plugin - - - org.codehaus.mojo - findbugs-maven-plugin - - - org.codehaus.mojo - javancss-maven-plugin - - - org.codehaus.mojo - jdepend-maven-plugin - - - org.codehaus.mojo - jxr-maven-plugin - - - org.codehaus.mojo - taglist-maven-plugin - - - org.codehaus.mojo - versions-maven-plugin - - - - - - - - sonatype-postgis-releases - Sonatype Postgis Releases Repo - http://oss.sonatype.org/content/repositories/postgis-releases - - - + + + 4.0.0 + + org.postgis + postgis-jdbc-jtsparser + 2.0.0 + jar + + Postgis JDBC Driver JTS Parser + http://www.postgis.org + Parser between JTS and PostGIS geometry formats. + + + + GNU Lesser General Public License + http://www.gnu.org/licenses/lgpl-2.1.txt + repo + + + + + + Postgis Development Team + + + María Arias de Reyna + delawen en gmail.com + + + + + Hakan Tandogan + hakan@gurkensalat.com + http://www.gurkensalat.com/ + + Maven Packager + + + + + + User List + postgis-users-subscribe@postgis.refractions.net + postgis-users-unsubscribe@postgis.refractions.net + postgis-users@postgis.refractions.net + http://postgis.refractions.net/pipermail/postgis-users/ + + + Developer List + postgis-devel-subscribe@postgis.refractions.net + postgis-devel-unsubscribe@postgis.refractions.net + postgis-devel@postgis.refractions.net + http://postgis.refractions.net/pipermail/postgis-devel/ + + + + Trac + http://trac.osgeo.org/postgis/ + + + http://trac.osgeo.org/postgis/browser/tags/2.0.0 + scm:svn:http://svn.osgeo.org/postgis/tags/2.0.0/ + scm:svn:http://svn.osgeo.org/postgis/tags/2.0.0/ + + + + ${basedir}/org + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + verify + + jar + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + verify + + jar + + + + + + + + + + + org.postgis + postgis-jdbc + 2.0.0 + + + com.vividsolutions + jts + 1.12 + + + + + + + maven-javadoc-plugin + + + maven-dependency-plugin + + + maven-project-info-reports-plugin + + + maven-surefire-report-plugin + + + org.codehaus.mojo + findbugs-maven-plugin + + + org.codehaus.mojo + javancss-maven-plugin + + + org.codehaus.mojo + jdepend-maven-plugin + + + org.codehaus.mojo + jxr-maven-plugin + + + org.codehaus.mojo + taglist-maven-plugin + + + org.codehaus.mojo + versions-maven-plugin + + + + + + + + sonatype-postgis-releases + Sonatype Postgis Releases Repo + http://oss.sonatype.org/content/repositories/postgis-releases + + + diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 5315dc164..e7cedd46d 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -1,182 +1,182 @@ - - - 4.0.0 - - org.postgis - postgis-jdbc - ${POSTGIS_MAJOR_VERSION}.${POSTGIS_MINOR_VERSION}.${POSTGIS_MICRO_VERSION} - jar - - Postgis JDBC Driver - http://www.postgis.org - PostGIS adds support for geographic objects to the PostgreSQL object-relational database. - - - - GNU Lesser General Public License - http://www.gnu.org/licenses/lgpl-2.1.txt - repo - - - - - - Postgis Development Team - - - María Arias de Reyna - delawen en gmail.com - - - - - Hakan Tandogan - hakan@gurkensalat.com - http://www.gurkensalat.com/ - - Maven Packager - - - - - - User List - postgis-users-subscribe@postgis.refractions.net - postgis-users-unsubscribe@postgis.refractions.net - postgis-users@postgis.refractions.net - http://postgis.refractions.net/pipermail/postgis-users/ - - - Developer List - postgis-devel-subscribe@postgis.refractions.net - postgis-devel-unsubscribe@postgis.refractions.net - postgis-devel@postgis.refractions.net - http://postgis.refractions.net/pipermail/postgis-devel/ - - - - Trac - http://trac.osgeo.org/postgis/ - - - http://trac.osgeo.org/postgis/browser/tags/2.0.0 - scm:svn:http://svn.osgeo.org/postgis/tags/2.0.0/ - scm:svn:http://svn.osgeo.org/postgis/tags/2.0.0/ - - - - - ${basedir}/src - - - - src - true - - **/*.properties - - - **/*.java - - - - - - - - - - - - postgresql - postgresql - 9.1-901.jdbc3 - - - - - - maven-javadoc-plugin - - - maven-dependency-plugin - - - maven-project-info-reports-plugin - - - maven-surefire-report-plugin - - - org.codehaus.mojo - findbugs-maven-plugin - - - org.codehaus.mojo - javancss-maven-plugin - - - org.codehaus.mojo - jdepend-maven-plugin - - - org.codehaus.mojo - jxr-maven-plugin - - - org.codehaus.mojo - taglist-maven-plugin - - - org.codehaus.mojo - versions-maven-plugin - - - - - - - - sonatype-postgis-releases - Sonatype Postgis Releases Repo - http://oss.sonatype.org/content/repositories/postgis-releases - - - - - - 2 - 0 - 0 - - - + + + 4.0.0 + + org.postgis + postgis-jdbc + ${POSTGIS_MAJOR_VERSION}.${POSTGIS_MINOR_VERSION}.${POSTGIS_MICRO_VERSION} + jar + + Postgis JDBC Driver + http://www.postgis.org + PostGIS adds support for geographic objects to the PostgreSQL object-relational database. + + + + GNU Lesser General Public License + http://www.gnu.org/licenses/lgpl-2.1.txt + repo + + + + + + Postgis Development Team + + + María Arias de Reyna + delawen en gmail.com + + + + + Hakan Tandogan + hakan@gurkensalat.com + http://www.gurkensalat.com/ + + Maven Packager + + + + + + User List + postgis-users-subscribe@postgis.refractions.net + postgis-users-unsubscribe@postgis.refractions.net + postgis-users@postgis.refractions.net + http://postgis.refractions.net/pipermail/postgis-users/ + + + Developer List + postgis-devel-subscribe@postgis.refractions.net + postgis-devel-unsubscribe@postgis.refractions.net + postgis-devel@postgis.refractions.net + http://postgis.refractions.net/pipermail/postgis-devel/ + + + + Trac + http://trac.osgeo.org/postgis/ + + + http://trac.osgeo.org/postgis/browser/tags/2.0.0 + scm:svn:http://svn.osgeo.org/postgis/tags/2.0.0/ + scm:svn:http://svn.osgeo.org/postgis/tags/2.0.0/ + + + + + ${basedir}/src + + + + src + true + + **/*.properties + + + **/*.java + + + + + + + + + + + + postgresql + postgresql + 9.1-901.jdbc3 + + + + + + maven-javadoc-plugin + + + maven-dependency-plugin + + + maven-project-info-reports-plugin + + + maven-surefire-report-plugin + + + org.codehaus.mojo + findbugs-maven-plugin + + + org.codehaus.mojo + javancss-maven-plugin + + + org.codehaus.mojo + jdepend-maven-plugin + + + org.codehaus.mojo + jxr-maven-plugin + + + org.codehaus.mojo + taglist-maven-plugin + + + org.codehaus.mojo + versions-maven-plugin + + + + + + + + sonatype-postgis-releases + Sonatype Postgis Releases Repo + http://oss.sonatype.org/content/repositories/postgis-releases + + + + + + 2 + 0 + 0 + + + diff --git a/libpgcommon/common.h b/libpgcommon/common.h index 452c69603..ca6371b37 100644 --- a/libpgcommon/common.h +++ b/libpgcommon/common.h @@ -1,5 +1,5 @@ /********************************************************************** - * $Id: $ + * $Id$ * * PostGIS - Spatial Types for PostgreSQL * http://postgis.refractions.net diff --git a/raster/scripts/plpgsql/st_addband.sql b/raster/scripts/plpgsql/st_addband.sql index ce73fd216..d69744502 100644 --- a/raster/scripts/plpgsql/st_addband.sql +++ b/raster/scripts/plpgsql/st_addband.sql @@ -1,54 +1,54 @@ ----------------------------------------------------------------------- --- --- $Id: st_addband.sql 6127 2010-10-25 16:06:00Z jorgearevalo $ --- --- Copyright (c) 2009-2010 Pierre Racine --- ----------------------------------------------------------------------- - --- NOTE: This function is provided merely as an example since a C version was implemented and is now provided in rtpostgis.sql - -CREATE OR REPLACE FUNCTION ST_AddBand(rast1 raster, rast2 raster, band int, index int) - RETURNS raster AS - $$ - DECLARE - newraster raster; - newnodatavalue int; - newindex int := index; - newband int := band; - x int; - y int; - BEGIN - IF ST_Width(rast1) != ST_Width(rast2) OR ST_Height(rast1) != ST_Height(rast2) THEN - RAISE EXCEPTION 'ST_AddBand: Attempting to add a band with different width or height'; - END IF; - IF newindex < 1 THEN - newindex := 1; - END IF; - IF newindex IS NULL OR newindex > ST_NumBands(rast1) THEN - newindex := ST_NumBands(rast1) + 1; - END IF; - IF newband < 1 THEN - newband := 1; - END IF; - IF newband IS NULL OR newband > ST_NumBands(rast2) THEN - newband := ST_NumBands(rast2); - END IF; - - IF newband = 0 THEN - RETURN rast1; - END IF; - newnodatavalue := ST_BandNodataValue(rast2, newband); - newraster := ST_AddBand(rast1, newindex, ST_BandPixelType(rast2, newband), newnodatavalue, newnodatavalue); - FOR x IN 1..ST_Width(rast2) LOOP - FOR y IN 1..ST_Height(rast2) LOOP - newraster := ST_SetValue(newraster, newindex, x, y, ST_Value(rast2, newband, x, y)); - END LOOP; - END LOOP; - RETURN newraster; - END; - $$ - LANGUAGE 'plpgsql'; - ---Test +---------------------------------------------------------------------- +-- +-- $Id: st_addband.sql 6127 2010-10-25 16:06:00Z jorgearevalo $ +-- +-- Copyright (c) 2009-2010 Pierre Racine +-- +---------------------------------------------------------------------- + +-- NOTE: This function is provided merely as an example since a C version was implemented and is now provided in rtpostgis.sql + +CREATE OR REPLACE FUNCTION ST_AddBand(rast1 raster, rast2 raster, band int, index int) + RETURNS raster AS + $$ + DECLARE + newraster raster; + newnodatavalue int; + newindex int := index; + newband int := band; + x int; + y int; + BEGIN + IF ST_Width(rast1) != ST_Width(rast2) OR ST_Height(rast1) != ST_Height(rast2) THEN + RAISE EXCEPTION 'ST_AddBand: Attempting to add a band with different width or height'; + END IF; + IF newindex < 1 THEN + newindex := 1; + END IF; + IF newindex IS NULL OR newindex > ST_NumBands(rast1) THEN + newindex := ST_NumBands(rast1) + 1; + END IF; + IF newband < 1 THEN + newband := 1; + END IF; + IF newband IS NULL OR newband > ST_NumBands(rast2) THEN + newband := ST_NumBands(rast2); + END IF; + + IF newband = 0 THEN + RETURN rast1; + END IF; + newnodatavalue := ST_BandNodataValue(rast2, newband); + newraster := ST_AddBand(rast1, newindex, ST_BandPixelType(rast2, newband), newnodatavalue, newnodatavalue); + FOR x IN 1..ST_Width(rast2) LOOP + FOR y IN 1..ST_Height(rast2) LOOP + newraster := ST_SetValue(newraster, newindex, x, y, ST_Value(rast2, newband, x, y)); + END LOOP; + END LOOP; + RETURN newraster; + END; + $$ + LANGUAGE 'plpgsql'; + +--Test SELECT ST_NumBands(ST_AddBand(ST_TestRaster(0, 0, 1), ST_TestRaster(0, 0, 1), 1, 2)) \ No newline at end of file diff --git a/raster/scripts/plpgsql/st_geomextent2rastercoord.sql b/raster/scripts/plpgsql/st_geomextent2rastercoord.sql index 65f6ba1ed..8445abfd2 100644 --- a/raster/scripts/plpgsql/st_geomextent2rastercoord.sql +++ b/raster/scripts/plpgsql/st_geomextent2rastercoord.sql @@ -1,102 +1,102 @@ -DROP FUNCTION ST_GeomExtent2RasterCoord(rast raster, geomin geometry); -CREATE OR REPLACE FUNCTION ST_GeomExtent2RasterCoord(rast raster, - geomin geometry) - RETURNS int[] AS - $$ - DECLARE - geomintersect geometry; - x1w double precision := 0.0; - x2w double precision := 0.0; - y1w double precision := 0.0; - y2w double precision := 0.0; - x1 integer := 0; - x2 integer := 0; - x3 integer := 0; - x4 integer := 0; - y1 integer := 0; - y2 integer := 0; - y3 integer := 0; - y4 integer := 0; - psize float8; - BEGIN - - -- Get the intersection between with the geometry. - -- We will search for withvalue pixel only in this area. - geomintersect := st_intersection(geomin, st_convexhull(rast)); ---RAISE NOTICE 'geomintersect1=%', astext(geomintersect); - - -- If the intersection is empty, return false - IF st_isempty(geomintersect) THEN - RETURN ARRAY[NULL, NULL, NULL, NULL]; - END IF; - - -- We create a minimalistic buffer around the intersection in order to scan every pixels - -- that would touch the edge or intersect with the geometry - psize := st_scalex(rast) + st_skewy(rast); - geomintersect := st_buffer(geomintersect, psize / 1000000); - ---RAISE NOTICE 'geomintersect2=%', astext(geomintersect); - - -- Find the world coordinates of the bounding box of the intersecting area - x1w := st_xmin(geomintersect); - y1w := st_ymin(geomintersect); - x2w := st_xmax(geomintersect); - y2w := st_ymax(geomintersect); - ---RAISE NOTICE 'x1w=%, y1w=%, x2w=%, y2w=%', x1w, y1w, x2w, y2w; - - -- Convert world coordinates to raster coordinates - x1 := st_world2rastercoordx(rast, x1w, y1w); - y1 := st_world2rastercoordy(rast, x1w, y1w); - x2 := st_world2rastercoordx(rast, x2w, y1w); - y2 := st_world2rastercoordy(rast, x2w, y1w); - x3 := st_world2rastercoordx(rast, x1w, y2w); - y3 := st_world2rastercoordy(rast, x1w, y2w); - x4 := st_world2rastercoordx(rast, x2w, y2w); - y4 := st_world2rastercoordy(rast, x2w, y2w); - ---RAISE NOTICE 'x1=%, y1=%, x2=%, y2=%, x3=%, y3=%, x4=%, y4=%', x1, y1, x2, y2, x3, y3, x4, y4; - - -- Order the raster coordinates for the upcoming FOR loop. - x1 := int4smaller(int4smaller(int4smaller(x1, x2), x3), x4); - y1 := int4smaller(int4smaller(int4smaller(y1, y2), y3), y4); - x2 := int4larger(int4larger(int4larger(x1, x2), x3), x4); - y2 := int4larger(int4larger(int4larger(y1, y2), y3), y4); - - -- Make sure the range is not lower than 1. - -- This can happen when world coordinate are exactly on the left border - -- of the raster and that they do not span on more than one pixel. - x1 := int4smaller(int4larger(x1, 1), st_width(rast)); - y1 := int4smaller(int4larger(y1, 1), st_height(rast)); - - -- Also make sure the range does not exceed the width and height of the raster. - -- This can happen when world coordinate are exactly on the lower right border - -- of the raster. - x2 := int4smaller(x2, st_width(rast)); - y2 := int4smaller(y2, st_height(rast)); - - RETURN ARRAY[x1, y1, x2, y2]; - - END; - $$ - LANGUAGE 'plpgsql' IMMUTABLE STRICT; - ---Test -SELECT (gvxy).geom, (gvxy).x::text || ',' || (gvxy).y::text -FROM (SELECT DISTINCT rid, ST_PixelAsPolygons(rast) gvxy - FROM srtm_22_03_tiled, rect3 - WHERE st_intersects(rast, geom) - ) foo - -SELECT DISTINCT rid -FROM srtm_22_03_tiled, rect3 -WHERE st_intersects(rast, geom) - - -SELECT rid, id, ST_GeomExtent2RasterCoord(rast, geom) -FROM srtm_22_03_tiled, rect3 -WHERE st_intersects(rast, geom) - - -SELECT (ext).x1, (ext).y1, (ext).x2, (ext).y2 FROM (SELECT ST_GeomExtent2RasterCoord(rast, geom) ext FROM srtm_22_03_tiled, rect3 +DROP FUNCTION ST_GeomExtent2RasterCoord(rast raster, geomin geometry); +CREATE OR REPLACE FUNCTION ST_GeomExtent2RasterCoord(rast raster, + geomin geometry) + RETURNS int[] AS + $$ + DECLARE + geomintersect geometry; + x1w double precision := 0.0; + x2w double precision := 0.0; + y1w double precision := 0.0; + y2w double precision := 0.0; + x1 integer := 0; + x2 integer := 0; + x3 integer := 0; + x4 integer := 0; + y1 integer := 0; + y2 integer := 0; + y3 integer := 0; + y4 integer := 0; + psize float8; + BEGIN + + -- Get the intersection between with the geometry. + -- We will search for withvalue pixel only in this area. + geomintersect := st_intersection(geomin, st_convexhull(rast)); +--RAISE NOTICE 'geomintersect1=%', astext(geomintersect); + + -- If the intersection is empty, return false + IF st_isempty(geomintersect) THEN + RETURN ARRAY[NULL, NULL, NULL, NULL]; + END IF; + + -- We create a minimalistic buffer around the intersection in order to scan every pixels + -- that would touch the edge or intersect with the geometry + psize := st_scalex(rast) + st_skewy(rast); + geomintersect := st_buffer(geomintersect, psize / 1000000); + +--RAISE NOTICE 'geomintersect2=%', astext(geomintersect); + + -- Find the world coordinates of the bounding box of the intersecting area + x1w := st_xmin(geomintersect); + y1w := st_ymin(geomintersect); + x2w := st_xmax(geomintersect); + y2w := st_ymax(geomintersect); + +--RAISE NOTICE 'x1w=%, y1w=%, x2w=%, y2w=%', x1w, y1w, x2w, y2w; + + -- Convert world coordinates to raster coordinates + x1 := st_world2rastercoordx(rast, x1w, y1w); + y1 := st_world2rastercoordy(rast, x1w, y1w); + x2 := st_world2rastercoordx(rast, x2w, y1w); + y2 := st_world2rastercoordy(rast, x2w, y1w); + x3 := st_world2rastercoordx(rast, x1w, y2w); + y3 := st_world2rastercoordy(rast, x1w, y2w); + x4 := st_world2rastercoordx(rast, x2w, y2w); + y4 := st_world2rastercoordy(rast, x2w, y2w); + +--RAISE NOTICE 'x1=%, y1=%, x2=%, y2=%, x3=%, y3=%, x4=%, y4=%', x1, y1, x2, y2, x3, y3, x4, y4; + + -- Order the raster coordinates for the upcoming FOR loop. + x1 := int4smaller(int4smaller(int4smaller(x1, x2), x3), x4); + y1 := int4smaller(int4smaller(int4smaller(y1, y2), y3), y4); + x2 := int4larger(int4larger(int4larger(x1, x2), x3), x4); + y2 := int4larger(int4larger(int4larger(y1, y2), y3), y4); + + -- Make sure the range is not lower than 1. + -- This can happen when world coordinate are exactly on the left border + -- of the raster and that they do not span on more than one pixel. + x1 := int4smaller(int4larger(x1, 1), st_width(rast)); + y1 := int4smaller(int4larger(y1, 1), st_height(rast)); + + -- Also make sure the range does not exceed the width and height of the raster. + -- This can happen when world coordinate are exactly on the lower right border + -- of the raster. + x2 := int4smaller(x2, st_width(rast)); + y2 := int4smaller(y2, st_height(rast)); + + RETURN ARRAY[x1, y1, x2, y2]; + + END; + $$ + LANGUAGE 'plpgsql' IMMUTABLE STRICT; + +--Test +SELECT (gvxy).geom, (gvxy).x::text || ',' || (gvxy).y::text +FROM (SELECT DISTINCT rid, ST_PixelAsPolygons(rast) gvxy + FROM srtm_22_03_tiled, rect3 + WHERE st_intersects(rast, geom) + ) foo + +SELECT DISTINCT rid +FROM srtm_22_03_tiled, rect3 +WHERE st_intersects(rast, geom) + + +SELECT rid, id, ST_GeomExtent2RasterCoord(rast, geom) +FROM srtm_22_03_tiled, rect3 +WHERE st_intersects(rast, geom) + + +SELECT (ext).x1, (ext).y1, (ext).x2, (ext).y2 FROM (SELECT ST_GeomExtent2RasterCoord(rast, geom) ext FROM srtm_22_03_tiled, rect3 WHERE st_intersects(rast, geom)) foo \ No newline at end of file diff --git a/raster/scripts/plpgsql/st_mapalgebra_optimized.sql b/raster/scripts/plpgsql/st_mapalgebra_optimized.sql index a1f4bef48..eaebcaf75 100644 --- a/raster/scripts/plpgsql/st_mapalgebra_optimized.sql +++ b/raster/scripts/plpgsql/st_mapalgebra_optimized.sql @@ -1,652 +1,652 @@ ----------------------------------------------------------------------- --- --- $Id: st_mapalgebra_optimized.sql 6127 2010-10-25 16:06:00Z jorgearevalo $ --- --- Copyright (c) 2009-2010 Pierre Racine --- ----------------------------------------------------------------------- - --- Note: The functions provided in this script are in developement. Do not use. - --- Note: this script is dependent on --- _MapAlgebraParts(r1x int, r1y int, r1w int, r1h int, r2x int, r2y int, r2w int, r2h int) --- ST_SameAlignment(rast1ulx float8, rast1uly float8, rast1scalex float8, rast1scaley float8, rast1skewx float8, rast1skewy float8, rast2ulx float8, rast2uly float8, rast2scalex float8, rast2scaley float8, rast2skewx float8, rast2skewy float8) --- ST_IsEmpty(raster) --- ST_HasNoBand(raster, int) --- ST_BandIsNoData(raster, int) --- to be found in the script/plpgsql folder - --------------------------------------------------------------------- --- ST_MapAlgebra - (two rasters version) Return a raster which --- values are the result of an SQL expression involving --- pixel values from input rasters bands. --- Arguments --- rast1 raster - First raster referred by rast1 in the expression. --- band1 integer - Band number of the first raster. Default to 1. --- rast2 raster - Second raster referred by rast2 in the expression. --- band2 integer - Band number of the second raster. Default to 1. --- expression text - SQL expression. Ex.: "rast1 + 2 * rast2" --- pixeltype text - Pixeltype assigned to the resulting raster. Expression --- results are truncated to this type. Default to the --- pixeltype of the first raster. --- extentexpr text - Raster extent of the result. Can be: --- -FIRST: Same extent as the first raster. Default. --- -SECOND: Same extent as the second) raster. Default. --- -INTERSECTION: Intersection of extent of the two rasters. --- -UNION: Union oof extent of the two rasters. --- nodata1expr text - Expression used when only rast1 pixel value are nodata or absent, i.e. rast2 pixel value is with data. --- nodata2expr text - Expression used when only rast2 pixel value are nodata or absent, i.e. rast1 pixel value is with data. --- nodatanodataexpr text - Expression used when both pixel values are nodata values or absent. - --- Further enhancements: --- -Move the expression parameter in seventh position just before other expression parameters. --- -Optimization for UNION & FIRST. We might not have to iterate over all the new raster. See st_mapalgebra_optimized.sql --- -Add the possibility to assign the x or y coordinate of the pixel to the pixel (do the same to the one raster version). --- -Resample the second raster when necessary (Require ST_Resample) --- -More test with rotated images --------------------------------------------------------------------- -CREATE OR REPLACE FUNCTION ST_MapAlgebra2(rast1 raster, - band1 integer, - rast2 raster, - band2 integer, - expression text, - pixeltype text, - extentexpr text, - nodata1expr text, - nodata2expr text, - nodatanodataexpr text) - RETURNS raster AS - $$ - DECLARE - x integer; - y integer; - r1 float; - r2 float; - rast1ulx float8; - rast1uly float8; - rast1width int; - rast1height int; - rast1scalex float8; - rast1scaley float8; - rast1skewx float8; - rast1skewy float8; - rast1nodataval float8; - rast1srid int; - - rast1offsetx int; - rast1offsety int; - - rast2ulx float8; - rast2uly float8; - rast2width int; - rast2height int; - rast2scalex float8; - rast2scaley float8; - rast2skewx float8; - rast2skewy float8; - rast2nodataval float8; - rast2srid int; - - r1x int; - r1y int; - r1w int; - r1h int; - r2x int; - r2y int; - r2w int; - r2h int; - - newrx int; - newry int; - - newrast raster; - tmprast raster; - newsrid int; - - newscalex float8; - newscaley float8; - newskewx float8; - newskewy float8; - newnodatavalue float8; - newpixeltype text; - newulx float8; - newuly float8; - newwidth int; - newheight int; - newoffsetx1 int; - newoffsety1 int; - newoffsetx2 int; - newoffsety2 int; - - newval float; - newexpr text; - upnodatanodataexpr text; - upnodata1expr text; - upnodata2expr text; - upexpression text; - nodatanodataval float; - skipcomputation int; - - zones int[]; - z11x int; - z11y int; - z11w int; - z11h int; - z12x int; - z12y int; - z12w int; - z12h int; - z13x int; - z13y int; - z13w int; - z13h int; - z14x int; - z14y int; - z14w int; - z14h int; - z21x int; - z21y int; - z21w int; - z21h int; - z22x int; - z22y int; - z22w int; - z22h int; - z23x int; - z23y int; - z23w int; - z23h int; - z24x int; - z24y int; - z24w int; - z24h int; - zcx int; - zcy int; - zcw int; - zch int; - - BEGIN - -- We have to deal with NULL, empty, hasnoband and hasnodatavalue band rasters... - -- These are respectively tested by "IS NULL", "ST_IsEmpty()", "ST_HasNoBand()" and "ST_BandIsNodata()" - - -- If both raster are null, we return NULL. ok - -- If both raster do not have extent (are empty), we return an empty raster. ok - -- If both raster do not have the specified band, - -- we return a no band raster with the correct extent (according to the extent expression). ok - -- If both raster bands are nodatavalue and there is no replacement value, we return a nodata value band. ok - - -- If only one raster is null or empty or has no band or hasnodata band we treat it as a nodata band raster. - -- If there is a replacement value we replace the missing raster values with this replacement value. ok - -- If there is no replacement value, we return a nodata value band. ok - - -- What to do when only one raster is NULL or empty - -- If the extent expression is FIRST and the first raster is null we return NULL. ok - -- If the extent expression is FIRST and the first raster do not have extent (is empty), we return an empty raster. ok - -- If the extent expression is SECOND and the second raster is null we return NULL. ok - -- If the extent expression is SECOND and the second raster do not have extent (is empty), we return an empty raster. ok - -- If the extent expression is INTERSECTION and one raster is null or do not have extent (is empty), we return an empty raster. ok - -- If the extent expression is UNION and one raster is null or do not have extent (is empty), - -- we return a raster having the extent and the band characteristics of the other raster. ok - - -- What to do when only one raster do not have the required band. - -- If the extent expression is FIRST and the first raster do not have the specified band, - -- we return a no band raster with the correct extent (according to the extent expression). ok - -- If the extent expression is SECOND and the second raster do not have the specified band, - -- we return a no band raster with the correct extent (according to the extent expression). ok - -- If the extent expression is INTERSECTION and one raster do not have the specified band, - -- we treat it as a nodata raster band. ok - -- If the extent expression is UNION and one raster do not have the specified band, - -- we treat it as a nodata raster band. ok - - -- In all those cases, we make a warning. - - -- Check if both rasters are NULL -RAISE NOTICE 'ST_MapAlgebra2 000'; - - IF rast1 IS NULL AND rast2 IS NULL THEN - RAISE NOTICE 'ST_MapAlgebra: Both raster are NULL. Returning NULL'; - RETURN NULL; - END IF; - - -- Check if both rasters are empty (width or height = 0) - IF ST_IsEmpty(rast1) AND ST_IsEmpty(rast2) THEN - RAISE NOTICE 'ST_MapAlgebra: Both raster are empty. Returning an empty raster'; - RETURN ST_MakeEmptyRaster(0, 0, 0, 0, 0, 0, 0, 0, -1); - END IF; - - rast1ulx := ST_UpperLeftX(rast1); - rast1uly := ST_UpperLeftY(rast1); - rast1width := ST_Width(rast1); - rast1height := ST_Height(rast1); - rast1scalex := ST_ScaleX(rast1); - rast1scaley := ST_ScaleY(rast1); - rast1skewx := ST_SkewX(rast1); - rast1skewy := ST_SkewY(rast1); - rast1srid := ST_SRID(rast1); - - rast2ulx := ST_UpperLeftX(rast2); - rast2uly := ST_UpperLeftY(rast2); - rast2width := ST_Width(rast2); - rast2height := ST_Height(rast2); - rast2scalex := ST_ScaleX(rast2); - rast2scaley := ST_ScaleY(rast2); - rast2skewx := ST_SkewX(rast2); - rast2skewy := ST_SkewY(rast2); - rast2srid := ST_SRID(rast2); - - -- Check if the first raster is NULL or empty - IF rast1 IS NULL OR ST_IsEmpty(rast1) THEN - rast1ulx := rast2ulx; - rast1uly := rast2uly; - rast1width := rast2width; - rast1height := rast2height; - rast1scalex := rast2scalex; - rast1scaley := rast2scaley; - rast1skewx := rast2skewx; - rast1skewy := rast2skewy; - rast1srid := rast2srid; - END IF; - -- Check if the second raster is NULL or empty - IF rast2 IS NULL OR ST_IsEmpty(rast2) THEN - rast2ulx := rast1ulx; - rast2uly := rast1uly; - rast2width := rast1width; - rast2height := rast1height; - rast2scalex := rast1scalex; - rast2scaley := rast1scaley; - rast2skewx := rast1skewx; - rast2skewy := rast1skewy; - rast2srid := rast1srid; - END IF; - - -- Check for SRID - IF rast1srid != rast2srid THEN - RAISE EXCEPTION 'ST_MapAlgebra: Provided raster with different SRID. Aborting'; - END IF; - newsrid := rast1srid; - - -- Check for alignment. (Rotation problem here) - IF NOT ST_SameAlignment(rast1ulx, rast1uly, rast1scalex, rast1scaley, rast1skewx, rast1skewy, rast2ulx, rast2uly, rast2scalex, rast2scaley, rast2skewx, rast2skewy) THEN - -- For now print an error message, but a more robust implementation should resample the second raster to the alignment of the first raster. - RAISE EXCEPTION 'ST_MapAlgebra: Provided raster do not have the same alignment. Aborting'; - END IF; - - -- Set new pixel size and skew. We set it to the rast1 scale and skew - -- since both rasters are aligned and thus have the same scale and skew - newscalex := rast1scalex; - newscaley := rast1scaley; - newskewx := rast1skewx; - newskewy := rast1skewy; - - --r1x & r2x are the offset of each rasters relatively to global extent - r1x := 0; - r2x := -st_world2rastercoordx(rast2, rast1ulx, rast1uly) + 1; - IF r2x < 0 THEN - r1x := -r2x; - r2x := 0; - END IF; - r1y := 0; - r2y := -st_world2rastercoordy(rast2, rast1ulx, rast1uly) + 1; - IF r2y < 0 THEN - r1y := -r2y; - r2y := 0; - END IF; - - r1w := rast1width; - r1h := rast1height; - r2w := rast2width; - r2h := rast2height; - - zones := _MapAlgebraParts(r1x + 1, r1y + 1, r1w, r1h, r2x + 1, r2y + 1, r2w, r2h); - z11x := zones[1]; - z11y := zones[2]; - z11w := zones[3]; - z11h := zones[4]; - z12x := zones[5]; - z12y := zones[6]; - z12w := zones[7]; - z12h := zones[8]; - z13x := zones[9]; - z13y := zones[10]; - z13w := zones[11]; - z13h := zones[12]; - z14x := zones[13]; - z14y := zones[14]; - z14w := zones[15]; - z14h := zones[16]; - z21x := zones[17]; - z21y := zones[18]; - z21w := zones[19]; - z21h := zones[20]; - z22x := zones[21]; - z22y := zones[22]; - z22w := zones[23]; - z22h := zones[24]; - z23x := zones[25]; - z23y := zones[26]; - z23w := zones[27]; - z23h := zones[28]; - z24x := zones[29]; - z24y := zones[30]; - z24w := zones[31]; - z24h := zones[32]; - zcx := zones[33]; - zcy := zones[34]; - zcw := zones[35]; - zch := zones[36]; - - -- Compute x and y relative index of master and slave according to the extent expression (FIRST, SECOND, INTERSECTION or UNION) - IF extentexpr IS NULL OR upper(extentexpr) = 'FIRST' THEN - - -- Check if rast1 is NULL - IF rast1 IS NULL THEN - RAISE NOTICE 'ST_MapAlgebra: FIRST raster is NULL. Returning NULL'; - RETURN NULL; - END IF; - - -- Check if rast1 is empty - IF ST_IsEmpty(rast1) THEN - RAISE NOTICE 'ST_MapAlgebra: FIRST raster is empty. Returning an empty raster'; - RETURN ST_MakeEmptyRaster(0, 0, 0, 0, 0, 0, 0, 0, newsrid); - END IF; - - -- Check if rast1 has the required band - IF ST_HasNoBand(rast1, band1) THEN - RAISE NOTICE 'ST_MapAlgebra: FIRST raster has no band. Returning a raster without band'; - RETURN ST_MakeEmptyRaster(rast1width, rast1height, rast1ulx, rast1uly, rast1scalex, rast1scaley, rast1skewx, rast1skewy, rast1srid); - END IF; - - newulx := rast1ulx; - newuly := rast1uly; - newwidth := rast1width; - newheight := rast1height; - - newrx := r1x; - newry := r1y; - z21w := 0; - z22w := 0; - z23w := 0; - z24w := 0; - - ELSIF upper(extentexpr) = 'SECOND' THEN - - -- Check if rast2 is NULL - IF rast2 IS NULL THEN - RAISE NOTICE 'ST_MapAlgebra: SECOND raster is NULL. Returning NULL'; - RETURN NULL; - END IF; - - -- Check if rast2 is empty - IF ST_IsEmpty(rast2) THEN - RAISE NOTICE 'ST_MapAlgebra: SECOND raster is empty. Returning an empty raster'; - RETURN ST_MakeEmptyRaster(0, 0, 0, 0, 0, 0, 0, 0, newsrid); - END IF; - - -- Check if rast2 has the required band - IF ST_HasNoBand(rast2, band2) THEN - RAISE NOTICE 'ST_MapAlgebra: SECOND raster has no band. Returning an empty raster'; - RETURN ST_MakeEmptyRaster(rast2width, rast2height, rast2ulx, rast2uly, rast2scalex, rast2scaley, rast2skewx, rast2skewy, rast2srid); - END IF; - - newulx := rast2ulx; - newuly := rast2uly; - newwidth := rast2width; - newheight := rast2height; - - newrx := r2x; - newry := r2y; - z11w := 0; - z12w := 0; - z13w := 0; - z14w := 0; - - ELSIF upper(extentexpr) = 'INTERSECTION' THEN - - -- Check if the intersection is empty. - IF zcw = 0 OR zch = 0 OR - rast1 IS NULL OR ST_IsEmpty(rast1) OR - rast2 IS NULL OR ST_IsEmpty(rast2) THEN - RAISE NOTICE 'ST_MapAlgebra: INTERSECTION of provided rasters is empty. Returning an empty raster'; - RETURN ST_MakeEmptyRaster(0, 0, 0, 0, 0, 0, 0, 0, newsrid); - END IF; - - - -- Compute the new ulx and uly - newulx := st_raster2worldcoordx(rast1, zcx - r1x + 1, zcy - r1y + 1); - newuly := st_raster2worldcoordy(rast1, zcx - r1x + 1, zcy - r1y + 1); - newwidth := zcw; - newheight := zch; - - newrx := zcx; - newry := zcy; - z11w := 0; - z12w := 0; - z13w := 0; - z14w := 0; - z21w := 0; - z22w := 0; - z23w := 0; - z24w := 0; - - ELSIF upper(extentexpr) = 'UNION' THEN - - IF rast1 IS NULL OR ST_IsEmpty(rast1) THEN - newulx := rast2ulx; - newuly := rast2uly; - newwidth := rast2width; - newheight := rast2height; - - newrx := r2x; - newry := r2y; - z21w := 0; - z22w := 0; - z23w := 0; - z24w := 0; - ELSIF rast2 IS NULL OR ST_IsEmpty(rast2) THEN - newulx := rast1ulx; - newuly := rast1uly; - newwidth := rast1width; - newheight := rast1height; - - newrx := r1x; - newry := r1y; - z11w := 0; - z12w := 0; - z13w := 0; - z14w := 0; - ELSE - newrx := 0; - newry := 0; - - newulx := st_raster2worldcoordx(rast1, r1x + 1, r1y + 1); - newuly := st_raster2worldcoordy(rast1, r1x + 1, r1y + 1); - newwidth := max(r1x + r1w, r2x + r2w); - newheight := max(r1y + r1h, r2y + r2h); - - END IF; - ELSE - RAISE EXCEPTION 'ST_MapAlgebra: Unhandled extent expression "%". Only MASTER, INTERSECTION and UNION are accepted. Aborting.', upper(extentexpr); - END IF; - - -- Check if both rasters do not have the specified band. - IF ST_HasNoband(rast1, band1) AND ST_HasNoband(rast2, band2) THEN - RAISE NOTICE 'ST_MapAlgebra: Both raster do not have the specified band. Returning a no band raster with the correct extent'; - RETURN ST_MakeEmptyRaster(newwidth, newheight, newulx, newuly, newscalex, newscaley, newskewx, newskewy, newsrid); - END IF; - - -- Check newpixeltype - newpixeltype := pixeltype; - IF newpixeltype NOTNULL AND newpixeltype != '1BB' AND newpixeltype != '2BUI' AND newpixeltype != '4BUI' AND newpixeltype != '8BSI' AND newpixeltype != '8BUI' AND - newpixeltype != '16BSI' AND newpixeltype != '16BUI' AND newpixeltype != '32BSI' AND newpixeltype != '32BUI' AND newpixeltype != '32BF' AND newpixeltype != '64BF' THEN - RAISE EXCEPTION 'ST_MapAlgebra: Invalid pixeltype "%". Aborting.', newpixeltype; - END IF; - - -- If no newpixeltype was provided, get it from the provided rasters. - IF newpixeltype IS NULL THEN - IF (upper(extentexpr) = 'SECOND' AND NOT ST_HasNoBand(rast2, band2)) OR ST_HasNoBand(rast1, band1) THEN - newpixeltype := ST_BandPixelType(rast2, band2); - ELSE - newpixeltype := ST_BandPixelType(rast1, band1); - END IF; - END IF; - - -- Get the nodata value for first raster - IF NOT ST_HasNoBand(rast1, band1) AND ST_BandHasNodataValue(rast1, band1) THEN - rast1nodataval := ST_BandNodatavalue(rast1, band1); - ELSE - rast1nodataval := NULL; - END IF; - -- Get the nodata value for second raster - IF NOT ST_HasNoBand(rast2, band2) AND ST_BandHasNodatavalue(rast2, band2) THEN - rast2nodataval := ST_BandNodatavalue(rast2, band2); - ELSE - rast2nodataval := NULL; - END IF; - - -- Determine new notadavalue - IF (upper(extentexpr) = 'SECOND' AND NOT rast2nodataval IS NULL) THEN - newnodatavalue := rast2nodataval; - ELSEIF NOT rast1nodataval IS NULL THEN - newnodatavalue := rast1nodataval; - ELSE - RAISE NOTICE 'ST_MapAlgebra: Both source rasters do not have a nodata value, nodata value for new raster set to the minimum value possible'; - newnodatavalue := ST_MinPossibleValue(newrast); - END IF; - - upnodatanodataexpr := upper(nodatanodataexpr); - upnodata1expr := upper(nodata1expr); - upnodata2expr := upper(nodata2expr); - upexpression := upper(expression); - - -- Initialise newrast with nodata-nodata values. Then we don't have anymore to set values for nodata-nodata pixels. - IF upnodatanodataexpr IS NULL THEN - nodatanodataval := newnodatavalue; - ELSE - EXECUTE 'SELECT ' || upnodatanodataexpr INTO nodatanodataval; - IF nodatanodataval IS NULL THEN - nodatanodataval := newnodatavalue; - ELSE - newnodatavalue := nodatanodataval; - END IF; - END IF; - - ------------------------------------------------------------------- - --Create the raster receiving all the computed values. Initialize it to the new nodatavalue. - newrast := ST_AddBand(ST_MakeEmptyRaster(newwidth, newheight, newulx, newuly, newscalex, newscaley, newskewx, newskewy, newsrid), newpixeltype, newnodatavalue, newnodatavalue); - ------------------------------------------------------------------- - -RAISE NOTICE 'ST_MapAlgebra2 111 z11x=%, z11y=%, z11w=%, z11h=%', z11x, z11y, z11w, z11h; - -- First zone with only rast1 (z11) - IF z11w > 0 AND z11h > 0 AND NOT ST_BandIsNodata(rast1, band1) AND NOT nodata2expr IS NULL THEN - IF upnodata2expr = 'RAST' THEN - - - -- IF rast1nodataval != nodatanodataval THEN -RAISE NOTICE 'ST_MapAlgebra2 222'; - -- newrast := ST_SetValues(newrast, 1, z11x, z11y, z11w, z11h, nodatanodataval); - -- END IF; -RAISE NOTICE 'ST_MapAlgebra2 333 z11x=%, z11y=%, z11w=%, z11h=%', z11x, z11y, z11w, z11h; - newrast := ST_SetValues(newrast, 1, z11x, z11y, z11w, z11h, rast1, band1, NULL, TRUE); - - ELSE -RAISE NOTICE 'ST_MapAlgebra2 444'; - - tmprast := ST_Clip(rast1, z11x - r1x + 1, z11y - r1y + 1, z11w, z11h); - newrast := ST_Mapalgebra2(newrast, 1, tmprast, 1, replace(upnodata2expr, 'RAST', 'RAST2'), NULL, 'FIRST', NULL, 'RAST', NULL); - - END IF; - END IF; - -RAISE NOTICE 'ST_MapAlgebra2 555'; - - -- Common zone (zc) - skipcomputation = 0; - IF zcw > 0 AND zch > 0 AND (NOT ST_BandIsNodata(rast1, band1) OR NOT ST_BandIsNodata(rast2, band2)) THEN - -RAISE NOTICE 'ST_MapAlgebra2 666'; - -- Initialize the zone with nodatavalue. We will not further compute nodata nodata pixels - -- newrast := ST_SetValues(newrast, 1, zcx + 1, zcy + 1, zcw, zch, newnodatavalue); - - -- If rast1 is only nodata values, apply nodata1expr - IF ST_BandIsNodata(rast1, band1) THEN - - IF nodata1expr IS NULL THEN - - -- Do nothing - skipcomputation = 0; - - ELSEIF upnodata1expr = 'RAST' THEN - - -- Copy rast2 into newrast - newrast := ST_SetValues(newrast, 1, zcx, zcy, zcw, zch, , rast2, band2, NULL, 'KEEP'); - - ELSE - -- If nodata1expr resume to a constant - IF position('RAST' in upnodata1expr) = 0 THEN - - EXECUTE 'SELECT ' || upnodata1expr INTO newval; - IF newval IS NULL OR newval = newnodatavalue THEN - -- The constant is equal to nodata. We have nothing to compute since newrast was already initialized to nodata - skipcomputation := 2; - ELSEIF newnodatavalue IS NULL THEN - -- We can globally initialize to the constant only if there was no newnodatavalue. - newrast := ST_SetValues(newrast, 1, zcx, zcy, zcw, zch, newval); - skipcomputation := 2; - ELSE - -- We will assign the constant pixel by pixel. - skipcomputation := 1; - END IF; - END IF; - IF skipcomputation < 2 THEN - FOR x IN 1..zcw LOOP - FOR y IN 1..zch LOOP - r2 := ST_Value(rast2, band2, x + r2x, y + r2y); - IF (r2 IS NULL OR r2 = rast2nodataval) THEN - -- Do nothing since the raster have already been all set to this value - ELSE - IF skipcomputation < 1 THEN - newexpr := replace('SELECT ' || upnodata1expr, 'RAST', r2); - EXECUTE newexpr INTO newval; - IF newval IS NULL THEN - newval := newnodatavalue; - END IF; - END IF; - newrast = ST_SetValue(newrast, 1, x + zcx, y + zcy, newval); - END IF; - END LOOP; - END LOOP; - END IF; - END IF; - ELSEIF ST_BandIsNodata(rast2, band2) THEN - ELSE - END IF; - END IF; - - RETURN newrast; - END; - $$ - LANGUAGE 'plpgsql'; - - -CREATE OR REPLACE FUNCTION ST_TestRaster(ulx float8, uly float8, val float8) - RETURNS raster AS - $$ - DECLARE - BEGIN - RETURN ST_AddBand(ST_MakeEmptyRaster(5, 5, ulx, uly, 1, -1, 0, 0, -1), '32BF', val, -1); - END; - $$ - LANGUAGE 'plpgsql'; - - -SELECT asbinary((gv).geom), (gv).val -FROM st_pixelaspolygons(ST_TestRaster(-10, 2, 1)) gv; - -SELECT asbinary(_MapAlgebraAllPartsGeom(0, 0, 2, 1, 1, 0, 2, 1)) - -SELECT asbinary(pix.geom) as geom, pix.val -FROM st_pixelaspolygons(ST_MapAlgebra2(ST_TestRaster(0, 1, 1), 1, ST_TestRaster(1, 0, 1), 1, '(rast1 + rast2) / 2', NULL, 'union', '2*rast', 'rast', NULL), 1) as pix - - - - +---------------------------------------------------------------------- +-- +-- $Id: st_mapalgebra_optimized.sql 6127 2010-10-25 16:06:00Z jorgearevalo $ +-- +-- Copyright (c) 2009-2010 Pierre Racine +-- +---------------------------------------------------------------------- + +-- Note: The functions provided in this script are in developement. Do not use. + +-- Note: this script is dependent on +-- _MapAlgebraParts(r1x int, r1y int, r1w int, r1h int, r2x int, r2y int, r2w int, r2h int) +-- ST_SameAlignment(rast1ulx float8, rast1uly float8, rast1scalex float8, rast1scaley float8, rast1skewx float8, rast1skewy float8, rast2ulx float8, rast2uly float8, rast2scalex float8, rast2scaley float8, rast2skewx float8, rast2skewy float8) +-- ST_IsEmpty(raster) +-- ST_HasNoBand(raster, int) +-- ST_BandIsNoData(raster, int) +-- to be found in the script/plpgsql folder + +-------------------------------------------------------------------- +-- ST_MapAlgebra - (two rasters version) Return a raster which +-- values are the result of an SQL expression involving +-- pixel values from input rasters bands. +-- Arguments +-- rast1 raster - First raster referred by rast1 in the expression. +-- band1 integer - Band number of the first raster. Default to 1. +-- rast2 raster - Second raster referred by rast2 in the expression. +-- band2 integer - Band number of the second raster. Default to 1. +-- expression text - SQL expression. Ex.: "rast1 + 2 * rast2" +-- pixeltype text - Pixeltype assigned to the resulting raster. Expression +-- results are truncated to this type. Default to the +-- pixeltype of the first raster. +-- extentexpr text - Raster extent of the result. Can be: +-- -FIRST: Same extent as the first raster. Default. +-- -SECOND: Same extent as the second) raster. Default. +-- -INTERSECTION: Intersection of extent of the two rasters. +-- -UNION: Union oof extent of the two rasters. +-- nodata1expr text - Expression used when only rast1 pixel value are nodata or absent, i.e. rast2 pixel value is with data. +-- nodata2expr text - Expression used when only rast2 pixel value are nodata or absent, i.e. rast1 pixel value is with data. +-- nodatanodataexpr text - Expression used when both pixel values are nodata values or absent. + +-- Further enhancements: +-- -Move the expression parameter in seventh position just before other expression parameters. +-- -Optimization for UNION & FIRST. We might not have to iterate over all the new raster. See st_mapalgebra_optimized.sql +-- -Add the possibility to assign the x or y coordinate of the pixel to the pixel (do the same to the one raster version). +-- -Resample the second raster when necessary (Require ST_Resample) +-- -More test with rotated images +-------------------------------------------------------------------- +CREATE OR REPLACE FUNCTION ST_MapAlgebra2(rast1 raster, + band1 integer, + rast2 raster, + band2 integer, + expression text, + pixeltype text, + extentexpr text, + nodata1expr text, + nodata2expr text, + nodatanodataexpr text) + RETURNS raster AS + $$ + DECLARE + x integer; + y integer; + r1 float; + r2 float; + rast1ulx float8; + rast1uly float8; + rast1width int; + rast1height int; + rast1scalex float8; + rast1scaley float8; + rast1skewx float8; + rast1skewy float8; + rast1nodataval float8; + rast1srid int; + + rast1offsetx int; + rast1offsety int; + + rast2ulx float8; + rast2uly float8; + rast2width int; + rast2height int; + rast2scalex float8; + rast2scaley float8; + rast2skewx float8; + rast2skewy float8; + rast2nodataval float8; + rast2srid int; + + r1x int; + r1y int; + r1w int; + r1h int; + r2x int; + r2y int; + r2w int; + r2h int; + + newrx int; + newry int; + + newrast raster; + tmprast raster; + newsrid int; + + newscalex float8; + newscaley float8; + newskewx float8; + newskewy float8; + newnodatavalue float8; + newpixeltype text; + newulx float8; + newuly float8; + newwidth int; + newheight int; + newoffsetx1 int; + newoffsety1 int; + newoffsetx2 int; + newoffsety2 int; + + newval float; + newexpr text; + upnodatanodataexpr text; + upnodata1expr text; + upnodata2expr text; + upexpression text; + nodatanodataval float; + skipcomputation int; + + zones int[]; + z11x int; + z11y int; + z11w int; + z11h int; + z12x int; + z12y int; + z12w int; + z12h int; + z13x int; + z13y int; + z13w int; + z13h int; + z14x int; + z14y int; + z14w int; + z14h int; + z21x int; + z21y int; + z21w int; + z21h int; + z22x int; + z22y int; + z22w int; + z22h int; + z23x int; + z23y int; + z23w int; + z23h int; + z24x int; + z24y int; + z24w int; + z24h int; + zcx int; + zcy int; + zcw int; + zch int; + + BEGIN + -- We have to deal with NULL, empty, hasnoband and hasnodatavalue band rasters... + -- These are respectively tested by "IS NULL", "ST_IsEmpty()", "ST_HasNoBand()" and "ST_BandIsNodata()" + + -- If both raster are null, we return NULL. ok + -- If both raster do not have extent (are empty), we return an empty raster. ok + -- If both raster do not have the specified band, + -- we return a no band raster with the correct extent (according to the extent expression). ok + -- If both raster bands are nodatavalue and there is no replacement value, we return a nodata value band. ok + + -- If only one raster is null or empty or has no band or hasnodata band we treat it as a nodata band raster. + -- If there is a replacement value we replace the missing raster values with this replacement value. ok + -- If there is no replacement value, we return a nodata value band. ok + + -- What to do when only one raster is NULL or empty + -- If the extent expression is FIRST and the first raster is null we return NULL. ok + -- If the extent expression is FIRST and the first raster do not have extent (is empty), we return an empty raster. ok + -- If the extent expression is SECOND and the second raster is null we return NULL. ok + -- If the extent expression is SECOND and the second raster do not have extent (is empty), we return an empty raster. ok + -- If the extent expression is INTERSECTION and one raster is null or do not have extent (is empty), we return an empty raster. ok + -- If the extent expression is UNION and one raster is null or do not have extent (is empty), + -- we return a raster having the extent and the band characteristics of the other raster. ok + + -- What to do when only one raster do not have the required band. + -- If the extent expression is FIRST and the first raster do not have the specified band, + -- we return a no band raster with the correct extent (according to the extent expression). ok + -- If the extent expression is SECOND and the second raster do not have the specified band, + -- we return a no band raster with the correct extent (according to the extent expression). ok + -- If the extent expression is INTERSECTION and one raster do not have the specified band, + -- we treat it as a nodata raster band. ok + -- If the extent expression is UNION and one raster do not have the specified band, + -- we treat it as a nodata raster band. ok + + -- In all those cases, we make a warning. + + -- Check if both rasters are NULL +RAISE NOTICE 'ST_MapAlgebra2 000'; + + IF rast1 IS NULL AND rast2 IS NULL THEN + RAISE NOTICE 'ST_MapAlgebra: Both raster are NULL. Returning NULL'; + RETURN NULL; + END IF; + + -- Check if both rasters are empty (width or height = 0) + IF ST_IsEmpty(rast1) AND ST_IsEmpty(rast2) THEN + RAISE NOTICE 'ST_MapAlgebra: Both raster are empty. Returning an empty raster'; + RETURN ST_MakeEmptyRaster(0, 0, 0, 0, 0, 0, 0, 0, -1); + END IF; + + rast1ulx := ST_UpperLeftX(rast1); + rast1uly := ST_UpperLeftY(rast1); + rast1width := ST_Width(rast1); + rast1height := ST_Height(rast1); + rast1scalex := ST_ScaleX(rast1); + rast1scaley := ST_ScaleY(rast1); + rast1skewx := ST_SkewX(rast1); + rast1skewy := ST_SkewY(rast1); + rast1srid := ST_SRID(rast1); + + rast2ulx := ST_UpperLeftX(rast2); + rast2uly := ST_UpperLeftY(rast2); + rast2width := ST_Width(rast2); + rast2height := ST_Height(rast2); + rast2scalex := ST_ScaleX(rast2); + rast2scaley := ST_ScaleY(rast2); + rast2skewx := ST_SkewX(rast2); + rast2skewy := ST_SkewY(rast2); + rast2srid := ST_SRID(rast2); + + -- Check if the first raster is NULL or empty + IF rast1 IS NULL OR ST_IsEmpty(rast1) THEN + rast1ulx := rast2ulx; + rast1uly := rast2uly; + rast1width := rast2width; + rast1height := rast2height; + rast1scalex := rast2scalex; + rast1scaley := rast2scaley; + rast1skewx := rast2skewx; + rast1skewy := rast2skewy; + rast1srid := rast2srid; + END IF; + -- Check if the second raster is NULL or empty + IF rast2 IS NULL OR ST_IsEmpty(rast2) THEN + rast2ulx := rast1ulx; + rast2uly := rast1uly; + rast2width := rast1width; + rast2height := rast1height; + rast2scalex := rast1scalex; + rast2scaley := rast1scaley; + rast2skewx := rast1skewx; + rast2skewy := rast1skewy; + rast2srid := rast1srid; + END IF; + + -- Check for SRID + IF rast1srid != rast2srid THEN + RAISE EXCEPTION 'ST_MapAlgebra: Provided raster with different SRID. Aborting'; + END IF; + newsrid := rast1srid; + + -- Check for alignment. (Rotation problem here) + IF NOT ST_SameAlignment(rast1ulx, rast1uly, rast1scalex, rast1scaley, rast1skewx, rast1skewy, rast2ulx, rast2uly, rast2scalex, rast2scaley, rast2skewx, rast2skewy) THEN + -- For now print an error message, but a more robust implementation should resample the second raster to the alignment of the first raster. + RAISE EXCEPTION 'ST_MapAlgebra: Provided raster do not have the same alignment. Aborting'; + END IF; + + -- Set new pixel size and skew. We set it to the rast1 scale and skew + -- since both rasters are aligned and thus have the same scale and skew + newscalex := rast1scalex; + newscaley := rast1scaley; + newskewx := rast1skewx; + newskewy := rast1skewy; + + --r1x & r2x are the offset of each rasters relatively to global extent + r1x := 0; + r2x := -st_world2rastercoordx(rast2, rast1ulx, rast1uly) + 1; + IF r2x < 0 THEN + r1x := -r2x; + r2x := 0; + END IF; + r1y := 0; + r2y := -st_world2rastercoordy(rast2, rast1ulx, rast1uly) + 1; + IF r2y < 0 THEN + r1y := -r2y; + r2y := 0; + END IF; + + r1w := rast1width; + r1h := rast1height; + r2w := rast2width; + r2h := rast2height; + + zones := _MapAlgebraParts(r1x + 1, r1y + 1, r1w, r1h, r2x + 1, r2y + 1, r2w, r2h); + z11x := zones[1]; + z11y := zones[2]; + z11w := zones[3]; + z11h := zones[4]; + z12x := zones[5]; + z12y := zones[6]; + z12w := zones[7]; + z12h := zones[8]; + z13x := zones[9]; + z13y := zones[10]; + z13w := zones[11]; + z13h := zones[12]; + z14x := zones[13]; + z14y := zones[14]; + z14w := zones[15]; + z14h := zones[16]; + z21x := zones[17]; + z21y := zones[18]; + z21w := zones[19]; + z21h := zones[20]; + z22x := zones[21]; + z22y := zones[22]; + z22w := zones[23]; + z22h := zones[24]; + z23x := zones[25]; + z23y := zones[26]; + z23w := zones[27]; + z23h := zones[28]; + z24x := zones[29]; + z24y := zones[30]; + z24w := zones[31]; + z24h := zones[32]; + zcx := zones[33]; + zcy := zones[34]; + zcw := zones[35]; + zch := zones[36]; + + -- Compute x and y relative index of master and slave according to the extent expression (FIRST, SECOND, INTERSECTION or UNION) + IF extentexpr IS NULL OR upper(extentexpr) = 'FIRST' THEN + + -- Check if rast1 is NULL + IF rast1 IS NULL THEN + RAISE NOTICE 'ST_MapAlgebra: FIRST raster is NULL. Returning NULL'; + RETURN NULL; + END IF; + + -- Check if rast1 is empty + IF ST_IsEmpty(rast1) THEN + RAISE NOTICE 'ST_MapAlgebra: FIRST raster is empty. Returning an empty raster'; + RETURN ST_MakeEmptyRaster(0, 0, 0, 0, 0, 0, 0, 0, newsrid); + END IF; + + -- Check if rast1 has the required band + IF ST_HasNoBand(rast1, band1) THEN + RAISE NOTICE 'ST_MapAlgebra: FIRST raster has no band. Returning a raster without band'; + RETURN ST_MakeEmptyRaster(rast1width, rast1height, rast1ulx, rast1uly, rast1scalex, rast1scaley, rast1skewx, rast1skewy, rast1srid); + END IF; + + newulx := rast1ulx; + newuly := rast1uly; + newwidth := rast1width; + newheight := rast1height; + + newrx := r1x; + newry := r1y; + z21w := 0; + z22w := 0; + z23w := 0; + z24w := 0; + + ELSIF upper(extentexpr) = 'SECOND' THEN + + -- Check if rast2 is NULL + IF rast2 IS NULL THEN + RAISE NOTICE 'ST_MapAlgebra: SECOND raster is NULL. Returning NULL'; + RETURN NULL; + END IF; + + -- Check if rast2 is empty + IF ST_IsEmpty(rast2) THEN + RAISE NOTICE 'ST_MapAlgebra: SECOND raster is empty. Returning an empty raster'; + RETURN ST_MakeEmptyRaster(0, 0, 0, 0, 0, 0, 0, 0, newsrid); + END IF; + + -- Check if rast2 has the required band + IF ST_HasNoBand(rast2, band2) THEN + RAISE NOTICE 'ST_MapAlgebra: SECOND raster has no band. Returning an empty raster'; + RETURN ST_MakeEmptyRaster(rast2width, rast2height, rast2ulx, rast2uly, rast2scalex, rast2scaley, rast2skewx, rast2skewy, rast2srid); + END IF; + + newulx := rast2ulx; + newuly := rast2uly; + newwidth := rast2width; + newheight := rast2height; + + newrx := r2x; + newry := r2y; + z11w := 0; + z12w := 0; + z13w := 0; + z14w := 0; + + ELSIF upper(extentexpr) = 'INTERSECTION' THEN + + -- Check if the intersection is empty. + IF zcw = 0 OR zch = 0 OR + rast1 IS NULL OR ST_IsEmpty(rast1) OR + rast2 IS NULL OR ST_IsEmpty(rast2) THEN + RAISE NOTICE 'ST_MapAlgebra: INTERSECTION of provided rasters is empty. Returning an empty raster'; + RETURN ST_MakeEmptyRaster(0, 0, 0, 0, 0, 0, 0, 0, newsrid); + END IF; + + + -- Compute the new ulx and uly + newulx := st_raster2worldcoordx(rast1, zcx - r1x + 1, zcy - r1y + 1); + newuly := st_raster2worldcoordy(rast1, zcx - r1x + 1, zcy - r1y + 1); + newwidth := zcw; + newheight := zch; + + newrx := zcx; + newry := zcy; + z11w := 0; + z12w := 0; + z13w := 0; + z14w := 0; + z21w := 0; + z22w := 0; + z23w := 0; + z24w := 0; + + ELSIF upper(extentexpr) = 'UNION' THEN + + IF rast1 IS NULL OR ST_IsEmpty(rast1) THEN + newulx := rast2ulx; + newuly := rast2uly; + newwidth := rast2width; + newheight := rast2height; + + newrx := r2x; + newry := r2y; + z21w := 0; + z22w := 0; + z23w := 0; + z24w := 0; + ELSIF rast2 IS NULL OR ST_IsEmpty(rast2) THEN + newulx := rast1ulx; + newuly := rast1uly; + newwidth := rast1width; + newheight := rast1height; + + newrx := r1x; + newry := r1y; + z11w := 0; + z12w := 0; + z13w := 0; + z14w := 0; + ELSE + newrx := 0; + newry := 0; + + newulx := st_raster2worldcoordx(rast1, r1x + 1, r1y + 1); + newuly := st_raster2worldcoordy(rast1, r1x + 1, r1y + 1); + newwidth := max(r1x + r1w, r2x + r2w); + newheight := max(r1y + r1h, r2y + r2h); + + END IF; + ELSE + RAISE EXCEPTION 'ST_MapAlgebra: Unhandled extent expression "%". Only MASTER, INTERSECTION and UNION are accepted. Aborting.', upper(extentexpr); + END IF; + + -- Check if both rasters do not have the specified band. + IF ST_HasNoband(rast1, band1) AND ST_HasNoband(rast2, band2) THEN + RAISE NOTICE 'ST_MapAlgebra: Both raster do not have the specified band. Returning a no band raster with the correct extent'; + RETURN ST_MakeEmptyRaster(newwidth, newheight, newulx, newuly, newscalex, newscaley, newskewx, newskewy, newsrid); + END IF; + + -- Check newpixeltype + newpixeltype := pixeltype; + IF newpixeltype NOTNULL AND newpixeltype != '1BB' AND newpixeltype != '2BUI' AND newpixeltype != '4BUI' AND newpixeltype != '8BSI' AND newpixeltype != '8BUI' AND + newpixeltype != '16BSI' AND newpixeltype != '16BUI' AND newpixeltype != '32BSI' AND newpixeltype != '32BUI' AND newpixeltype != '32BF' AND newpixeltype != '64BF' THEN + RAISE EXCEPTION 'ST_MapAlgebra: Invalid pixeltype "%". Aborting.', newpixeltype; + END IF; + + -- If no newpixeltype was provided, get it from the provided rasters. + IF newpixeltype IS NULL THEN + IF (upper(extentexpr) = 'SECOND' AND NOT ST_HasNoBand(rast2, band2)) OR ST_HasNoBand(rast1, band1) THEN + newpixeltype := ST_BandPixelType(rast2, band2); + ELSE + newpixeltype := ST_BandPixelType(rast1, band1); + END IF; + END IF; + + -- Get the nodata value for first raster + IF NOT ST_HasNoBand(rast1, band1) AND ST_BandHasNodataValue(rast1, band1) THEN + rast1nodataval := ST_BandNodatavalue(rast1, band1); + ELSE + rast1nodataval := NULL; + END IF; + -- Get the nodata value for second raster + IF NOT ST_HasNoBand(rast2, band2) AND ST_BandHasNodatavalue(rast2, band2) THEN + rast2nodataval := ST_BandNodatavalue(rast2, band2); + ELSE + rast2nodataval := NULL; + END IF; + + -- Determine new notadavalue + IF (upper(extentexpr) = 'SECOND' AND NOT rast2nodataval IS NULL) THEN + newnodatavalue := rast2nodataval; + ELSEIF NOT rast1nodataval IS NULL THEN + newnodatavalue := rast1nodataval; + ELSE + RAISE NOTICE 'ST_MapAlgebra: Both source rasters do not have a nodata value, nodata value for new raster set to the minimum value possible'; + newnodatavalue := ST_MinPossibleValue(newrast); + END IF; + + upnodatanodataexpr := upper(nodatanodataexpr); + upnodata1expr := upper(nodata1expr); + upnodata2expr := upper(nodata2expr); + upexpression := upper(expression); + + -- Initialise newrast with nodata-nodata values. Then we don't have anymore to set values for nodata-nodata pixels. + IF upnodatanodataexpr IS NULL THEN + nodatanodataval := newnodatavalue; + ELSE + EXECUTE 'SELECT ' || upnodatanodataexpr INTO nodatanodataval; + IF nodatanodataval IS NULL THEN + nodatanodataval := newnodatavalue; + ELSE + newnodatavalue := nodatanodataval; + END IF; + END IF; + + ------------------------------------------------------------------- + --Create the raster receiving all the computed values. Initialize it to the new nodatavalue. + newrast := ST_AddBand(ST_MakeEmptyRaster(newwidth, newheight, newulx, newuly, newscalex, newscaley, newskewx, newskewy, newsrid), newpixeltype, newnodatavalue, newnodatavalue); + ------------------------------------------------------------------- + +RAISE NOTICE 'ST_MapAlgebra2 111 z11x=%, z11y=%, z11w=%, z11h=%', z11x, z11y, z11w, z11h; + -- First zone with only rast1 (z11) + IF z11w > 0 AND z11h > 0 AND NOT ST_BandIsNodata(rast1, band1) AND NOT nodata2expr IS NULL THEN + IF upnodata2expr = 'RAST' THEN + + + -- IF rast1nodataval != nodatanodataval THEN +RAISE NOTICE 'ST_MapAlgebra2 222'; + -- newrast := ST_SetValues(newrast, 1, z11x, z11y, z11w, z11h, nodatanodataval); + -- END IF; +RAISE NOTICE 'ST_MapAlgebra2 333 z11x=%, z11y=%, z11w=%, z11h=%', z11x, z11y, z11w, z11h; + newrast := ST_SetValues(newrast, 1, z11x, z11y, z11w, z11h, rast1, band1, NULL, TRUE); + + ELSE +RAISE NOTICE 'ST_MapAlgebra2 444'; + + tmprast := ST_Clip(rast1, z11x - r1x + 1, z11y - r1y + 1, z11w, z11h); + newrast := ST_Mapalgebra2(newrast, 1, tmprast, 1, replace(upnodata2expr, 'RAST', 'RAST2'), NULL, 'FIRST', NULL, 'RAST', NULL); + + END IF; + END IF; + +RAISE NOTICE 'ST_MapAlgebra2 555'; + + -- Common zone (zc) + skipcomputation = 0; + IF zcw > 0 AND zch > 0 AND (NOT ST_BandIsNodata(rast1, band1) OR NOT ST_BandIsNodata(rast2, band2)) THEN + +RAISE NOTICE 'ST_MapAlgebra2 666'; + -- Initialize the zone with nodatavalue. We will not further compute nodata nodata pixels + -- newrast := ST_SetValues(newrast, 1, zcx + 1, zcy + 1, zcw, zch, newnodatavalue); + + -- If rast1 is only nodata values, apply nodata1expr + IF ST_BandIsNodata(rast1, band1) THEN + + IF nodata1expr IS NULL THEN + + -- Do nothing + skipcomputation = 0; + + ELSEIF upnodata1expr = 'RAST' THEN + + -- Copy rast2 into newrast + newrast := ST_SetValues(newrast, 1, zcx, zcy, zcw, zch, , rast2, band2, NULL, 'KEEP'); + + ELSE + -- If nodata1expr resume to a constant + IF position('RAST' in upnodata1expr) = 0 THEN + + EXECUTE 'SELECT ' || upnodata1expr INTO newval; + IF newval IS NULL OR newval = newnodatavalue THEN + -- The constant is equal to nodata. We have nothing to compute since newrast was already initialized to nodata + skipcomputation := 2; + ELSEIF newnodatavalue IS NULL THEN + -- We can globally initialize to the constant only if there was no newnodatavalue. + newrast := ST_SetValues(newrast, 1, zcx, zcy, zcw, zch, newval); + skipcomputation := 2; + ELSE + -- We will assign the constant pixel by pixel. + skipcomputation := 1; + END IF; + END IF; + IF skipcomputation < 2 THEN + FOR x IN 1..zcw LOOP + FOR y IN 1..zch LOOP + r2 := ST_Value(rast2, band2, x + r2x, y + r2y); + IF (r2 IS NULL OR r2 = rast2nodataval) THEN + -- Do nothing since the raster have already been all set to this value + ELSE + IF skipcomputation < 1 THEN + newexpr := replace('SELECT ' || upnodata1expr, 'RAST', r2); + EXECUTE newexpr INTO newval; + IF newval IS NULL THEN + newval := newnodatavalue; + END IF; + END IF; + newrast = ST_SetValue(newrast, 1, x + zcx, y + zcy, newval); + END IF; + END LOOP; + END LOOP; + END IF; + END IF; + ELSEIF ST_BandIsNodata(rast2, band2) THEN + ELSE + END IF; + END IF; + + RETURN newrast; + END; + $$ + LANGUAGE 'plpgsql'; + + +CREATE OR REPLACE FUNCTION ST_TestRaster(ulx float8, uly float8, val float8) + RETURNS raster AS + $$ + DECLARE + BEGIN + RETURN ST_AddBand(ST_MakeEmptyRaster(5, 5, ulx, uly, 1, -1, 0, 0, -1), '32BF', val, -1); + END; + $$ + LANGUAGE 'plpgsql'; + + +SELECT asbinary((gv).geom), (gv).val +FROM st_pixelaspolygons(ST_TestRaster(-10, 2, 1)) gv; + +SELECT asbinary(_MapAlgebraAllPartsGeom(0, 0, 2, 1, 1, 0, 2, 1)) + +SELECT asbinary(pix.geom) as geom, pix.val +FROM st_pixelaspolygons(ST_MapAlgebra2(ST_TestRaster(0, 1, 1), 1, ST_TestRaster(1, 0, 1), 1, '(rast1 + rast2) / 2', NULL, 'union', '2*rast', 'rast', NULL), 1) as pix + + + + diff --git a/raster/scripts/plpgsql/st_multibandmapalgebra.sql b/raster/scripts/plpgsql/st_multibandmapalgebra.sql index d69d20493..d947b1365 100644 --- a/raster/scripts/plpgsql/st_multibandmapalgebra.sql +++ b/raster/scripts/plpgsql/st_multibandmapalgebra.sql @@ -1,29 +1,29 @@ ------------------------------------------------------------------------ --- ST_MultiBandMapAlgebra --- Return the same map algebra expression to all the band of a raster. ------------------------------------------------------------------------ -CREATE OR REPLACE FUNCTION ST_MultiBandMapAlgebra(rast1 raster, - rast2 raster, - expression text, - extentexpr text) - RETURNS raster AS - $$ - DECLARE - numband int; - newrast raster; - pixeltype text; - nodataval float; - BEGIN - numband := ST_NumBands(rast1); - IF numband != ST_NumBands(rast2) THEN - RAISE EXCEPTION 'ST_MultiBandMapAlgebra: Rasters do not have the same number of band'; - END IF; - newrast := ST_MakeEmptyRaster(rast1); - FOR b IN 1..numband LOOP - pixeltype := ST_BandPixelType(rast1, b); - nodataval := ST_BandNodataValue(rast1, b); - newrast := ST_AddBand(newrast, NULL, ST_MapAlgebraExpr(rast1, b, rast2, b, expression, pixeltype, extentexpr, nodataval), 1); - END LOOP; - END; - $$ +----------------------------------------------------------------------- +-- ST_MultiBandMapAlgebra +-- Return the same map algebra expression to all the band of a raster. +----------------------------------------------------------------------- +CREATE OR REPLACE FUNCTION ST_MultiBandMapAlgebra(rast1 raster, + rast2 raster, + expression text, + extentexpr text) + RETURNS raster AS + $$ + DECLARE + numband int; + newrast raster; + pixeltype text; + nodataval float; + BEGIN + numband := ST_NumBands(rast1); + IF numband != ST_NumBands(rast2) THEN + RAISE EXCEPTION 'ST_MultiBandMapAlgebra: Rasters do not have the same number of band'; + END IF; + newrast := ST_MakeEmptyRaster(rast1); + FOR b IN 1..numband LOOP + pixeltype := ST_BandPixelType(rast1, b); + nodataval := ST_BandNodataValue(rast1, b); + newrast := ST_AddBand(newrast, NULL, ST_MapAlgebraExpr(rast1, b, rast2, b, expression, pixeltype, extentexpr, nodataval), 1); + END LOOP; + END; + $$ LANGUAGE 'plpgsql'; \ No newline at end of file diff --git a/raster/scripts/plpgsql/st_pixelaspoints.sql b/raster/scripts/plpgsql/st_pixelaspoints.sql index a34addb44..11cb38a4a 100644 --- a/raster/scripts/plpgsql/st_pixelaspoints.sql +++ b/raster/scripts/plpgsql/st_pixelaspoints.sql @@ -1,46 +1,46 @@ ------------------------------------------------------------------------ --- Complex type geomvalxy for returning the geometry, the value, the x coordinate and the y coordinate of a pixel ------------------------------------------------------------------------ -CREATE TYPE geomvalxy AS ( - geom geometry, - val double precision, - x int, - y int -); ------------------------------------------------------------------------ --- ST_PixelAsPoints --- Return all the pixels of a raster as a record composed of a point geometry, a value, a x and a y raster coordinate. --- Should be called like this: --- SELECT (gv).geom, (gv).val, (gv).x, (gv).y FROM (SELECT ST_PixelAsPoints(rast) gv FROM mytable) foo ------------------------------------------------------------------------ -DROP FUNCTION IF EXISTS ST_PixelAsPoints(rast raster, band integer); -CREATE OR REPLACE FUNCTION ST_PixelAsPoints(rast raster, band integer) - RETURNS SETOF geomvalxy AS - $$ - DECLARE - rast alias for $1; - w integer; - h integer; - x integer; - y integer; - result geomvalxy; - BEGIN - SELECT st_width(rast), st_height(rast) - INTO w, h; - FOR x IN 1..w LOOP - FOR y IN 1..h LOOP - SELECT ST_Centroid(ST_PixelAsPolygon(rast, x, y)), ST_Value(rast, band, x, y), x, y INTO result; - RETURN NEXT result; - END LOOP; - END LOOP; - RETURN; - END; - $$ - LANGUAGE 'plpgsql'; - -DROP FUNCTION IF EXISTS ST_PixelAsPoints(rast raster); -CREATE FUNCTION ST_PixelAsPoints(raster) RETURNS SETOF geomvalxy AS -$$ - SELECT ST_PixelAsPoints($1, 1); -$$ +----------------------------------------------------------------------- +-- Complex type geomvalxy for returning the geometry, the value, the x coordinate and the y coordinate of a pixel +----------------------------------------------------------------------- +CREATE TYPE geomvalxy AS ( + geom geometry, + val double precision, + x int, + y int +); +----------------------------------------------------------------------- +-- ST_PixelAsPoints +-- Return all the pixels of a raster as a record composed of a point geometry, a value, a x and a y raster coordinate. +-- Should be called like this: +-- SELECT (gv).geom, (gv).val, (gv).x, (gv).y FROM (SELECT ST_PixelAsPoints(rast) gv FROM mytable) foo +----------------------------------------------------------------------- +DROP FUNCTION IF EXISTS ST_PixelAsPoints(rast raster, band integer); +CREATE OR REPLACE FUNCTION ST_PixelAsPoints(rast raster, band integer) + RETURNS SETOF geomvalxy AS + $$ + DECLARE + rast alias for $1; + w integer; + h integer; + x integer; + y integer; + result geomvalxy; + BEGIN + SELECT st_width(rast), st_height(rast) + INTO w, h; + FOR x IN 1..w LOOP + FOR y IN 1..h LOOP + SELECT ST_Centroid(ST_PixelAsPolygon(rast, x, y)), ST_Value(rast, band, x, y), x, y INTO result; + RETURN NEXT result; + END LOOP; + END LOOP; + RETURN; + END; + $$ + LANGUAGE 'plpgsql'; + +DROP FUNCTION IF EXISTS ST_PixelAsPoints(rast raster); +CREATE FUNCTION ST_PixelAsPoints(raster) RETURNS SETOF geomvalxy AS +$$ + SELECT ST_PixelAsPoints($1, 1); +$$ LANGUAGE SQL; \ No newline at end of file diff --git a/raster/scripts/plpgsql/st_querytables.sql b/raster/scripts/plpgsql/st_querytables.sql index 4754d56ef..32379af09 100644 --- a/raster/scripts/plpgsql/st_querytables.sql +++ b/raster/scripts/plpgsql/st_querytables.sql @@ -1,26 +1,26 @@ ----------------------------------------------------------------------------------------------------------------------- --- ST_QueryTables --- Execute a query on a series of table based on a prefix. --- The string "tablename" will be replaced by the name of the table. --- schemaname - The schema where to execute the queries. --- prefix - Prefix to restraint the query to tables names starting with this string. --- inquery - Query to execute. Can contain the 'tablename' string which will be replaced buy the name of the current table. --- --- Example to drop a set of table --- --- SELECT ST_QueryTables('public', 'aa', 'DROP TABLE IF EXISTS tablename'); ----------------------------------------------------------------------------------------------------------------------- -CREATE OR REPLACE FUNCTION ST_QueryTables(schemaname text, prefix text, inquery text) -RETURNS int AS -$BODY$ -DECLARE - tabletoquery RECORD; -BEGIN - FOR tabletoquery IN EXECUTE 'SELECT tablename FROM pg_tables WHERE schemaname = ' || quote_literal(schemaname) || ' AND tablename LIKE ' || quote_literal(prefix || '%') LOOP - RAISE NOTICE 'Querying %', schemaname || '.' || tabletoquery.tablename; - EXECUTE replace(inquery, 'tablename', '"' || schemaname || '"."' || tabletoquery.tablename || '"'); - END LOOP; - RETURN 1; -END; -$BODY$ +---------------------------------------------------------------------------------------------------------------------- +-- ST_QueryTables +-- Execute a query on a series of table based on a prefix. +-- The string "tablename" will be replaced by the name of the table. +-- schemaname - The schema where to execute the queries. +-- prefix - Prefix to restraint the query to tables names starting with this string. +-- inquery - Query to execute. Can contain the 'tablename' string which will be replaced buy the name of the current table. +-- +-- Example to drop a set of table +-- +-- SELECT ST_QueryTables('public', 'aa', 'DROP TABLE IF EXISTS tablename'); +---------------------------------------------------------------------------------------------------------------------- +CREATE OR REPLACE FUNCTION ST_QueryTables(schemaname text, prefix text, inquery text) +RETURNS int AS +$BODY$ +DECLARE + tabletoquery RECORD; +BEGIN + FOR tabletoquery IN EXECUTE 'SELECT tablename FROM pg_tables WHERE schemaname = ' || quote_literal(schemaname) || ' AND tablename LIKE ' || quote_literal(prefix || '%') LOOP + RAISE NOTICE 'Querying %', schemaname || '.' || tabletoquery.tablename; + EXECUTE replace(inquery, 'tablename', '"' || schemaname || '"."' || tabletoquery.tablename || '"'); + END LOOP; + RETURN 1; +END; +$BODY$ LANGUAGE plpgsql VOLATILE STRICT; \ No newline at end of file diff --git a/raster/scripts/plpgsql/st_tile.sql b/raster/scripts/plpgsql/st_tile.sql index d7eee98ed..085bee263 100644 --- a/raster/scripts/plpgsql/st_tile.sql +++ b/raster/scripts/plpgsql/st_tile.sql @@ -1,229 +1,229 @@ ----------------------------------------------------------------------- --- --- $Id: st_tile.sql 8255 2011-11-29 16:34:48Z pracine $ --- --- Copyright (c) 2009-2010 Pierre Racine --- ----------------------------------------------------------------------- --- ST_Tile --- Split a raster into a set of raster tiles, one tile per row returned. --- Works on multiband rasters. There is no way to specify the upper left --- corner of the new tiled grid. The grid start at the upperleft corner --- of the provided raster. --- --- rast - Raster to be tiled. --- width - Width of the tiles. --- height - Height of the tiles --- padwithnodata - If TRUE, the produced tiles are strictly width x heigth pixels. --- Pixels outside the extent of the passed raster are filled with --- nodata value. When FALSE out of bound tiles are clipped to the --- extent of the raster. Default to FALSE. --- nodatavalue - nodata value to use to pad the outbound tiles when the provided --- raster do not have a nodata value defined. If not provided and --- the raster do not have a nodata value defined --- ST_MinPossibleValue(ST_BandPixelType(rast, band)) is used for each band. --- --- Example producing 120 x 120 pixel tiles --- --- CREATE TABLE srtm_22_03_tiled_120x120 AS --- SELECT ST_Tile(rast, 120, 120, true), generate_series(1, 3600) rid --- FROM srtm_22_03; ----------------------------------------------------------------------------------------------------------------------- -DROP FUNCTION IF EXISTS ST_Tile(rast raster, width integer, height integer, padwithnodata boolean, nodatavalue double precision); -CREATE OR REPLACE FUNCTION ST_Tile(rast raster, width integer, height integer, padwithnodata boolean DEFAULT FALSE, nodatavalue double precision DEFAULT NULL) - RETURNS SETOF raster AS - $$ - DECLARE - gridrast raster; - rastwidth integer; - rastheight integer; - gridwidth integer; - gridheight integer; - newnodata double precision; - newpixtype text; - nbband integer; - bandi integer; - newrast raster; - initvalue double precision; - grid record; - geomrast raster; - BEGIN - IF rast IS NULL THEN - RETURN; - END IF; - - nbband := ST_Numbands(rast); - IF nbband < 1 THEN - RAISE NOTICE 'Raster do not have band %. Returning null', band; - RETURN; - END IF; - - rastwidth := ST_Width(rast); - IF width IS NULL THEN - width := rastwidth; - END IF; - - rastheight := ST_Height(rast); - IF height IS NULL THEN - height := rastheight; - END IF; - - gridwidth := (rastwidth / width) + CASE WHEN rastwidth % width > 0 THEN 1 ELSE 0 END; - gridheight := (rastheight / height) + CASE WHEN rastheight % height > 0 THEN 1 ELSE 0 END; - - gridrast := ST_AddBand(ST_MakeEmptyRaster(gridwidth, gridheight, ST_UpperLeftX(rast), ST_UpperLeftY(rast), ST_ScaleX(rast) * width, ST_ScaleY(rast) * height, ST_SkewX(rast), ST_SkewY(rast), ST_SRID(rast)), '8BUI'::text, 1, 0); - IF padwithnodata THEN - FOR grid IN SELECT (ST_PixelAsPolygons(gridrast)).geom LOOP - FOR bandi IN 1..nbband LOOP - -- for each band we must determine the nodata value - newpixtype := ST_BandPixelType(rast, bandi); - newnodata := ST_BandNodataValue(rast, bandi); - IF newnodata IS NULL THEN - newnodata := coalesce(nodatavalue, ST_MinPossibleVal(newpixtype)); - rast := ST_SetBandNodataValue(rast, newnodata); - END IF; ---RAISE NOTICE 'newnodata1 %', ST_BandNodataValue(rast); - - geomrast := ST_AsRaster(grid.geom, rast); - IF bandi = 1 THEN - newrast := ST_SetBandNodataValue(ST_MapAlgebraExpr(rast, 1, geomrast, 1, 'RAST1', newpixtype, 'SECOND', newnodata::text, newnodata::text, newnodata), newnodata); - ELSE - newrast := ST_AddBand(newrast, ST_SetBandNodataValue(ST_MapAlgebraExpr(rast, bandi, geomrast, 1, 'RAST1', newpixtype, 'SECOND', newnodata::text, newnodata::text, newnodata), newnodata)); - END IF; ---RAISE NOTICE 'newnodata2 = %, newnodata = %, numbands = %, type = %, newset = %', ST_BandNodataValue(newrast), newnodata, ST_NumBands(newrast), ST_BandPixelType(newrast), ST_BandNodataValue(ST_SetBandNodataValue(newrast, 1, -4)); - END LOOP; - RETURN NEXT newrast; - END LOOP; - RETURN; - ELSE - RETURN QUERY SELECT ST_Clip(rast, (ST_PixelAsPolygons(gridrast)).geom, NULL, TRUE) rast; - END IF; - RETURN; - END; - $$ - LANGUAGE 'plpgsql'; - ----------------------------------------------------------------------- --- ST_TileAsGeom --- Split a raster into a set of raster tiles, returning only the geometry --- corresponding to each tile. --- There is no way to specify the upper left corner of the new tiled grid. --- The grid start at the upperleft corner of the provided raster. --- --- rast - Raster to be tiled. --- width - Width of the tiles. --- height - Height of the tiles --- padwithnodata - If TRUE, the produced tiles are strictly width x heigth pixels. --- Pixels outside the extent of the passed raster are filled with --- nodata value. When FALSE out of bound tiles are clipped to the --- extent of the raster. Default to FALSE. --- --- Example producing 120 x 120 pixel tiles --- --- SELECT ST_TileAsGeom(rast, 130, 130, true) --- FROM srtm_22_03; ----------------------------------------------------------------------------------------------------------------------- -DROP FUNCTION IF EXISTS ST_TileAsGeom(rast raster, width integer, height integer, padwithnodata boolean); -CREATE OR REPLACE FUNCTION ST_TileAsGeom(rast raster, width integer, height integer, padwithnodata boolean DEFAULT FALSE) - RETURNS SETOF geometry AS - $$ - DECLARE - gridrast raster; - rastwidth integer; - rastheight integer; - gridwidth integer; - gridheight integer; - nbband integer; - rastextent geometry; - BEGIN - IF rast IS NULL THEN - RETURN; - END IF; - - nbband := ST_Numbands(rast); - IF nbband < 1 THEN - RAISE NOTICE 'Raster do not have band %. Returning null', band; - RETURN; - END IF; - - rastwidth := ST_Width(rast); - IF width IS NULL THEN - width := rastwidth; - END IF; - - rastheight := ST_Height(rast); - IF height IS NULL THEN - height := rastheight; - END IF; - - gridwidth := (rastwidth / width) + CASE WHEN rastwidth % width > 0 THEN 1 ELSE 0 END; - gridheight := (rastheight / height) + CASE WHEN rastheight % height > 0 THEN 1 ELSE 0 END; - - gridrast := ST_AddBand(ST_MakeEmptyRaster(gridwidth, gridheight, ST_UpperLeftX(rast), ST_UpperLeftY(rast), ST_ScaleX(rast) * width, ST_ScaleY(rast) * height, ST_SkewX(rast), ST_SkewY(rast), ST_SRID(rast)), '8BUI'::text, 1, 0); - IF padwithnodata THEN - RETURN QUERY SELECT (ST_PixelAsPolygons(gridrast)).geom geom; - ELSE - rastextent := rast::geometry; - RETURN QUERY SELECT ST_Intersection(rastextent, (ST_PixelAsPolygons(gridrast)).geom) geom; - END IF; - RETURN; - END; - $$ - LANGUAGE 'plpgsql'; - - --- Redefine ST_TestRaster() -CREATE OR REPLACE FUNCTION ST_TestRaster(ulx float8, uly float8, val float8) - RETURNS raster AS - $$ - DECLARE - BEGIN - RETURN ST_AddBand(ST_MakeEmptyRaster(48, 63, ulx, uly, 0.001, -0.001, 0, 0, 4269), '32BF', val, -1); - END; - $$ - LANGUAGE 'plpgsql'; - ------------------------------------------------ --- Display the test raster -SELECT ST_AsBinary((gv).geom) geom, (gv).val -FROM (SELECT ST_PixelAsPolygons(ST_TestRaster(0, 0, 1)) gv) foo; - --- Tile it to 10x10 tiles -SELECT ST_Tile(ST_TestRaster(0, 0, 1), 10, 10) - --- Display the result of the tile function -SELECT ST_AsBinary((gv).geom) geom, (gv).val -FROM (SELECT ST_PixelAsPolygons(ST_Tile(ST_TestRaster(0, 0, 1), 3, 4)) gv) foo; - --- Display each tile as a geometry -SELECT ST_Asbinary(ST_Tile(ST_TestRaster(0, 0, 1), 10, 10)::geometry); - --- Test the padwithnodata parameter -SELECT ST_Asbinary(ST_Tile(ST_TestRaster(0, 0, 1), 10, 10, true)::geometry); - --- Display the result -SELECT ST_AsBinary((gv).geom) geom, (gv).val -FROM (SELECT ST_PixelAsPolygons(ST_Tile(ST_TestRaster(0, 0, 1), 10, 10, true)) gv) foo; - --- Add a rid -SELECT ST_Asbinary(ST_Tile(ST_TestRaster(0, 0, 1), 10, 10)::geometry), generate_series(1, 35) rid; - -SELECT ST_AsBinary((gv).geom) geom, (gv).val, rid -FROM (SELECT ST_PixelAsPolygons(ST_Tile(ST_TestRaster(0, 0, 1), 10, 10, true)) gv, generate_series(1, 35) rid) foo; - -SELECT ST_AsBinary((gv).geom) geom, (gv).val, rid -FROM (SELECT ST_PixelAsPolygons(rast) gv, rid - FROM (SELECT ST_Tile(ST_TestRaster(0, 0, 1), 10, 10, true) rast, generate_series(1, 35) rid) foo WHERE rid = 2) foo2; - --- Test ST_TileAsGeom -SELECT ST_TileAsGeom(ST_TestRaster(0, 0, 1), 10, 10); - - --- Other tests -SELECT ST_Tile(ST_AddBand(ST_MakeEmptyRaster(48, 63, 0, 0, 0.001, -0.001, 0, 0, 4269), '8BSI'::text, 0, -2), 10, 10, true, -10); - -SELECT ST_BandNodataValue(ST_Tile(ST_AddBand(ST_MakeEmptyRaster(48, 63, 0, 0, 0.001, -0.001, 0, 0, 4269), '8BSI'::text, 0, 200), 10, 10, true)); - -SELECT ST_BandNodataValue(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 0.001, -0.001, 0, 0, 4269), '8BSI'::text, 0, 128)); - -SELECT ST_BandNodataValue(ST_SetBandNodataValue(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 0.001, -0.001, 0, 0, 4269), '8BSI'::text, 0, 2), 200)); +---------------------------------------------------------------------- +-- +-- $Id: st_tile.sql 8255 2011-11-29 16:34:48Z pracine $ +-- +-- Copyright (c) 2009-2010 Pierre Racine +-- +---------------------------------------------------------------------- +-- ST_Tile +-- Split a raster into a set of raster tiles, one tile per row returned. +-- Works on multiband rasters. There is no way to specify the upper left +-- corner of the new tiled grid. The grid start at the upperleft corner +-- of the provided raster. +-- +-- rast - Raster to be tiled. +-- width - Width of the tiles. +-- height - Height of the tiles +-- padwithnodata - If TRUE, the produced tiles are strictly width x heigth pixels. +-- Pixels outside the extent of the passed raster are filled with +-- nodata value. When FALSE out of bound tiles are clipped to the +-- extent of the raster. Default to FALSE. +-- nodatavalue - nodata value to use to pad the outbound tiles when the provided +-- raster do not have a nodata value defined. If not provided and +-- the raster do not have a nodata value defined +-- ST_MinPossibleValue(ST_BandPixelType(rast, band)) is used for each band. +-- +-- Example producing 120 x 120 pixel tiles +-- +-- CREATE TABLE srtm_22_03_tiled_120x120 AS +-- SELECT ST_Tile(rast, 120, 120, true), generate_series(1, 3600) rid +-- FROM srtm_22_03; +---------------------------------------------------------------------------------------------------------------------- +DROP FUNCTION IF EXISTS ST_Tile(rast raster, width integer, height integer, padwithnodata boolean, nodatavalue double precision); +CREATE OR REPLACE FUNCTION ST_Tile(rast raster, width integer, height integer, padwithnodata boolean DEFAULT FALSE, nodatavalue double precision DEFAULT NULL) + RETURNS SETOF raster AS + $$ + DECLARE + gridrast raster; + rastwidth integer; + rastheight integer; + gridwidth integer; + gridheight integer; + newnodata double precision; + newpixtype text; + nbband integer; + bandi integer; + newrast raster; + initvalue double precision; + grid record; + geomrast raster; + BEGIN + IF rast IS NULL THEN + RETURN; + END IF; + + nbband := ST_Numbands(rast); + IF nbband < 1 THEN + RAISE NOTICE 'Raster do not have band %. Returning null', band; + RETURN; + END IF; + + rastwidth := ST_Width(rast); + IF width IS NULL THEN + width := rastwidth; + END IF; + + rastheight := ST_Height(rast); + IF height IS NULL THEN + height := rastheight; + END IF; + + gridwidth := (rastwidth / width) + CASE WHEN rastwidth % width > 0 THEN 1 ELSE 0 END; + gridheight := (rastheight / height) + CASE WHEN rastheight % height > 0 THEN 1 ELSE 0 END; + + gridrast := ST_AddBand(ST_MakeEmptyRaster(gridwidth, gridheight, ST_UpperLeftX(rast), ST_UpperLeftY(rast), ST_ScaleX(rast) * width, ST_ScaleY(rast) * height, ST_SkewX(rast), ST_SkewY(rast), ST_SRID(rast)), '8BUI'::text, 1, 0); + IF padwithnodata THEN + FOR grid IN SELECT (ST_PixelAsPolygons(gridrast)).geom LOOP + FOR bandi IN 1..nbband LOOP + -- for each band we must determine the nodata value + newpixtype := ST_BandPixelType(rast, bandi); + newnodata := ST_BandNodataValue(rast, bandi); + IF newnodata IS NULL THEN + newnodata := coalesce(nodatavalue, ST_MinPossibleVal(newpixtype)); + rast := ST_SetBandNodataValue(rast, newnodata); + END IF; +--RAISE NOTICE 'newnodata1 %', ST_BandNodataValue(rast); + + geomrast := ST_AsRaster(grid.geom, rast); + IF bandi = 1 THEN + newrast := ST_SetBandNodataValue(ST_MapAlgebraExpr(rast, 1, geomrast, 1, 'RAST1', newpixtype, 'SECOND', newnodata::text, newnodata::text, newnodata), newnodata); + ELSE + newrast := ST_AddBand(newrast, ST_SetBandNodataValue(ST_MapAlgebraExpr(rast, bandi, geomrast, 1, 'RAST1', newpixtype, 'SECOND', newnodata::text, newnodata::text, newnodata), newnodata)); + END IF; +--RAISE NOTICE 'newnodata2 = %, newnodata = %, numbands = %, type = %, newset = %', ST_BandNodataValue(newrast), newnodata, ST_NumBands(newrast), ST_BandPixelType(newrast), ST_BandNodataValue(ST_SetBandNodataValue(newrast, 1, -4)); + END LOOP; + RETURN NEXT newrast; + END LOOP; + RETURN; + ELSE + RETURN QUERY SELECT ST_Clip(rast, (ST_PixelAsPolygons(gridrast)).geom, NULL, TRUE) rast; + END IF; + RETURN; + END; + $$ + LANGUAGE 'plpgsql'; + +---------------------------------------------------------------------- +-- ST_TileAsGeom +-- Split a raster into a set of raster tiles, returning only the geometry +-- corresponding to each tile. +-- There is no way to specify the upper left corner of the new tiled grid. +-- The grid start at the upperleft corner of the provided raster. +-- +-- rast - Raster to be tiled. +-- width - Width of the tiles. +-- height - Height of the tiles +-- padwithnodata - If TRUE, the produced tiles are strictly width x heigth pixels. +-- Pixels outside the extent of the passed raster are filled with +-- nodata value. When FALSE out of bound tiles are clipped to the +-- extent of the raster. Default to FALSE. +-- +-- Example producing 120 x 120 pixel tiles +-- +-- SELECT ST_TileAsGeom(rast, 130, 130, true) +-- FROM srtm_22_03; +---------------------------------------------------------------------------------------------------------------------- +DROP FUNCTION IF EXISTS ST_TileAsGeom(rast raster, width integer, height integer, padwithnodata boolean); +CREATE OR REPLACE FUNCTION ST_TileAsGeom(rast raster, width integer, height integer, padwithnodata boolean DEFAULT FALSE) + RETURNS SETOF geometry AS + $$ + DECLARE + gridrast raster; + rastwidth integer; + rastheight integer; + gridwidth integer; + gridheight integer; + nbband integer; + rastextent geometry; + BEGIN + IF rast IS NULL THEN + RETURN; + END IF; + + nbband := ST_Numbands(rast); + IF nbband < 1 THEN + RAISE NOTICE 'Raster do not have band %. Returning null', band; + RETURN; + END IF; + + rastwidth := ST_Width(rast); + IF width IS NULL THEN + width := rastwidth; + END IF; + + rastheight := ST_Height(rast); + IF height IS NULL THEN + height := rastheight; + END IF; + + gridwidth := (rastwidth / width) + CASE WHEN rastwidth % width > 0 THEN 1 ELSE 0 END; + gridheight := (rastheight / height) + CASE WHEN rastheight % height > 0 THEN 1 ELSE 0 END; + + gridrast := ST_AddBand(ST_MakeEmptyRaster(gridwidth, gridheight, ST_UpperLeftX(rast), ST_UpperLeftY(rast), ST_ScaleX(rast) * width, ST_ScaleY(rast) * height, ST_SkewX(rast), ST_SkewY(rast), ST_SRID(rast)), '8BUI'::text, 1, 0); + IF padwithnodata THEN + RETURN QUERY SELECT (ST_PixelAsPolygons(gridrast)).geom geom; + ELSE + rastextent := rast::geometry; + RETURN QUERY SELECT ST_Intersection(rastextent, (ST_PixelAsPolygons(gridrast)).geom) geom; + END IF; + RETURN; + END; + $$ + LANGUAGE 'plpgsql'; + + +-- Redefine ST_TestRaster() +CREATE OR REPLACE FUNCTION ST_TestRaster(ulx float8, uly float8, val float8) + RETURNS raster AS + $$ + DECLARE + BEGIN + RETURN ST_AddBand(ST_MakeEmptyRaster(48, 63, ulx, uly, 0.001, -0.001, 0, 0, 4269), '32BF', val, -1); + END; + $$ + LANGUAGE 'plpgsql'; + +----------------------------------------------- +-- Display the test raster +SELECT ST_AsBinary((gv).geom) geom, (gv).val +FROM (SELECT ST_PixelAsPolygons(ST_TestRaster(0, 0, 1)) gv) foo; + +-- Tile it to 10x10 tiles +SELECT ST_Tile(ST_TestRaster(0, 0, 1), 10, 10) + +-- Display the result of the tile function +SELECT ST_AsBinary((gv).geom) geom, (gv).val +FROM (SELECT ST_PixelAsPolygons(ST_Tile(ST_TestRaster(0, 0, 1), 3, 4)) gv) foo; + +-- Display each tile as a geometry +SELECT ST_Asbinary(ST_Tile(ST_TestRaster(0, 0, 1), 10, 10)::geometry); + +-- Test the padwithnodata parameter +SELECT ST_Asbinary(ST_Tile(ST_TestRaster(0, 0, 1), 10, 10, true)::geometry); + +-- Display the result +SELECT ST_AsBinary((gv).geom) geom, (gv).val +FROM (SELECT ST_PixelAsPolygons(ST_Tile(ST_TestRaster(0, 0, 1), 10, 10, true)) gv) foo; + +-- Add a rid +SELECT ST_Asbinary(ST_Tile(ST_TestRaster(0, 0, 1), 10, 10)::geometry), generate_series(1, 35) rid; + +SELECT ST_AsBinary((gv).geom) geom, (gv).val, rid +FROM (SELECT ST_PixelAsPolygons(ST_Tile(ST_TestRaster(0, 0, 1), 10, 10, true)) gv, generate_series(1, 35) rid) foo; + +SELECT ST_AsBinary((gv).geom) geom, (gv).val, rid +FROM (SELECT ST_PixelAsPolygons(rast) gv, rid + FROM (SELECT ST_Tile(ST_TestRaster(0, 0, 1), 10, 10, true) rast, generate_series(1, 35) rid) foo WHERE rid = 2) foo2; + +-- Test ST_TileAsGeom +SELECT ST_TileAsGeom(ST_TestRaster(0, 0, 1), 10, 10); + + +-- Other tests +SELECT ST_Tile(ST_AddBand(ST_MakeEmptyRaster(48, 63, 0, 0, 0.001, -0.001, 0, 0, 4269), '8BSI'::text, 0, -2), 10, 10, true, -10); + +SELECT ST_BandNodataValue(ST_Tile(ST_AddBand(ST_MakeEmptyRaster(48, 63, 0, 0, 0.001, -0.001, 0, 0, 4269), '8BSI'::text, 0, 200), 10, 10, true)); + +SELECT ST_BandNodataValue(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 0.001, -0.001, 0, 0, 4269), '8BSI'::text, 0, 128)); + +SELECT ST_BandNodataValue(ST_SetBandNodataValue(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 0.001, -0.001, 0, 0, 4269), '8BSI'::text, 0, 2), 200)); diff --git a/raster/test/regress/create_rt_empty_raster_test.sql b/raster/test/regress/create_rt_empty_raster_test.sql index d25de91c2..e60a0a91c 100644 --- a/raster/test/regress/create_rt_empty_raster_test.sql +++ b/raster/test/regress/create_rt_empty_raster_test.sql @@ -1,16 +1,16 @@ ------------------------------------------------------------------------ --- $Id$ --- --- Copyright (c) 2011 Jorge Arevalo --- --- This is free software; you can redistribute and/or modify it under --- the terms of the GNU General Public Licence. See the COPYING file. ------------------------------------------------------------------------ - -CREATE TABLE empty_raster_test ( - rid numeric, - rast raster -); - -INSERT INTO empty_raster_test +----------------------------------------------------------------------- +-- $Id$ +-- +-- Copyright (c) 2011 Jorge Arevalo +-- +-- This is free software; you can redistribute and/or modify it under +-- the terms of the GNU General Public Licence. See the COPYING file. +----------------------------------------------------------------------- + +CREATE TABLE empty_raster_test ( + rid numeric, + rast raster +); + +INSERT INTO empty_raster_test VALUES (1, ST_MakeEmptyRaster( 100, 100, 0.0005, 0.0005, 1, 1, 0, 0, 4326) ); \ No newline at end of file diff --git a/raster/test/regress/rt_hasnoband.sql b/raster/test/regress/rt_hasnoband.sql index fac8731a2..d2ac4c2c6 100644 --- a/raster/test/regress/rt_hasnoband.sql +++ b/raster/test/regress/rt_hasnoband.sql @@ -1,13 +1,13 @@ ------------------------------------------------------------------------ --- $Id$ --- --- Copyright (c) 2011 Jorge Arevalo --- --- This is free software; you can redistribute and/or modify it under --- the terms of the GNU General Public Licence. See the COPYING file. ------------------------------------------------------------------------ - -------------------------------------------------------------------- --- st_hasnodata ------------------------------------------------------------------------ +----------------------------------------------------------------------- +-- $Id$ +-- +-- Copyright (c) 2011 Jorge Arevalo +-- +-- This is free software; you can redistribute and/or modify it under +-- the terms of the GNU General Public Licence. See the COPYING file. +----------------------------------------------------------------------- + +------------------------------------------------------------------- +-- st_hasnodata +----------------------------------------------------------------------- select st_hasnoband(rast) from empty_raster_test; \ No newline at end of file diff --git a/raster/test/regress/rt_isempty.sql b/raster/test/regress/rt_isempty.sql index a1d8b2e92..e9ef39a2b 100644 --- a/raster/test/regress/rt_isempty.sql +++ b/raster/test/regress/rt_isempty.sql @@ -1,13 +1,13 @@ ------------------------------------------------------------------------ --- $Id$ --- --- Copyright (c) 2011 Jorge Arevalo --- --- This is free software; you can redistribute and/or modify it under --- the terms of the GNU General Public Licence. See the COPYING file. ------------------------------------------------------------------------ - -------------------------------------------------------------------- --- st_isempty ------------------------------------------------------------------------ +----------------------------------------------------------------------- +-- $Id$ +-- +-- Copyright (c) 2011 Jorge Arevalo +-- +-- This is free software; you can redistribute and/or modify it under +-- the terms of the GNU General Public Licence. See the COPYING file. +----------------------------------------------------------------------- + +------------------------------------------------------------------- +-- st_isempty +----------------------------------------------------------------------- select st_isempty(rast) from empty_raster_test; \ No newline at end of file diff --git a/regress/concave_hull.sql b/regress/concave_hull.sql index 9b26a0167..e44a4a784 100644 --- a/regress/concave_hull.sql +++ b/regress/concave_hull.sql @@ -1,42 +1,42 @@ --- $Id$ --- Tests to confirm the concave hull area is <= convex hull and --- covers the original geometry (can't use covers because always gives topo errors with 3.3 -SELECT - 'ST_ConcaveHull MultiPolygon 0.95', ST_Area(ST_Intersection(geom,ST_ConcaveHull( - geom, 0.95) )) = ST_Area(geom) As encloses_geom, - (ST_Area(ST_ConvexHull(geom)) - - ST_Area(ST_ConcaveHull(geom, 0.95))) < (0.95 * ST_Area(ST_ConvexHull(geom) ) ) As reached_target -FROM ST_Union(ST_GeomFromText('POLYGON((175 150, 20 40, - 50 60, 125 100, 175 150))'), - ST_Buffer(ST_GeomFromText('POINT(110 170)'), 20) - ) As geom; - -SELECT - 'ST_ConcaveHull Lines 0.80', ST_Intersection(geom,ST_ConcaveHull( - geom, 0.80) ) = geom As encloses_geom, - (ST_Area(ST_ConvexHull(geom)) - - ST_Area(ST_ConcaveHull(geom, 0.80))) < (0.80 * ST_Area(ST_ConvexHull(geom) ) ) As reached_target - -FROM ST_GeomFromText('MULTILINESTRING((106 164,30 112,74 70,82 112,130 94, - 130 62,122 40,156 32,162 76,172 88), -(132 178,134 148,128 136,96 128,132 108,150 130, -170 142,174 110,156 96,158 90,158 88), -(22 64,66 28,94 38,94 68,114 76,112 30, -132 10,168 18,178 34,186 52,184 74,190 100, -190 122,182 148,178 170,176 184,156 164,146 178, -132 186,92 182,56 158,36 150,62 150,76 128,88 118))') As geom; - --- test holes vs. no holes - holes should still enclose but have smaller area than no holes -- -SELECT - 'ST_ConcaveHull Lines 0.80 holes', ST_Intersection(geom,ST_ConcaveHull( - geom, 0.80, true) ) = geom As encloses_geom, - ST_Area(ST_ConcaveHull(geom, 0.80, true)) < ST_Area(ST_ConcaveHull(geom, 0.80)) As reached_target - -FROM ST_GeomFromText('MULTILINESTRING((106 164,30 112,74 70,82 112,130 94, - 130 62,122 40,156 32,162 76,172 88), -(132 178,134 148,128 136,96 128,132 108,150 130, -170 142,174 110,156 96,158 90,158 88), -(22 64,66 28,94 38,94 68,114 76,112 30, -132 10,168 18,178 34,186 52,184 74,190 100, -190 122,182 148,178 170,176 184,156 164,146 178, -132 186,92 182,56 158,36 150,62 150,76 128,88 118))') As geom; +-- $Id$ +-- Tests to confirm the concave hull area is <= convex hull and +-- covers the original geometry (can't use covers because always gives topo errors with 3.3 +SELECT + 'ST_ConcaveHull MultiPolygon 0.95', ST_Area(ST_Intersection(geom,ST_ConcaveHull( + geom, 0.95) )) = ST_Area(geom) As encloses_geom, + (ST_Area(ST_ConvexHull(geom)) + - ST_Area(ST_ConcaveHull(geom, 0.95))) < (0.95 * ST_Area(ST_ConvexHull(geom) ) ) As reached_target +FROM ST_Union(ST_GeomFromText('POLYGON((175 150, 20 40, + 50 60, 125 100, 175 150))'), + ST_Buffer(ST_GeomFromText('POINT(110 170)'), 20) + ) As geom; + +SELECT + 'ST_ConcaveHull Lines 0.80', ST_Intersection(geom,ST_ConcaveHull( + geom, 0.80) ) = geom As encloses_geom, + (ST_Area(ST_ConvexHull(geom)) + - ST_Area(ST_ConcaveHull(geom, 0.80))) < (0.80 * ST_Area(ST_ConvexHull(geom) ) ) As reached_target + +FROM ST_GeomFromText('MULTILINESTRING((106 164,30 112,74 70,82 112,130 94, + 130 62,122 40,156 32,162 76,172 88), +(132 178,134 148,128 136,96 128,132 108,150 130, +170 142,174 110,156 96,158 90,158 88), +(22 64,66 28,94 38,94 68,114 76,112 30, +132 10,168 18,178 34,186 52,184 74,190 100, +190 122,182 148,178 170,176 184,156 164,146 178, +132 186,92 182,56 158,36 150,62 150,76 128,88 118))') As geom; + +-- test holes vs. no holes - holes should still enclose but have smaller area than no holes -- +SELECT + 'ST_ConcaveHull Lines 0.80 holes', ST_Intersection(geom,ST_ConcaveHull( + geom, 0.80, true) ) = geom As encloses_geom, + ST_Area(ST_ConcaveHull(geom, 0.80, true)) < ST_Area(ST_ConcaveHull(geom, 0.80)) As reached_target + +FROM ST_GeomFromText('MULTILINESTRING((106 164,30 112,74 70,82 112,130 94, + 130 62,122 40,156 32,162 76,172 88), +(132 178,134 148,128 136,96 128,132 108,150 130, +170 142,174 110,156 96,158 90,158 88), +(22 64,66 28,94 38,94 68,114 76,112 30, +132 10,168 18,178 34,186 52,184 74,190 100, +190 122,182 148,178 170,176 184,156 164,146 178, +132 186,92 182,56 158,36 150,62 150,76 128,88 118))') As geom; diff --git a/regress/regress_index_nulls.sql b/regress/regress_index_nulls.sql index 56bfa3dae..462a0d509 100644 --- a/regress/regress_index_nulls.sql +++ b/regress/regress_index_nulls.sql @@ -1,6 +1,6 @@ -\i regress_lots_of_nulls.sql - - -CREATE INDEX "test_geom_idx" ON "test" using gist (the_geom); - -DROP TABLE "test"; +\i regress_lots_of_nulls.sql + + +CREATE INDEX "test_geom_idx" ON "test" using gist (the_geom); + +DROP TABLE "test"; diff --git a/regress/regress_lots_of_nulls.sql b/regress/regress_lots_of_nulls.sql index 9fb7e07b7..11cabf985 100644 --- a/regress/regress_lots_of_nulls.sql +++ b/regress/regress_lots_of_nulls.sql @@ -1,510 +1,510 @@ --- Test index creation on null geometries --- An index on more than 459 null geometries (with or without actual geometires) --- used to fail on PostgreSQL 8.2. - -CREATE TABLE "test" ( - "num" integer, - "the_geom" geometry -); - -INSERT INTO "test" ("num", "the_geom") VALUES ( 1 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 2 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 3 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 4 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 5 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 6 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 7 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 8 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 9 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 10 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 11 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 12 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 13 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 14 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 15 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 16 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 17 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 18 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 19 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 20 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 21 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 22 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 23 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 24 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 25 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 26 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 27 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 28 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 29 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 30 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 31 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 32 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 33 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 34 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 35 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 36 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 37 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 38 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 39 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 40 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 41 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 42 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 43 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 44 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 45 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 46 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 47 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 48 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 49 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 50 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 51 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 52 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 53 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 54 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 55 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 56 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 57 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 58 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 59 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 60 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 61 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 62 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 63 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 64 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 65 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 66 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 67 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 68 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 69 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 70 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 71 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 72 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 73 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 74 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 75 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 76 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 77 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 78 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 79 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 80 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 81 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 82 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 83 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 84 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 85 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 86 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 87 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 88 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 89 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 90 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 91 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 92 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 93 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 94 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 95 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 96 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 97 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 98 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 99 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 100 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 101 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 102 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 103 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 104 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 105 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 106 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 107 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 108 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 109 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 110 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 111 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 112 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 113 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 114 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 115 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 116 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 117 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 118 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 119 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 120 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 121 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 122 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 123 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 124 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 125 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 126 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 127 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 128 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 129 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 130 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 131 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 132 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 133 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 134 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 135 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 136 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 137 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 138 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 139 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 140 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 141 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 142 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 143 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 144 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 145 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 146 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 147 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 148 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 149 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 150 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 151 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 152 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 153 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 154 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 155 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 156 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 157 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 158 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 159 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 160 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 161 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 162 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 163 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 164 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 165 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 166 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 167 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 168 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 169 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 170 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 171 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 172 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 173 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 174 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 175 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 176 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 177 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 178 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 179 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 180 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 181 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 182 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 183 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 184 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 185 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 186 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 187 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 188 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 189 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 190 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 191 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 192 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 193 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 194 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 195 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 196 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 197 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 198 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 199 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 200 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 201 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 202 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 203 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 204 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 205 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 206 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 207 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 208 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 209 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 210 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 211 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 212 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 213 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 214 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 215 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 216 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 217 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 218 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 219 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 220 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 221 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 222 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 223 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 224 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 225 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 226 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 227 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 228 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 229 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 230 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 231 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 232 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 233 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 234 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 235 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 236 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 237 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 238 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 239 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 240 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 241 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 242 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 243 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 244 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 245 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 246 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 247 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 248 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 249 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 250 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 251 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 252 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 253 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 254 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 255 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 256 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 257 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 258 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 259 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 260 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 261 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 262 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 263 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 264 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 265 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 266 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 267 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 268 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 269 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 270 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 271 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 272 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 273 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 274 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 275 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 276 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 277 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 278 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 279 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 280 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 281 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 282 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 283 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 284 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 285 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 286 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 287 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 288 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 289 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 290 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 291 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 292 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 293 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 294 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 295 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 296 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 297 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 298 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 299 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 300 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 301 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 302 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 303 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 304 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 305 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 306 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 307 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 308 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 309 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 310 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 311 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 312 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 313 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 314 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 315 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 316 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 317 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 318 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 319 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 320 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 321 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 322 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 323 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 324 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 325 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 326 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 327 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 328 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 329 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 330 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 331 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 332 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 333 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 334 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 335 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 336 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 337 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 338 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 339 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 340 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 341 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 342 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 343 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 344 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 345 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 346 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 347 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 348 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 349 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 350 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 351 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 352 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 353 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 354 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 355 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 356 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 357 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 358 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 359 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 360 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 361 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 362 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 363 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 364 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 365 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 366 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 367 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 368 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 369 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 370 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 371 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 372 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 373 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 374 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 375 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 376 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 377 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 378 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 379 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 380 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 381 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 382 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 383 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 384 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 385 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 386 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 387 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 388 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 389 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 390 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 391 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 392 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 393 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 394 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 395 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 396 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 397 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 398 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 399 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 400 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 401 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 402 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 403 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 404 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 405 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 406 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 407 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 408 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 409 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 410 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 411 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 412 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 413 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 414 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 415 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 416 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 417 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 418 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 419 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 420 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 421 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 422 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 423 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 424 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 425 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 426 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 427 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 428 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 429 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 430 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 431 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 432 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 433 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 434 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 435 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 436 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 437 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 438 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 439 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 440 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 441 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 442 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 443 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 444 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 445 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 446 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 447 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 448 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 449 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 450 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 451 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 452 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 453 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 454 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 455 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 456 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 457 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 458 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 459 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 460 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 461 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 462 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 463 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 464 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 465 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 466 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 467 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 468 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 469 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 470 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 471 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 472 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 473 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 474 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 475 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 476 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 477 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 478 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 479 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 480 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 481 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 482 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 483 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 484 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 485 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 486 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 487 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 488 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 489 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 490 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 491 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 492 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 493 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 494 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 495 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 496 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 497 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 498 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 499 , NULL); -INSERT INTO "test" ("num", "the_geom") VALUES ( 500 , NULL); - +-- Test index creation on null geometries +-- An index on more than 459 null geometries (with or without actual geometires) +-- used to fail on PostgreSQL 8.2. + +CREATE TABLE "test" ( + "num" integer, + "the_geom" geometry +); + +INSERT INTO "test" ("num", "the_geom") VALUES ( 1 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 2 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 3 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 4 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 5 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 6 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 7 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 8 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 9 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 10 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 11 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 12 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 13 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 14 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 15 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 16 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 17 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 18 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 19 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 20 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 21 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 22 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 23 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 24 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 25 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 26 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 27 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 28 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 29 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 30 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 31 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 32 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 33 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 34 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 35 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 36 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 37 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 38 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 39 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 40 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 41 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 42 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 43 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 44 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 45 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 46 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 47 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 48 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 49 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 50 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 51 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 52 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 53 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 54 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 55 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 56 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 57 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 58 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 59 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 60 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 61 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 62 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 63 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 64 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 65 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 66 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 67 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 68 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 69 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 70 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 71 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 72 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 73 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 74 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 75 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 76 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 77 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 78 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 79 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 80 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 81 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 82 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 83 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 84 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 85 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 86 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 87 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 88 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 89 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 90 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 91 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 92 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 93 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 94 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 95 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 96 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 97 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 98 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 99 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 100 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 101 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 102 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 103 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 104 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 105 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 106 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 107 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 108 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 109 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 110 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 111 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 112 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 113 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 114 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 115 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 116 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 117 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 118 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 119 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 120 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 121 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 122 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 123 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 124 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 125 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 126 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 127 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 128 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 129 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 130 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 131 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 132 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 133 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 134 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 135 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 136 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 137 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 138 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 139 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 140 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 141 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 142 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 143 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 144 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 145 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 146 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 147 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 148 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 149 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 150 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 151 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 152 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 153 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 154 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 155 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 156 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 157 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 158 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 159 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 160 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 161 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 162 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 163 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 164 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 165 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 166 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 167 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 168 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 169 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 170 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 171 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 172 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 173 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 174 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 175 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 176 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 177 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 178 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 179 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 180 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 181 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 182 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 183 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 184 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 185 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 186 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 187 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 188 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 189 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 190 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 191 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 192 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 193 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 194 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 195 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 196 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 197 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 198 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 199 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 200 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 201 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 202 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 203 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 204 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 205 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 206 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 207 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 208 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 209 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 210 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 211 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 212 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 213 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 214 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 215 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 216 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 217 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 218 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 219 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 220 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 221 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 222 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 223 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 224 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 225 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 226 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 227 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 228 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 229 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 230 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 231 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 232 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 233 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 234 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 235 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 236 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 237 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 238 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 239 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 240 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 241 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 242 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 243 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 244 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 245 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 246 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 247 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 248 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 249 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 250 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 251 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 252 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 253 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 254 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 255 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 256 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 257 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 258 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 259 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 260 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 261 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 262 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 263 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 264 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 265 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 266 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 267 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 268 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 269 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 270 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 271 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 272 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 273 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 274 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 275 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 276 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 277 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 278 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 279 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 280 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 281 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 282 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 283 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 284 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 285 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 286 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 287 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 288 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 289 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 290 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 291 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 292 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 293 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 294 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 295 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 296 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 297 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 298 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 299 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 300 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 301 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 302 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 303 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 304 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 305 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 306 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 307 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 308 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 309 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 310 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 311 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 312 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 313 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 314 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 315 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 316 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 317 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 318 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 319 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 320 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 321 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 322 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 323 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 324 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 325 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 326 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 327 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 328 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 329 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 330 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 331 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 332 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 333 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 334 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 335 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 336 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 337 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 338 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 339 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 340 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 341 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 342 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 343 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 344 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 345 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 346 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 347 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 348 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 349 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 350 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 351 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 352 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 353 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 354 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 355 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 356 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 357 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 358 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 359 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 360 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 361 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 362 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 363 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 364 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 365 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 366 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 367 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 368 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 369 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 370 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 371 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 372 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 373 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 374 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 375 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 376 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 377 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 378 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 379 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 380 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 381 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 382 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 383 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 384 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 385 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 386 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 387 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 388 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 389 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 390 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 391 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 392 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 393 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 394 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 395 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 396 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 397 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 398 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 399 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 400 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 401 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 402 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 403 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 404 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 405 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 406 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 407 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 408 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 409 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 410 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 411 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 412 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 413 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 414 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 415 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 416 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 417 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 418 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 419 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 420 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 421 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 422 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 423 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 424 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 425 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 426 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 427 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 428 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 429 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 430 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 431 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 432 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 433 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 434 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 435 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 436 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 437 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 438 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 439 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 440 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 441 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 442 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 443 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 444 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 445 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 446 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 447 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 448 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 449 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 450 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 451 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 452 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 453 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 454 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 455 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 456 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 457 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 458 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 459 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 460 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 461 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 462 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 463 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 464 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 465 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 466 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 467 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 468 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 469 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 470 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 471 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 472 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 473 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 474 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 475 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 476 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 477 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 478 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 479 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 480 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 481 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 482 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 483 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 484 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 485 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 486 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 487 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 488 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 489 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 490 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 491 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 492 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 493 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 494 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 495 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 496 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 497 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 498 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 499 , NULL); +INSERT INTO "test" ("num", "the_geom") VALUES ( 500 , NULL); + diff --git a/regress/regress_management.sql b/regress/regress_management.sql index 28a90de5b..e12bd68a0 100644 --- a/regress/regress_management.sql +++ b/regress/regress_management.sql @@ -1,10 +1,10 @@ --- $Id$ --- Test the populate_geometry_columns,DropGeometryTable etc -- -\set VERBOSITY terse -DELETE FROM spatial_ref_sys WHERE srid = 4326; -INSERT INTO spatial_ref_sys ( srid, proj4text ) VALUES( 4326, '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'); -CREATE TABLE test_pt(gid SERIAL PRIMARY KEY, geom geometry); -INSERT INTO test_pt(geom) VALUES(ST_GeomFromEWKT('SRID=4326;POINT M(1 2 3)')); -SELECT populate_geometry_columns('test_pt'::regclass); -SELECT 'The result: ' || DropGeometryTable('test_pt'); -SELECT 'Unexistant: ' || DropGeometryTable('unexistent'); -- see ticket #861 +-- $Id$ +-- Test the populate_geometry_columns,DropGeometryTable etc -- +\set VERBOSITY terse +DELETE FROM spatial_ref_sys WHERE srid = 4326; +INSERT INTO spatial_ref_sys ( srid, proj4text ) VALUES( 4326, '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'); +CREATE TABLE test_pt(gid SERIAL PRIMARY KEY, geom geometry); +INSERT INTO test_pt(geom) VALUES(ST_GeomFromEWKT('SRID=4326;POINT M(1 2 3)')); +SELECT populate_geometry_columns('test_pt'::regclass); +SELECT 'The result: ' || DropGeometryTable('test_pt'); +SELECT 'Unexistant: ' || DropGeometryTable('unexistent'); -- see ticket #861 diff --git a/regress/sql-mm-circularstring.sql b/regress/sql-mm-circularstring.sql index edea0b54b..f97a168e8 100644 --- a/regress/sql-mm-circularstring.sql +++ b/regress/sql-mm-circularstring.sql @@ -1,281 +1,281 @@ -SET client_min_messages TO warning; - -SELECT 'ndims01', ST_ndims(ST_geomfromewkt('CIRCULARSTRING( - 0 0 0 0, - 0.26794919243112270647255365849413 1 3 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2)')); -SELECT 'geometrytype01', geometrytype(ST_geomfromewkt('CIRCULARSTRING( - 0 0 0 0, - 0.26794919243112270647255365849413 1 3 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2)')); -SELECT 'ndims02', ST_ndims(ST_geomfromewkt('CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 3, - 0.5857864376269049511981127579 1.4142135623730950488016887242097 1)')); -SELECT 'geometrytype02', geometrytype(ST_geomfromewkt('CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 3, - 0.5857864376269049511981127579 1.4142135623730950488016887242097 1)')); -SELECT 'ndims03', ST_ndims(ST_geomfromewkt('CIRCULARSTRINGM( - 0 0 0, - 0.26794919243112270647255365849413 1 -2, - 0.5857864376269049511981127579 1.4142135623730950488016887242097 2)')); -SELECT 'geometrytype03', geometrytype(ST_geomfromewkt('CIRCULARSTRINGM( - 0 0 0, - 0.26794919243112270647255365849413 1 -2, - 0.5857864376269049511981127579 1.4142135623730950488016887242097 2)')); -SELECT 'ndims04', ST_ndims(ST_geomfromewkt('CIRCULARSTRING( - 0 0, - 0.26794919243112270647255365849413 1, - 0.5857864376269049511981127579 1.4142135623730950488016887242097)')); -SELECT 'geometrytype04', geometrytype(ST_geomfromewkt('CIRCULARSTRING( - 0 0, - 0.26794919243112270647255365849413 1, - 0.5857864376269049511981127579 1.4142135623730950488016887242097)')); - -SELECT 'isClosed01', ST_isClosed(ST_geomfromewkt('CIRCULARSTRING( - 0 -2, - -2 0, - 0 2, - 2 0, - 0 -2)')); -SELECT 'isSimple01', ST_isSimple(ST_geomfromewkt('CIRCULARSTRING( - 0 -2, - -2 0, - 0 2, - 2 0, - 0 -2)')); -SELECT 'isRing01', ST_isRing(ST_geomfromewkt('CIRCULARSTRING( - 0 -2, - -2 0, - 0 2, - 2 0, - 0 -2)')); -SELECT 'isClosed02', ST_isClosed(ST_geomfromewkt('CIRCULARSTRING( - 0 -2, - -2 0, - 0 2, - -2 0, - 2 -2, - -2 0, - -2 -2, - -2 0, - 0 -2)')); -SELECT 'isSimple02', ST_isSimple(ST_geomfromewkt('CIRCULARSTRING( - 0 -2, - -2 0, - 0 2, - -2 0, - 2 -2, - -2 0, - -2 -2, - -2 0, - 0 -2)')); -SELECT 'isRing02', ST_isRing(ST_geomfromewkt('CIRCULARSTRING( - 0 -2, - -2 0, - 0 2, - -2 0, - 2 -2, - -2 0, - -2 -2, - -2 0, - 0 -2)')); - -CREATE TABLE public.circularstring (id INTEGER, description VARCHAR, -the_geom_2d GEOMETRY(CIRCULARSTRING), -the_geom_3dm GEOMETRY(CIRCULARSTRINGM), -the_geom_3dz GEOMETRY(CIRCULARSTRINGZ), -the_geom_4d GEOMETRY(CIRCULARSTRINGZM)); - -INSERT INTO public.circularstring ( - id, - description - ) VALUES ( - 1, - '180-135 degrees'); -UPDATE public.circularstring - SET the_geom_4d = ST_Geomfromewkt('CIRCULARSTRING( - 0 0 0 0, - 0.26794919243112270647255365849413 1 3 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2)') - WHERE id = 1; -UPDATE public.circularstring - SET the_geom_3dz = ST_Geomfromewkt('CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 3, - 0.5857864376269049511981127579 1.4142135623730950488016887242097 1)') - WHERE id = 1; -UPDATE public.circularstring - SET the_geom_3dm = ST_Geomfromewkt('CIRCULARSTRINGM( - 0 0 0, - 0.26794919243112270647255365849413 1 -2, - 0.5857864376269049511981127579 1.4142135623730950488016887242097 2)') - WHERE id = 1; -UPDATE public.circularstring - SET the_geom_2d = ST_Geomfromewkt('CIRCULARSTRING( - 0 0, - 0.26794919243112270647255365849413 1, - 0.5857864376269049511981127579 1.4142135623730950488016887242097)') - WHERE id = 1; - -INSERT INTO public.circularstring ( - id, - description - ) VALUES ( - 2, - '2-segment string'); -UPDATE public.circularstring - SET the_geom_4d = ST_Geomfromewkt('CIRCULARSTRING( - -5 0 0 4, - 0 5 1 3, - 5 0 2 2, - 10 -5 3 1, - 15 0 4 0)') - WHERE id = 2; -UPDATE public.circularstring - SET the_geom_3dz = ST_Geomfromewkt('CIRCULARSTRING( - -5 0 0, - 0 5 1, - 5 0 2, - 10 -5 3, - 15 0 4)') - WHERE id = 2; -UPDATE public.circularstring - SET the_geom_3dm = ST_Geomfromewkt('CIRCULARSTRINGM( - -5 0 4, - 0 5 3, - 5 0 2, - 10 -5 1, - 15 0 0)') - WHERE id = 2; -UPDATE public.circularstring - SET the_geom_2d = ST_Geomfromewkt('CIRCULARSTRING( - -5 0, - 0 5, - 5 0, - 10 -5, - 15 0)') - WHERE id = 2; - -SELECT 'astext01', ST_astext(the_geom_2d) FROM public.circularstring; -SELECT 'astext02', ST_astext(the_geom_3dm) FROM public.circularstring; -SELECT 'astext03', ST_astext(the_geom_3dz) FROM public.circularstring; -SELECT 'astext04', ST_astext(the_geom_4d) FROM public.circularstring; - -SELECT 'asewkt01', ST_asewkt(the_geom_2d) FROM public.circularstring; -SELECT 'asewkt02', ST_asewkt(the_geom_3dm) FROM public.circularstring; -SELECT 'asewkt03', ST_asewkt(the_geom_3dz) FROM public.circularstring; -SELECT 'asewkt04', ST_asewkt(the_geom_4d) FROM public.circularstring; - --- These tests will fail on different architectures --- We need a way to handle multiple byte orderings ---SELECT 'asbinary01', encode(asbinary(the_geom_2d), 'hex') FROM public.circularstring; ---SELECT 'asbinary02', encode(asbinary(the_geom_3dm), 'hex') FROM public.circularstring; ---SELECT 'asbinary03', encode(asbinary(the_geom_3dz), 'hex') FROM public.circularstring; ---SELECT 'asbinary04', encode(asbinary(the_geom_4d), 'hex') FROM public.circularstring; --- ---SELECT 'asewkb01', encode(asewkb(the_geom_2d), 'hex') FROM public.circularstring; ---SELECT 'asewkb02', encode(asewkb(the_geom_3dm), 'hex') FROM public.circularstring; ---SELECT 'asewkb03', encode(asewkb(the_geom_3dz), 'hex') FROM public.circularstring; ---SELECT 'asewkb04', encode(asewkb(the_geom_4d), 'hex') FROM public.circularstring; - -SELECT 'ST_CurveToLine-201', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; -SELECT 'ST_CurveToLine-202', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; -SELECT 'ST_CurveToLine-203', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; -SELECT 'ST_CurveToLine-204', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; - -SELECT 'ST_CurveToLine-401', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; -SELECT 'ST_CurveToLine-402', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; -SELECT 'ST_CurveToLine-403', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; -SELECT 'ST_CurveToLine-404', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; - -SELECT 'ST_CurveToLine01', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; -SELECT 'ST_CurveToLine02', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; -SELECT 'ST_CurveToLine03', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; -SELECT 'ST_CurveToLine04', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; - ---Removed due to discrepencies between hardware ---SELECT 'box2d01', box2d(the_geom_2d) FROM public.circularstring; ---SELECT 'box2d02', box2d(the_geom_3dm) FROM public.circularstring; ---SELECT 'box2d03', box2d(the_geom_3dz) FROM public.circularstring; ---SELECT 'box2d04', box2d(the_geom_4d) FROM public.circularstring; - ---SELECT 'box3d01', box3d(the_geom_2d) FROM public.circularstring; ---SELECT 'box3d02', box3d(the_geom_3dm) FROM public.circularstring; ---SELECT 'box3d03', box3d(the_geom_3dz) FROM public.circularstring; ---SELECT 'box3d04', box3d(the_geom_4d) FROM public.circularstring; --- TODO: ST_SnapToGrid is required to remove platform dependent precision --- issues. Until ST_SnapToGrid is updated to work against curves, these --- tests cannot be run. ---SELECT 'ST_LineToCurve01', ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_2d))) FROM public.circularstring; ---SELECT 'ST_LineToCurve02', ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dm))) FROM public.circularstring; ---SELECT 'ST_LineToCurve03', ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dz))) FROM public.circularstring; ---SELECT 'ST_LineToCurve04', ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_4d))) FROM public.circularstring; - --- Repeat tests with new function names. -SELECT 'astext01', ST_astext(the_geom_2d) FROM public.circularstring; -SELECT 'astext02', ST_astext(the_geom_3dm) FROM public.circularstring; -SELECT 'astext03', ST_astext(the_geom_3dz) FROM public.circularstring; -SELECT 'astext04', ST_astext(the_geom_4d) FROM public.circularstring; - -SELECT 'asewkt01', ST_asewkt(the_geom_2d) FROM public.circularstring; -SELECT 'asewkt02', ST_asewkt(the_geom_3dm) FROM public.circularstring; -SELECT 'asewkt03', ST_asewkt(the_geom_3dz) FROM public.circularstring; -SELECT 'asewkt04', ST_asewkt(the_geom_4d) FROM public.circularstring; - --- These tests will fail on different architectures --- We need a way to handle multiple byte orderings ---SELECT 'asbinary01', encode(ST_asbinary(the_geom_2d), 'hex') FROM public.circularstring; ---SELECT 'asbinary02', encode(ST_asbinary(the_geom_3dm), 'hex') FROM public.circularstring; ---SELECT 'asbinary03', encode(ST_asbinary(the_geom_3dz), 'hex') FROM public.circularstring; ---SELECT 'asbinary04', encode(ST_asbinary(the_geom_4d), 'hex') FROM public.circularstring; --- ---SELECT 'asewkb01', encode(ST_asewkb(the_geom_2d), 'hex') FROM public.circularstring; ---SELECT 'asewkb02', encode(ST_asewkb(the_geom_3dm), 'hex') FROM public.circularstring; ---SELECT 'asewkb03', encode(ST_asewkb(the_geom_3dz), 'hex') FROM public.circularstring; ---SELECT 'asewkb04', encode(ST_asewkb(the_geom_4d), 'hex') FROM public.circularstring; - ---Removed due to discrepencies between hardware ---SELECT 'box2d01', box2d(the_geom_2d) FROM public.circularstring; ---SELECT 'box2d02', box2d(the_geom_3dm) FROM public.circularstring; ---SELECT 'box2d03', box2d(the_geom_3dz) FROM public.circularstring; ---SELECT 'box2d04', box2d(the_geom_4d) FROM public.circularstring; - ---SELECT 'box3d01', box3d(the_geom_2d) FROM public.circularstring; ---SELECT 'box3d02', box3d(the_geom_3dm) FROM public.circularstring; ---SELECT 'box3d03', box3d(the_geom_3dz) FROM public.circularstring; ---SELECT 'box3d04', box3d(the_geom_4d) FROM public.circularstring; - -SELECT 'isValid01', ST_isValid(the_geom_2d) FROM public.circularstring; -SELECT 'isValid02', ST_isValid(the_geom_3dm) FROM public.circularstring; -SELECT 'isValid03', ST_isValid(the_geom_3dz) FROM public.circularstring; -SELECT 'isValid04', ST_isValid(the_geom_4d) FROM public.circularstring; - -SELECT 'dimension01', ST_dimension(the_geom_2d) FROM public.circularstring; -SELECT 'dimension02', ST_dimension(the_geom_3dm) FROM public.circularstring; -SELECT 'dimension03', ST_dimension(the_geom_3dz) FROM public.circularstring; -SELECT 'dimension04', ST_dimension(the_geom_4d) FROM public.circularstring; - -SELECT 'SRID01', ST_SRID(the_geom_2d) FROM public.circularstring; -SELECT 'SRID02', ST_SRID(the_geom_3dm) FROM public.circularstring; -SELECT 'SRID03', ST_SRID(the_geom_3dz) FROM public.circularstring; -SELECT 'SRID04', ST_SRID(the_geom_4d) FROM public.circularstring; - -SELECT 'accessors01', ST_IsEmpty(the_geom_2d), ST_isSimple(the_geom_2d), ST_isClosed(the_geom_2d), ST_isRing(the_geom_2d) FROM public.circularstring; -SELECT 'accessors02', ST_IsEmpty(the_geom_3dm), ST_isSimple(the_geom_3dm), ST_isClosed(the_geom_3dm), ST_isRing(the_geom_3dm) FROM public.circularstring; -SELECT 'accessors03', ST_IsEmpty(the_geom_3dz), ST_isSimple(the_geom_3dz), ST_isClosed(the_geom_3dz), ST_isRing(the_geom_3dz) FROM public.circularstring; -SELECT 'accessors04', ST_IsEmpty(the_geom_4d), ST_isSimple(the_geom_4d), ST_isClosed(the_geom_4d), ST_isRing(the_geom_4d) FROM public.circularstring; - -SELECT 'envelope01', ST_AsText(ST_SnapToGrid(ST_Envelope(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; -SELECT 'envelope02', ST_AsText(ST_SnapToGrid(ST_Envelope(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; -SELECT 'envelope03', ST_AsText(ST_SnapToGrid(ST_Envelope(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; -SELECT 'envelope04', ST_AsText(ST_SnapToGrid(ST_Envelope(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; - -SELECT DropGeometryColumn('public', 'circularstring', 'the_geom_4d'); -SELECT DropGeometryColumn('public', 'circularstring', 'the_geom_3dz'); -SELECT DropGeometryColumn('public', 'circularstring', 'the_geom_3dm'); -SELECT DropGeometryColumn('public', 'circularstring', 'the_geom_2d'); -DROP TABLE public.circularstring; -SELECT ST_AsText(st_snaptogrid(box2d('CIRCULARSTRING(220268.439465645 150415.359530563,220227.333322076 150505.561285879,220227.353105332 150406.434743975)'::geometry),0.0001)); -SELECT 'npoints_is_null',ST_NumPoints(ST_GeomFromEWKT('CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3)')); +SET client_min_messages TO warning; + +SELECT 'ndims01', ST_ndims(ST_geomfromewkt('CIRCULARSTRING( + 0 0 0 0, + 0.26794919243112270647255365849413 1 3 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2)')); +SELECT 'geometrytype01', geometrytype(ST_geomfromewkt('CIRCULARSTRING( + 0 0 0 0, + 0.26794919243112270647255365849413 1 3 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2)')); +SELECT 'ndims02', ST_ndims(ST_geomfromewkt('CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 3, + 0.5857864376269049511981127579 1.4142135623730950488016887242097 1)')); +SELECT 'geometrytype02', geometrytype(ST_geomfromewkt('CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 3, + 0.5857864376269049511981127579 1.4142135623730950488016887242097 1)')); +SELECT 'ndims03', ST_ndims(ST_geomfromewkt('CIRCULARSTRINGM( + 0 0 0, + 0.26794919243112270647255365849413 1 -2, + 0.5857864376269049511981127579 1.4142135623730950488016887242097 2)')); +SELECT 'geometrytype03', geometrytype(ST_geomfromewkt('CIRCULARSTRINGM( + 0 0 0, + 0.26794919243112270647255365849413 1 -2, + 0.5857864376269049511981127579 1.4142135623730950488016887242097 2)')); +SELECT 'ndims04', ST_ndims(ST_geomfromewkt('CIRCULARSTRING( + 0 0, + 0.26794919243112270647255365849413 1, + 0.5857864376269049511981127579 1.4142135623730950488016887242097)')); +SELECT 'geometrytype04', geometrytype(ST_geomfromewkt('CIRCULARSTRING( + 0 0, + 0.26794919243112270647255365849413 1, + 0.5857864376269049511981127579 1.4142135623730950488016887242097)')); + +SELECT 'isClosed01', ST_isClosed(ST_geomfromewkt('CIRCULARSTRING( + 0 -2, + -2 0, + 0 2, + 2 0, + 0 -2)')); +SELECT 'isSimple01', ST_isSimple(ST_geomfromewkt('CIRCULARSTRING( + 0 -2, + -2 0, + 0 2, + 2 0, + 0 -2)')); +SELECT 'isRing01', ST_isRing(ST_geomfromewkt('CIRCULARSTRING( + 0 -2, + -2 0, + 0 2, + 2 0, + 0 -2)')); +SELECT 'isClosed02', ST_isClosed(ST_geomfromewkt('CIRCULARSTRING( + 0 -2, + -2 0, + 0 2, + -2 0, + 2 -2, + -2 0, + -2 -2, + -2 0, + 0 -2)')); +SELECT 'isSimple02', ST_isSimple(ST_geomfromewkt('CIRCULARSTRING( + 0 -2, + -2 0, + 0 2, + -2 0, + 2 -2, + -2 0, + -2 -2, + -2 0, + 0 -2)')); +SELECT 'isRing02', ST_isRing(ST_geomfromewkt('CIRCULARSTRING( + 0 -2, + -2 0, + 0 2, + -2 0, + 2 -2, + -2 0, + -2 -2, + -2 0, + 0 -2)')); + +CREATE TABLE public.circularstring (id INTEGER, description VARCHAR, +the_geom_2d GEOMETRY(CIRCULARSTRING), +the_geom_3dm GEOMETRY(CIRCULARSTRINGM), +the_geom_3dz GEOMETRY(CIRCULARSTRINGZ), +the_geom_4d GEOMETRY(CIRCULARSTRINGZM)); + +INSERT INTO public.circularstring ( + id, + description + ) VALUES ( + 1, + '180-135 degrees'); +UPDATE public.circularstring + SET the_geom_4d = ST_Geomfromewkt('CIRCULARSTRING( + 0 0 0 0, + 0.26794919243112270647255365849413 1 3 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2)') + WHERE id = 1; +UPDATE public.circularstring + SET the_geom_3dz = ST_Geomfromewkt('CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 3, + 0.5857864376269049511981127579 1.4142135623730950488016887242097 1)') + WHERE id = 1; +UPDATE public.circularstring + SET the_geom_3dm = ST_Geomfromewkt('CIRCULARSTRINGM( + 0 0 0, + 0.26794919243112270647255365849413 1 -2, + 0.5857864376269049511981127579 1.4142135623730950488016887242097 2)') + WHERE id = 1; +UPDATE public.circularstring + SET the_geom_2d = ST_Geomfromewkt('CIRCULARSTRING( + 0 0, + 0.26794919243112270647255365849413 1, + 0.5857864376269049511981127579 1.4142135623730950488016887242097)') + WHERE id = 1; + +INSERT INTO public.circularstring ( + id, + description + ) VALUES ( + 2, + '2-segment string'); +UPDATE public.circularstring + SET the_geom_4d = ST_Geomfromewkt('CIRCULARSTRING( + -5 0 0 4, + 0 5 1 3, + 5 0 2 2, + 10 -5 3 1, + 15 0 4 0)') + WHERE id = 2; +UPDATE public.circularstring + SET the_geom_3dz = ST_Geomfromewkt('CIRCULARSTRING( + -5 0 0, + 0 5 1, + 5 0 2, + 10 -5 3, + 15 0 4)') + WHERE id = 2; +UPDATE public.circularstring + SET the_geom_3dm = ST_Geomfromewkt('CIRCULARSTRINGM( + -5 0 4, + 0 5 3, + 5 0 2, + 10 -5 1, + 15 0 0)') + WHERE id = 2; +UPDATE public.circularstring + SET the_geom_2d = ST_Geomfromewkt('CIRCULARSTRING( + -5 0, + 0 5, + 5 0, + 10 -5, + 15 0)') + WHERE id = 2; + +SELECT 'astext01', ST_astext(the_geom_2d) FROM public.circularstring; +SELECT 'astext02', ST_astext(the_geom_3dm) FROM public.circularstring; +SELECT 'astext03', ST_astext(the_geom_3dz) FROM public.circularstring; +SELECT 'astext04', ST_astext(the_geom_4d) FROM public.circularstring; + +SELECT 'asewkt01', ST_asewkt(the_geom_2d) FROM public.circularstring; +SELECT 'asewkt02', ST_asewkt(the_geom_3dm) FROM public.circularstring; +SELECT 'asewkt03', ST_asewkt(the_geom_3dz) FROM public.circularstring; +SELECT 'asewkt04', ST_asewkt(the_geom_4d) FROM public.circularstring; + +-- These tests will fail on different architectures +-- We need a way to handle multiple byte orderings +--SELECT 'asbinary01', encode(asbinary(the_geom_2d), 'hex') FROM public.circularstring; +--SELECT 'asbinary02', encode(asbinary(the_geom_3dm), 'hex') FROM public.circularstring; +--SELECT 'asbinary03', encode(asbinary(the_geom_3dz), 'hex') FROM public.circularstring; +--SELECT 'asbinary04', encode(asbinary(the_geom_4d), 'hex') FROM public.circularstring; +-- +--SELECT 'asewkb01', encode(asewkb(the_geom_2d), 'hex') FROM public.circularstring; +--SELECT 'asewkb02', encode(asewkb(the_geom_3dm), 'hex') FROM public.circularstring; +--SELECT 'asewkb03', encode(asewkb(the_geom_3dz), 'hex') FROM public.circularstring; +--SELECT 'asewkb04', encode(asewkb(the_geom_4d), 'hex') FROM public.circularstring; + +SELECT 'ST_CurveToLine-201', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; +SELECT 'ST_CurveToLine-202', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; +SELECT 'ST_CurveToLine-203', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; +SELECT 'ST_CurveToLine-204', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; + +SELECT 'ST_CurveToLine-401', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; +SELECT 'ST_CurveToLine-402', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; +SELECT 'ST_CurveToLine-403', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; +SELECT 'ST_CurveToLine-404', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; + +SELECT 'ST_CurveToLine01', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; +SELECT 'ST_CurveToLine02', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; +SELECT 'ST_CurveToLine03', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; +SELECT 'ST_CurveToLine04', ST_asewkt( ST_SnapToGrid(ST_CurveToLine(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; + +--Removed due to discrepencies between hardware +--SELECT 'box2d01', box2d(the_geom_2d) FROM public.circularstring; +--SELECT 'box2d02', box2d(the_geom_3dm) FROM public.circularstring; +--SELECT 'box2d03', box2d(the_geom_3dz) FROM public.circularstring; +--SELECT 'box2d04', box2d(the_geom_4d) FROM public.circularstring; + +--SELECT 'box3d01', box3d(the_geom_2d) FROM public.circularstring; +--SELECT 'box3d02', box3d(the_geom_3dm) FROM public.circularstring; +--SELECT 'box3d03', box3d(the_geom_3dz) FROM public.circularstring; +--SELECT 'box3d04', box3d(the_geom_4d) FROM public.circularstring; +-- TODO: ST_SnapToGrid is required to remove platform dependent precision +-- issues. Until ST_SnapToGrid is updated to work against curves, these +-- tests cannot be run. +--SELECT 'ST_LineToCurve01', ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_2d))) FROM public.circularstring; +--SELECT 'ST_LineToCurve02', ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dm))) FROM public.circularstring; +--SELECT 'ST_LineToCurve03', ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dz))) FROM public.circularstring; +--SELECT 'ST_LineToCurve04', ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_4d))) FROM public.circularstring; + +-- Repeat tests with new function names. +SELECT 'astext01', ST_astext(the_geom_2d) FROM public.circularstring; +SELECT 'astext02', ST_astext(the_geom_3dm) FROM public.circularstring; +SELECT 'astext03', ST_astext(the_geom_3dz) FROM public.circularstring; +SELECT 'astext04', ST_astext(the_geom_4d) FROM public.circularstring; + +SELECT 'asewkt01', ST_asewkt(the_geom_2d) FROM public.circularstring; +SELECT 'asewkt02', ST_asewkt(the_geom_3dm) FROM public.circularstring; +SELECT 'asewkt03', ST_asewkt(the_geom_3dz) FROM public.circularstring; +SELECT 'asewkt04', ST_asewkt(the_geom_4d) FROM public.circularstring; + +-- These tests will fail on different architectures +-- We need a way to handle multiple byte orderings +--SELECT 'asbinary01', encode(ST_asbinary(the_geom_2d), 'hex') FROM public.circularstring; +--SELECT 'asbinary02', encode(ST_asbinary(the_geom_3dm), 'hex') FROM public.circularstring; +--SELECT 'asbinary03', encode(ST_asbinary(the_geom_3dz), 'hex') FROM public.circularstring; +--SELECT 'asbinary04', encode(ST_asbinary(the_geom_4d), 'hex') FROM public.circularstring; +-- +--SELECT 'asewkb01', encode(ST_asewkb(the_geom_2d), 'hex') FROM public.circularstring; +--SELECT 'asewkb02', encode(ST_asewkb(the_geom_3dm), 'hex') FROM public.circularstring; +--SELECT 'asewkb03', encode(ST_asewkb(the_geom_3dz), 'hex') FROM public.circularstring; +--SELECT 'asewkb04', encode(ST_asewkb(the_geom_4d), 'hex') FROM public.circularstring; + +--Removed due to discrepencies between hardware +--SELECT 'box2d01', box2d(the_geom_2d) FROM public.circularstring; +--SELECT 'box2d02', box2d(the_geom_3dm) FROM public.circularstring; +--SELECT 'box2d03', box2d(the_geom_3dz) FROM public.circularstring; +--SELECT 'box2d04', box2d(the_geom_4d) FROM public.circularstring; + +--SELECT 'box3d01', box3d(the_geom_2d) FROM public.circularstring; +--SELECT 'box3d02', box3d(the_geom_3dm) FROM public.circularstring; +--SELECT 'box3d03', box3d(the_geom_3dz) FROM public.circularstring; +--SELECT 'box3d04', box3d(the_geom_4d) FROM public.circularstring; + +SELECT 'isValid01', ST_isValid(the_geom_2d) FROM public.circularstring; +SELECT 'isValid02', ST_isValid(the_geom_3dm) FROM public.circularstring; +SELECT 'isValid03', ST_isValid(the_geom_3dz) FROM public.circularstring; +SELECT 'isValid04', ST_isValid(the_geom_4d) FROM public.circularstring; + +SELECT 'dimension01', ST_dimension(the_geom_2d) FROM public.circularstring; +SELECT 'dimension02', ST_dimension(the_geom_3dm) FROM public.circularstring; +SELECT 'dimension03', ST_dimension(the_geom_3dz) FROM public.circularstring; +SELECT 'dimension04', ST_dimension(the_geom_4d) FROM public.circularstring; + +SELECT 'SRID01', ST_SRID(the_geom_2d) FROM public.circularstring; +SELECT 'SRID02', ST_SRID(the_geom_3dm) FROM public.circularstring; +SELECT 'SRID03', ST_SRID(the_geom_3dz) FROM public.circularstring; +SELECT 'SRID04', ST_SRID(the_geom_4d) FROM public.circularstring; + +SELECT 'accessors01', ST_IsEmpty(the_geom_2d), ST_isSimple(the_geom_2d), ST_isClosed(the_geom_2d), ST_isRing(the_geom_2d) FROM public.circularstring; +SELECT 'accessors02', ST_IsEmpty(the_geom_3dm), ST_isSimple(the_geom_3dm), ST_isClosed(the_geom_3dm), ST_isRing(the_geom_3dm) FROM public.circularstring; +SELECT 'accessors03', ST_IsEmpty(the_geom_3dz), ST_isSimple(the_geom_3dz), ST_isClosed(the_geom_3dz), ST_isRing(the_geom_3dz) FROM public.circularstring; +SELECT 'accessors04', ST_IsEmpty(the_geom_4d), ST_isSimple(the_geom_4d), ST_isClosed(the_geom_4d), ST_isRing(the_geom_4d) FROM public.circularstring; + +SELECT 'envelope01', ST_AsText(ST_SnapToGrid(ST_Envelope(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; +SELECT 'envelope02', ST_AsText(ST_SnapToGrid(ST_Envelope(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; +SELECT 'envelope03', ST_AsText(ST_SnapToGrid(ST_Envelope(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; +SELECT 'envelope04', ST_AsText(ST_SnapToGrid(ST_Envelope(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.circularstring; + +SELECT DropGeometryColumn('public', 'circularstring', 'the_geom_4d'); +SELECT DropGeometryColumn('public', 'circularstring', 'the_geom_3dz'); +SELECT DropGeometryColumn('public', 'circularstring', 'the_geom_3dm'); +SELECT DropGeometryColumn('public', 'circularstring', 'the_geom_2d'); +DROP TABLE public.circularstring; +SELECT ST_AsText(st_snaptogrid(box2d('CIRCULARSTRING(220268.439465645 150415.359530563,220227.333322076 150505.561285879,220227.353105332 150406.434743975)'::geometry),0.0001)); +SELECT 'npoints_is_null',ST_NumPoints(ST_GeomFromEWKT('CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3)')); diff --git a/regress/sql-mm-compoundcurve.sql b/regress/sql-mm-compoundcurve.sql index cf2467b25..f13d3a897 100644 --- a/regress/sql-mm-compoundcurve.sql +++ b/regress/sql-mm-compoundcurve.sql @@ -1,324 +1,324 @@ -SELECT 'ndims01', ST_NDims(ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0 0 0, - 0.26794919243112270647255365849413 1 3 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2, - 2 0 0 0, - 0 0 0 0))')); -SELECT 'geometrytype01', geometrytype(ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0 0 0, - 0.26794919243112270647255365849413 1 3 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2, - 2 0 0 0, - 0 0 0 0))')); -SELECT 'ndims02', ST_NDims(ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 3, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1, - 2 0 0, - 0 0 0))')); -SELECT 'geometrytype02', geometrytype(ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 3, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1, - 2 0 0, - 0 0 0))')); -SELECT 'ndims03', ST_NDims(ST_Geomfromewkt('COMPOUNDCURVEM(CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 2, - 2 0 0, - 0 0 0))')); -SELECT 'geometrytype03', geometrytype(ST_Geomfromewkt('COMPOUNDCURVEM(CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 2, - 2 0 0, - 0 0 0))')); -SELECT 'ndims04', ST_NDims(ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0, - 0.26794919243112270647255365849413 1, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097, - 2 0, - 0 0))')); -SELECT 'geometrytype04', geometrytype(ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0, - 0.26794919243112270647255365849413 1, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097, - 2 0, - 0 0))')); - --- Repeat tests with new function names. -SELECT 'ndims01', ST_NDims(ST_geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0 0 0, - 0.26794919243112270647255365849413 1 3 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2, - 2 0 0 0, - 0 0 0 0))')); -SELECT 'geometrytype01', geometrytype(ST_geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0 0 0, - 0.26794919243112270647255365849413 1 3 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2, - 2 0 0 0, - 0 0 0 0))')); -SELECT 'ndims02', ST_NDims(ST_geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 3, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1, - 2 0 0, - 0 0 0))')); -SELECT 'geometrytype02', geometrytype(ST_geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 3, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1, - 2 0 0, - 0 0 0))')); -SELECT 'ndims03', ST_NDims(ST_geomfromewkt('COMPOUNDCURVEM(CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 2, - 2 0 0, - 0 0 0))')); -SELECT 'geometrytype03', geometrytype(ST_geomfromewkt('COMPOUNDCURVEM(CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 2, - 2 0 0, - 0 0 0))')); -SELECT 'ndims04', ST_NDims(ST_geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0, - 0.26794919243112270647255365849413 1, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097, - 2 0, - 0 0))')); -SELECT 'geometrytype04', geometrytype(ST_geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0, - 0.26794919243112270647255365849413 1, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097, - 2 0, - 0 0))')); - -CREATE TABLE public.compoundcurve (id INTEGER, description VARCHAR, -the_geom_2d GEOMETRY(COMPOUNDCURVE), -the_geom_3dm GEOMETRY(COMPOUNDCURVEM), -the_geom_3dz GEOMETRY(COMPOUNDCURVEZ), -the_geom_4d GEOMETRY(COMPOUNDCURVEZM) -); - -INSERT INTO public.compoundcurve ( - id, - description - ) VALUES ( - 2, - 'compoundcurve'); -UPDATE public.compoundcurve - SET the_geom_4d = ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0 0 0, - 0.26794919243112270647255365849413 1 3 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2, - 2 0 0 0, - 0 0 0 0))'); -UPDATE public.compoundcurve - SET the_geom_3dz = ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 3, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1, - 2 0 0, - 0 0 0))'); -UPDATE public.compoundcurve - SET the_geom_3dm = ST_Geomfromewkt('COMPOUNDCURVEM(CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 2, - 2 0 0, - 0 0 0))'); -UPDATE public.compoundcurve - SET the_geom_2d = ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( - 0 0, - 0.26794919243112270647255365849413 1, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097, - 2 0, - 0 0))'); - -SELECT 'astext01', ST_Astext(the_geom_2d) FROM public.compoundcurve; -SELECT 'astext02', ST_Astext(the_geom_3dm) FROM public.compoundcurve; -SELECT 'astext03', ST_Astext(the_geom_3dz) FROM public.compoundcurve; -SELECT 'astext04', ST_Astext(the_geom_4d) FROM public.compoundcurve; - -SELECT 'asewkt01', ST_Asewkt(the_geom_2d) FROM public.compoundcurve; -SELECT 'asewkt02', ST_Asewkt(the_geom_3dm) FROM public.compoundcurve; -SELECT 'asewkt03', ST_Asewkt(the_geom_3dz) FROM public.compoundcurve; -SELECT 'asewkt04', ST_Asewkt(the_geom_4d) FROM public.compoundcurve; - --- These tests will fail on different architectures --- We need a way to handle multiple byte orderings ---SELECT 'asbinary01', encode(asbinary(the_geom_2d), 'hex') FROM public.compoundcurve; ---SELECT 'asbinary02', encode(asbinary(the_geom_3dm), 'hex') FROM public.compoundcurve; ---SELECT 'asbinary03', encode(asbinary(the_geom_3dz), 'hex') FROM public.compoundcurve; ---SELECT 'asbinary04', encode(asbinary(the_geom_4d), 'hex') FROM public.compoundcurve; --- ---SELECT 'asewkb01', encode(asewkb(the_geom_2d), 'hex') FROM public.compoundcurve; ---SELECT 'asewkb02', encode(asewkb(the_geom_3dm), 'hex') FROM public.compoundcurve; ---SELECT 'asewkb03', encode(asewkb(the_geom_3dz), 'hex') FROM public.compoundcurve; ---SELECT 'asewkb04', encode(asewkb(the_geom_4d), 'hex') FROM public.compoundcurve; - -SELECT 'ST_CurveToLine-201', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; -SELECT 'ST_CurveToLine-202', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; -SELECT 'ST_CurveToLine-203', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; -SELECT 'ST_CurveToLine-204', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; - -SELECT 'ST_CurveToLine-401', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; -SELECT 'ST_CurveToLine-402', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; -SELECT 'ST_CurveToLine-403', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; -SELECT 'ST_CurveToLine-404', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; - -SELECT 'ST_CurveToLine01', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; -SELECT 'ST_CurveToLine02', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; -SELECT 'ST_CurveToLine03', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; -SELECT 'ST_CurveToLine04', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; - --- Removed due to discrepencies between hardware ---SELECT 'box2d01', box2d(the_geom_2d) FROM public.compoundcurve; ---SELECT 'box2d02', box2d(the_geom_3dm) FROM public.compoundcurve; ---SELECT 'box2d03', box2d(the_geom_3dz) FROM public.compoundcurve; ---SELECT 'box2d04', box2d(the_geom_4d) FROM public.compoundcurve; - ---SELECT 'box3d01', box3d(the_geom_2d) FROM public.compoundcurve; ---SELECT 'box3d02', box3d(the_geom_3dm) FROM public.compoundcurve; ---SELECT 'box3d03', box3d(the_geom_3dz) FROM public.compoundcurve; ---SELECT 'box3d04', box3d(the_geom_4d) FROM public.compoundcurve; - --- SELECT 'isValid01', isValid(the_geom_2d) FROM public.compoundcurve; --- SELECT 'isValid02', isValid(the_geom_3dm) FROM public.compoundcurve; --- SELECT 'isValid03', isValid(the_geom_3dz) FROM public.compoundcurve; --- SELECT 'isValid04', isValid(the_geom_4d) FROM public.compoundcurve; - --- SELECT 'dimension01', dimension(the_geom_2d) FROM public.compoundcurve; --- SELECT 'dimension02', dimension(the_geom_3dm) FROM public.compoundcurve; --- SELECT 'dimension03', dimension(the_geom_3dz) FROM public.compoundcurve; --- SELECT 'dimension04', dimension(the_geom_4d) FROM public.compoundcurve; - --- SELECT 'SRID01', ST_SRID(the_geom_2d) FROM public.compoundcurve; --- SELECT 'SRID02', ST_SRID(the_geom_3dm) FROM public.compoundcurve; --- SELECT 'SRID03', ST_SRID(the_geom_3dz) FROM public.compoundcurve; --- SELECT 'SRID04', ST_SRID(the_geom_4d) FROM public.compoundcurve; - --- SELECT 'accessor01', isEmpty(the_geom_2d), isSimple(the_geom_2d), isClosed(the_geom_2d), isRing(the_geom_2d) FROM public.compoundcurve; --- SELECT 'accessor02', isEmpty(the_geom_3dm), isSimple(the_geom_3dm), isClosed(the_geom_3dm), isRing(the_geom_3dm) FROM public.compoundcurve; --- SELECT 'accessor03', isEmpty(the_geom_3dz), isSimple(the_geom_3dz), isClosed(the_geom_3dz), isRing(the_geom_3dz) FROM public.compoundcurve; --- SELECT 'accessor04', isEmpty(the_geom_4d), isSimple(the_geom_4d), isClosed(the_geom_4d), isRing(the_geom_4d) FROM public.compoundcurve; - --- SELECT 'envelope01', ST_AsText(ST_SnapToGrid(envelope(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; --- SELECT 'envelope02', ST_AsText(ST_SnapToGrid(envelope(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; --- SELECT 'envelope03', ST_AsText(ST_SnapToGrid(envelope(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; --- SELECT 'envelope04', ST_AsText(ST_SnapToGrid(envelope(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; - --- TODO: ST_SnapToGrid is required to remove platform dependent precision --- issues. Until ST_SnapToGrid is updated to work against curves, these --- tests cannot be run. ---SELECT 'ST_LineToCurve', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_2d))) FROM public.compoundcurve; ---SELECT 'ST_LineToCurve', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dm))) FROM public.compoundcurve; ---SELECT 'ST_LineToCurve', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dz))) FROM public.compoundcurve; ---SELECT 'ST_LineToCurve', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_4d))) FROM public.compoundcurve; - --- Repeat tests on new function names. -SELECT 'astext01', ST_astext(the_geom_2d) FROM public.compoundcurve; -SELECT 'astext02', ST_astext(the_geom_3dm) FROM public.compoundcurve; -SELECT 'astext03', ST_astext(the_geom_3dz) FROM public.compoundcurve; -SELECT 'astext04', ST_astext(the_geom_4d) FROM public.compoundcurve; - -SELECT 'asewkt01', ST_asewkt(the_geom_2d) FROM public.compoundcurve; -SELECT 'asewkt02', ST_asewkt(the_geom_3dm) FROM public.compoundcurve; -SELECT 'asewkt03', ST_asewkt(the_geom_3dz) FROM public.compoundcurve; -SELECT 'asewkt04', ST_asewkt(the_geom_4d) FROM public.compoundcurve; - ---SELECT 'asbinary01', encode(ST_asbinary(the_geom_2d), 'hex') FROM public.compoundcurve; ---SELECT 'asbinary02', encode(ST_asbinary(the_geom_3dm), 'hex') FROM public.compoundcurve; ---SELECT 'asbinary03', encode(ST_asbinary(the_geom_3dz), 'hex') FROM public.compoundcurve; ---SELECT 'asbinary04', encode(ST_asbinary(the_geom_4d), 'hex') FROM public.compoundcurve; --- ---SELECT 'asewkb01', encode(ST_asewkb(the_geom_2d), 'hex') FROM public.compoundcurve; ---SELECT 'asewkb02', encode(ST_asewkb(the_geom_3dm), 'hex') FROM public.compoundcurve; ---SELECT 'asewkb03', encode(ST_asewkb(the_geom_3dz), 'hex') FROM public.compoundcurve; ---SELECT 'asewkb04', encode(ST_asewkb(the_geom_4d), 'hex') FROM public.compoundcurve; - --- Removed due to discrepencies between hardware ---SELECT 'box2d01', ST_box2d(the_geom_2d) FROM public.compoundcurve; ---SELECT 'box2d02', ST_box2d(the_geom_3dm) FROM public.compoundcurve; ---SELECT 'box2d03', ST_box2d(the_geom_3dz) FROM public.compoundcurve; ---SELECT 'box2d04', ST_box2d(the_geom_4d) FROM public.compoundcurve; - ---SELECT 'box3d01', ST_box3d(the_geom_2d) FROM public.compoundcurve; ---SELECT 'box3d02', ST_box3d(the_geom_3dm) FROM public.compoundcurve; ---SELECT 'box3d03', ST_box3d(the_geom_3dz) FROM public.compoundcurve; ---SELECT 'box3d04', ST_box3d(the_geom_4d) FROM public.compoundcurve; - -SELECT 'isValid01', ST_isValid(the_geom_2d) FROM public.compoundcurve; -SELECT 'isValid02', ST_isValid(the_geom_3dm) FROM public.compoundcurve; -SELECT 'isValid03', ST_isValid(the_geom_3dz) FROM public.compoundcurve; -SELECT 'isValid04', ST_isValid(the_geom_4d) FROM public.compoundcurve; - -SELECT 'dimension01', ST_dimension(the_geom_2d) FROM public.compoundcurve; -SELECT 'dimension02', ST_dimension(the_geom_3dm) FROM public.compoundcurve; -SELECT 'dimension03', ST_dimension(the_geom_3dz) FROM public.compoundcurve; -SELECT 'dimension04', ST_dimension(the_geom_4d) FROM public.compoundcurve; - -SELECT 'SRID01', ST_SRID(the_geom_2d) FROM public.compoundcurve; -SELECT 'SRID02', ST_SRID(the_geom_3dm) FROM public.compoundcurve; -SELECT 'SRID03', ST_SRID(the_geom_3dz) FROM public.compoundcurve; -SELECT 'SRID04', ST_SRID(the_geom_4d) FROM public.compoundcurve; - -SELECT 'accessor01', ST_isEmpty(the_geom_2d), ST_isSimple(the_geom_2d), ST_isClosed(the_geom_2d), ST_isRing(the_geom_2d) FROM public.compoundcurve; -SELECT 'accessor02', ST_isEmpty(the_geom_3dm), ST_isSimple(the_geom_3dm), ST_isClosed(the_geom_3dm), ST_isRing(the_geom_3dm) FROM public.compoundcurve; -SELECT 'accessor03', ST_isEmpty(the_geom_3dz), ST_isSimple(the_geom_3dz), ST_isClosed(the_geom_3dz), ST_isRing(the_geom_3dz) FROM public.compoundcurve; -SELECT 'accessor04', ST_isEmpty(the_geom_4d), ST_isSimple(the_geom_4d), ST_isClosed(the_geom_4d), ST_isRing(the_geom_4d) FROM public.compoundcurve; - -SELECT 'envelope01', ST_asText(ST_snapToGrid(ST_envelope(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; -SELECT 'envelope02', ST_asText(ST_snapToGrid(ST_envelope(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; -SELECT 'envelope03', ST_asText(ST_snapToGrid(ST_envelope(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; -SELECT 'envelope04', ST_asText(ST_snapToGrid(ST_envelope(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; - -SELECT DropGeometryColumn('public', 'compoundcurve', 'the_geom_4d'); -SELECT DropGeometryColumn('public', 'compoundcurve', 'the_geom_3dz'); -SELECT DropGeometryColumn('public', 'compoundcurve', 'the_geom_3dm'); -SELECT DropGeometryColumn('public', 'compoundcurve', 'the_geom_2d'); -DROP TABLE public.compoundcurve; - -SELECT 'valid wkt compound curve 1', ST_GeomFromEWKT('COMPOUNDCURVE((153.72942375 -27.21757040, 152.29285719 -29.23940482, 154.74034096 -30.51635287),(154.74034096 -30.51635287, 152.39926953 -32.16574411, 155.11278414 -34.08116619, 151.86720784 -35.62414508))'); -SELECT 'valid wkt compound curve 2', ST_GeomFromEWKT('COMPOUNDCURVE((153.72942375 -27.21757040, 152.29285719 -29.23940482, 154.74034096 -30.51635287, 152.39926953 -32.16574411, 155.11278414 -34.08116619, 151.86720784 -35.62414508))'); -SELECT 'valid wkt compound curve 3', ST_GeomFromEWKT('COMPOUNDCURVE((151.60117699 -27.32398274, 151.22873381 -35.94338210, 150.74987829 -27.80283826))'); -SELECT 'valid wkt compound curve 4', ST_GeomFromEWKT('COMPOUNDCURVE((153.72942375 -27.21757040, 152.29285719 -29.23940482, 154.74034096 -30.51635287),CIRCULARSTRING(154.74034096 -30.51635287, 154.74034096 -30.51635287, 152.39926953 -32.16574411, 155.11278414 -34.08116619, 151.86720784 -35.62414508))'); -SELECT 'valid wkt compound curve 5', ST_GeomFromEWKT('COMPOUNDCURVE(CIRCULARSTRING(157.87950492 -27.59001358, 156.01728901 -28.28169378, 155.59163966 -26.52589021),(155.59163966 -26.52589021, 153.72942375 -27.21757040, 152.29285719 -29.23940482, 154.74034096 -30.51635287),CIRCULARSTRING(154.74034096 -30.51635287, 154.74034096 -30.51635287, 152.39926953 -32.16574411, 155.11278414 -34.08116619, 151.86720784 -35.62414508))'); -SELECT 'invalid wkt compound curve 1', ST_GeomFromEWKT('COMPOUNDCURVE((153.72942375 -27.21757040, 152.29285719 -29.23940482, 154.74034096 -30.51635287),(152.39926953 -32.16574411, 155.11278414 -34.08116619, 151.86720784 -35.62414508))'); -SELECT 'invalid wkt compound curve 2', ST_GeomFromEWKT('COMPOUNDCURVE((153.72942375 -27.21757040, 152.29285719 -29.23940482),CIRCULARSTRING(154.74034096 -30.51635287, 154.74034096 -30.51635287, 152.39926953 -32.16574411, 155.11278414 -34.08116619, 151.86720784 -35.62414508))'); -SELECT 'invalid wkt compound curve 3', ST_GeomFromEWKT('COMPOUNDCURVE(CIRCULARSTRING(157.87950492 -27.59001358, 156.01728901 -28.28169378, 155.59163966 -26.52589021, 153.72942375 -27.21757040),(153.72942375 -27.21757040, 152.29285719 -29.23940482),CIRCULARSTRING(154.74034096 -30.51635287, 154.74034096 -30.51635287, 152.39926953 -32.16574411, 155.11278414 -34.08116619, 151.86720784 -35.62414508))'); -SELECT 'valid wkb compound curve 1', ST_asEWKT(ST_GeomFromEWKB(decode('0109000000020000000102000000030000009FE5797057376340E09398B1B2373BC05AAE0A165F0963409F6760A2493D3DC0DB6286DFB057634082D8A1B32F843EC0010200000004000000DB6286DFB057634082D8A1B32F843EC075B4E4D0C60C634031FA5D1A371540C0D7197CED9B636340A3CB59A7630A41C050F4A72AC0FB6240974769FCE3CF41C0', 'hex'))); -SELECT 'valid wkb compound curve 2', ST_asEWKT(ST_GeomFromEWKB(decode('0109000000010000000102000000060000009FE5797057376340E09398B1B2373BC05AAE0A165F0963409F6760A2493D3DC0DB6286DFB057634082D8A1B32F843EC075B4E4D0C60C634031FA5D1A371540C0D7197CED9B636340A3CB59A7630A41C050F4A72AC0FB6240974769FCE3CF41C0', 'hex'))); -SELECT 'valid wkb compound curve 3', ST_asEWKT(ST_GeomFromEWKB(decode('0109000000010000000102000000030000000CE586D73CF36240BBC46888F0523BC0102E91C951E76240DF90A1BEC0F841C0F970C100FFD7624074ADE6CE86CD3BC0', 'hex'))); -SELECT 'valid wkb compound curve 4', ST_asEWKT(ST_GeomFromEWKB(decode('0109000000020000000102000000030000009FE5797057376340E09398B1B2373BC05AAE0A165F0963409F6760A2493D3DC0DB6286DFB057634082D8A1B32F843EC0010800000005000000DB6286DFB057634082D8A1B32F843EC0DB6286DFB057634082D8A1B32F843EC075B4E4D0C60C634031FA5D1A371540C0D7197CED9B636340A3CB59A7630A41C050F4A72AC0FB6240974769FCE3CF41C0', 'hex'))); -SELECT 'valid wkb compound curve 5', ST_asEWKT(ST_GeomFromEWKB(decode('010900000003000000010800000003000000468280E724BC6340BF4B46210B973BC0F890AEA18D8063402D9664151D483CC0EED64BB6EE726340903CA5BDA0863AC0010200000004000000EED64BB6EE726340903CA5BDA0863AC09FE5797057376340E09398B1B2373BC05AAE0A165F0963409F6760A2493D3DC0DB6286DFB057634082D8A1B32F843EC0010800000005000000DB6286DFB057634082D8A1B32F843EC0DB6286DFB057634082D8A1B32F843EC075B4E4D0C60C634031FA5D1A371540C0D7197CED9B636340A3CB59A7630A41C050F4A72AC0FB6240974769FCE3CF41C0', 'hex'))); -SELECT 'null response', ST_NumPoints(ST_GeomFromEWKT('COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0))')); -SELECT 'minpoints issues - pass', ST_GeomFromText('COMPOUNDCURVE((0 0,1 1))'); -SELECT 'minpoints issues - pass', ST_GeomFromText('COMPOUNDCURVE(CIRCULARSTRING(0 0,0 1,1 1))'); -SELECT 'minpoints issues - fail', ST_GeomFromText('COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1))'); -SELECT 'minpoints issues - fail', ST_GeomFromText('COMPOUNDCURVE(CIRCULARSTRING(0 0))'); -SELECT 'minpoints issues - fail', ST_GeomFromText('COMPOUNDCURVE((0 0),(0 0,1 1))'); +SELECT 'ndims01', ST_NDims(ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0 0 0, + 0.26794919243112270647255365849413 1 3 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2, + 2 0 0 0, + 0 0 0 0))')); +SELECT 'geometrytype01', geometrytype(ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0 0 0, + 0.26794919243112270647255365849413 1 3 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2, + 2 0 0 0, + 0 0 0 0))')); +SELECT 'ndims02', ST_NDims(ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 3, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1, + 2 0 0, + 0 0 0))')); +SELECT 'geometrytype02', geometrytype(ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 3, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1, + 2 0 0, + 0 0 0))')); +SELECT 'ndims03', ST_NDims(ST_Geomfromewkt('COMPOUNDCURVEM(CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 2, + 2 0 0, + 0 0 0))')); +SELECT 'geometrytype03', geometrytype(ST_Geomfromewkt('COMPOUNDCURVEM(CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 2, + 2 0 0, + 0 0 0))')); +SELECT 'ndims04', ST_NDims(ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0, + 0.26794919243112270647255365849413 1, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097, + 2 0, + 0 0))')); +SELECT 'geometrytype04', geometrytype(ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0, + 0.26794919243112270647255365849413 1, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097, + 2 0, + 0 0))')); + +-- Repeat tests with new function names. +SELECT 'ndims01', ST_NDims(ST_geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0 0 0, + 0.26794919243112270647255365849413 1 3 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2, + 2 0 0 0, + 0 0 0 0))')); +SELECT 'geometrytype01', geometrytype(ST_geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0 0 0, + 0.26794919243112270647255365849413 1 3 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2, + 2 0 0 0, + 0 0 0 0))')); +SELECT 'ndims02', ST_NDims(ST_geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 3, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1, + 2 0 0, + 0 0 0))')); +SELECT 'geometrytype02', geometrytype(ST_geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 3, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1, + 2 0 0, + 0 0 0))')); +SELECT 'ndims03', ST_NDims(ST_geomfromewkt('COMPOUNDCURVEM(CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 2, + 2 0 0, + 0 0 0))')); +SELECT 'geometrytype03', geometrytype(ST_geomfromewkt('COMPOUNDCURVEM(CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 2, + 2 0 0, + 0 0 0))')); +SELECT 'ndims04', ST_NDims(ST_geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0, + 0.26794919243112270647255365849413 1, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097, + 2 0, + 0 0))')); +SELECT 'geometrytype04', geometrytype(ST_geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0, + 0.26794919243112270647255365849413 1, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097, + 2 0, + 0 0))')); + +CREATE TABLE public.compoundcurve (id INTEGER, description VARCHAR, +the_geom_2d GEOMETRY(COMPOUNDCURVE), +the_geom_3dm GEOMETRY(COMPOUNDCURVEM), +the_geom_3dz GEOMETRY(COMPOUNDCURVEZ), +the_geom_4d GEOMETRY(COMPOUNDCURVEZM) +); + +INSERT INTO public.compoundcurve ( + id, + description + ) VALUES ( + 2, + 'compoundcurve'); +UPDATE public.compoundcurve + SET the_geom_4d = ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0 0 0, + 0.26794919243112270647255365849413 1 3 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2, + 2 0 0 0, + 0 0 0 0))'); +UPDATE public.compoundcurve + SET the_geom_3dz = ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 3, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1, + 2 0 0, + 0 0 0))'); +UPDATE public.compoundcurve + SET the_geom_3dm = ST_Geomfromewkt('COMPOUNDCURVEM(CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 2, + 2 0 0, + 0 0 0))'); +UPDATE public.compoundcurve + SET the_geom_2d = ST_Geomfromewkt('COMPOUNDCURVE(CIRCULARSTRING( + 0 0, + 0.26794919243112270647255365849413 1, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097, + 2 0, + 0 0))'); + +SELECT 'astext01', ST_Astext(the_geom_2d) FROM public.compoundcurve; +SELECT 'astext02', ST_Astext(the_geom_3dm) FROM public.compoundcurve; +SELECT 'astext03', ST_Astext(the_geom_3dz) FROM public.compoundcurve; +SELECT 'astext04', ST_Astext(the_geom_4d) FROM public.compoundcurve; + +SELECT 'asewkt01', ST_Asewkt(the_geom_2d) FROM public.compoundcurve; +SELECT 'asewkt02', ST_Asewkt(the_geom_3dm) FROM public.compoundcurve; +SELECT 'asewkt03', ST_Asewkt(the_geom_3dz) FROM public.compoundcurve; +SELECT 'asewkt04', ST_Asewkt(the_geom_4d) FROM public.compoundcurve; + +-- These tests will fail on different architectures +-- We need a way to handle multiple byte orderings +--SELECT 'asbinary01', encode(asbinary(the_geom_2d), 'hex') FROM public.compoundcurve; +--SELECT 'asbinary02', encode(asbinary(the_geom_3dm), 'hex') FROM public.compoundcurve; +--SELECT 'asbinary03', encode(asbinary(the_geom_3dz), 'hex') FROM public.compoundcurve; +--SELECT 'asbinary04', encode(asbinary(the_geom_4d), 'hex') FROM public.compoundcurve; +-- +--SELECT 'asewkb01', encode(asewkb(the_geom_2d), 'hex') FROM public.compoundcurve; +--SELECT 'asewkb02', encode(asewkb(the_geom_3dm), 'hex') FROM public.compoundcurve; +--SELECT 'asewkb03', encode(asewkb(the_geom_3dz), 'hex') FROM public.compoundcurve; +--SELECT 'asewkb04', encode(asewkb(the_geom_4d), 'hex') FROM public.compoundcurve; + +SELECT 'ST_CurveToLine-201', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +SELECT 'ST_CurveToLine-202', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +SELECT 'ST_CurveToLine-203', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +SELECT 'ST_CurveToLine-204', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; + +SELECT 'ST_CurveToLine-401', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +SELECT 'ST_CurveToLine-402', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +SELECT 'ST_CurveToLine-403', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +SELECT 'ST_CurveToLine-404', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; + +SELECT 'ST_CurveToLine01', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +SELECT 'ST_CurveToLine02', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +SELECT 'ST_CurveToLine03', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +SELECT 'ST_CurveToLine04', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; + +-- Removed due to discrepencies between hardware +--SELECT 'box2d01', box2d(the_geom_2d) FROM public.compoundcurve; +--SELECT 'box2d02', box2d(the_geom_3dm) FROM public.compoundcurve; +--SELECT 'box2d03', box2d(the_geom_3dz) FROM public.compoundcurve; +--SELECT 'box2d04', box2d(the_geom_4d) FROM public.compoundcurve; + +--SELECT 'box3d01', box3d(the_geom_2d) FROM public.compoundcurve; +--SELECT 'box3d02', box3d(the_geom_3dm) FROM public.compoundcurve; +--SELECT 'box3d03', box3d(the_geom_3dz) FROM public.compoundcurve; +--SELECT 'box3d04', box3d(the_geom_4d) FROM public.compoundcurve; + +-- SELECT 'isValid01', isValid(the_geom_2d) FROM public.compoundcurve; +-- SELECT 'isValid02', isValid(the_geom_3dm) FROM public.compoundcurve; +-- SELECT 'isValid03', isValid(the_geom_3dz) FROM public.compoundcurve; +-- SELECT 'isValid04', isValid(the_geom_4d) FROM public.compoundcurve; + +-- SELECT 'dimension01', dimension(the_geom_2d) FROM public.compoundcurve; +-- SELECT 'dimension02', dimension(the_geom_3dm) FROM public.compoundcurve; +-- SELECT 'dimension03', dimension(the_geom_3dz) FROM public.compoundcurve; +-- SELECT 'dimension04', dimension(the_geom_4d) FROM public.compoundcurve; + +-- SELECT 'SRID01', ST_SRID(the_geom_2d) FROM public.compoundcurve; +-- SELECT 'SRID02', ST_SRID(the_geom_3dm) FROM public.compoundcurve; +-- SELECT 'SRID03', ST_SRID(the_geom_3dz) FROM public.compoundcurve; +-- SELECT 'SRID04', ST_SRID(the_geom_4d) FROM public.compoundcurve; + +-- SELECT 'accessor01', isEmpty(the_geom_2d), isSimple(the_geom_2d), isClosed(the_geom_2d), isRing(the_geom_2d) FROM public.compoundcurve; +-- SELECT 'accessor02', isEmpty(the_geom_3dm), isSimple(the_geom_3dm), isClosed(the_geom_3dm), isRing(the_geom_3dm) FROM public.compoundcurve; +-- SELECT 'accessor03', isEmpty(the_geom_3dz), isSimple(the_geom_3dz), isClosed(the_geom_3dz), isRing(the_geom_3dz) FROM public.compoundcurve; +-- SELECT 'accessor04', isEmpty(the_geom_4d), isSimple(the_geom_4d), isClosed(the_geom_4d), isRing(the_geom_4d) FROM public.compoundcurve; + +-- SELECT 'envelope01', ST_AsText(ST_SnapToGrid(envelope(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +-- SELECT 'envelope02', ST_AsText(ST_SnapToGrid(envelope(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +-- SELECT 'envelope03', ST_AsText(ST_SnapToGrid(envelope(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +-- SELECT 'envelope04', ST_AsText(ST_SnapToGrid(envelope(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; + +-- TODO: ST_SnapToGrid is required to remove platform dependent precision +-- issues. Until ST_SnapToGrid is updated to work against curves, these +-- tests cannot be run. +--SELECT 'ST_LineToCurve', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_2d))) FROM public.compoundcurve; +--SELECT 'ST_LineToCurve', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dm))) FROM public.compoundcurve; +--SELECT 'ST_LineToCurve', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dz))) FROM public.compoundcurve; +--SELECT 'ST_LineToCurve', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_4d))) FROM public.compoundcurve; + +-- Repeat tests on new function names. +SELECT 'astext01', ST_astext(the_geom_2d) FROM public.compoundcurve; +SELECT 'astext02', ST_astext(the_geom_3dm) FROM public.compoundcurve; +SELECT 'astext03', ST_astext(the_geom_3dz) FROM public.compoundcurve; +SELECT 'astext04', ST_astext(the_geom_4d) FROM public.compoundcurve; + +SELECT 'asewkt01', ST_asewkt(the_geom_2d) FROM public.compoundcurve; +SELECT 'asewkt02', ST_asewkt(the_geom_3dm) FROM public.compoundcurve; +SELECT 'asewkt03', ST_asewkt(the_geom_3dz) FROM public.compoundcurve; +SELECT 'asewkt04', ST_asewkt(the_geom_4d) FROM public.compoundcurve; + +--SELECT 'asbinary01', encode(ST_asbinary(the_geom_2d), 'hex') FROM public.compoundcurve; +--SELECT 'asbinary02', encode(ST_asbinary(the_geom_3dm), 'hex') FROM public.compoundcurve; +--SELECT 'asbinary03', encode(ST_asbinary(the_geom_3dz), 'hex') FROM public.compoundcurve; +--SELECT 'asbinary04', encode(ST_asbinary(the_geom_4d), 'hex') FROM public.compoundcurve; +-- +--SELECT 'asewkb01', encode(ST_asewkb(the_geom_2d), 'hex') FROM public.compoundcurve; +--SELECT 'asewkb02', encode(ST_asewkb(the_geom_3dm), 'hex') FROM public.compoundcurve; +--SELECT 'asewkb03', encode(ST_asewkb(the_geom_3dz), 'hex') FROM public.compoundcurve; +--SELECT 'asewkb04', encode(ST_asewkb(the_geom_4d), 'hex') FROM public.compoundcurve; + +-- Removed due to discrepencies between hardware +--SELECT 'box2d01', ST_box2d(the_geom_2d) FROM public.compoundcurve; +--SELECT 'box2d02', ST_box2d(the_geom_3dm) FROM public.compoundcurve; +--SELECT 'box2d03', ST_box2d(the_geom_3dz) FROM public.compoundcurve; +--SELECT 'box2d04', ST_box2d(the_geom_4d) FROM public.compoundcurve; + +--SELECT 'box3d01', ST_box3d(the_geom_2d) FROM public.compoundcurve; +--SELECT 'box3d02', ST_box3d(the_geom_3dm) FROM public.compoundcurve; +--SELECT 'box3d03', ST_box3d(the_geom_3dz) FROM public.compoundcurve; +--SELECT 'box3d04', ST_box3d(the_geom_4d) FROM public.compoundcurve; + +SELECT 'isValid01', ST_isValid(the_geom_2d) FROM public.compoundcurve; +SELECT 'isValid02', ST_isValid(the_geom_3dm) FROM public.compoundcurve; +SELECT 'isValid03', ST_isValid(the_geom_3dz) FROM public.compoundcurve; +SELECT 'isValid04', ST_isValid(the_geom_4d) FROM public.compoundcurve; + +SELECT 'dimension01', ST_dimension(the_geom_2d) FROM public.compoundcurve; +SELECT 'dimension02', ST_dimension(the_geom_3dm) FROM public.compoundcurve; +SELECT 'dimension03', ST_dimension(the_geom_3dz) FROM public.compoundcurve; +SELECT 'dimension04', ST_dimension(the_geom_4d) FROM public.compoundcurve; + +SELECT 'SRID01', ST_SRID(the_geom_2d) FROM public.compoundcurve; +SELECT 'SRID02', ST_SRID(the_geom_3dm) FROM public.compoundcurve; +SELECT 'SRID03', ST_SRID(the_geom_3dz) FROM public.compoundcurve; +SELECT 'SRID04', ST_SRID(the_geom_4d) FROM public.compoundcurve; + +SELECT 'accessor01', ST_isEmpty(the_geom_2d), ST_isSimple(the_geom_2d), ST_isClosed(the_geom_2d), ST_isRing(the_geom_2d) FROM public.compoundcurve; +SELECT 'accessor02', ST_isEmpty(the_geom_3dm), ST_isSimple(the_geom_3dm), ST_isClosed(the_geom_3dm), ST_isRing(the_geom_3dm) FROM public.compoundcurve; +SELECT 'accessor03', ST_isEmpty(the_geom_3dz), ST_isSimple(the_geom_3dz), ST_isClosed(the_geom_3dz), ST_isRing(the_geom_3dz) FROM public.compoundcurve; +SELECT 'accessor04', ST_isEmpty(the_geom_4d), ST_isSimple(the_geom_4d), ST_isClosed(the_geom_4d), ST_isRing(the_geom_4d) FROM public.compoundcurve; + +SELECT 'envelope01', ST_asText(ST_snapToGrid(ST_envelope(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +SELECT 'envelope02', ST_asText(ST_snapToGrid(ST_envelope(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +SELECT 'envelope03', ST_asText(ST_snapToGrid(ST_envelope(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; +SELECT 'envelope04', ST_asText(ST_snapToGrid(ST_envelope(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.compoundcurve; + +SELECT DropGeometryColumn('public', 'compoundcurve', 'the_geom_4d'); +SELECT DropGeometryColumn('public', 'compoundcurve', 'the_geom_3dz'); +SELECT DropGeometryColumn('public', 'compoundcurve', 'the_geom_3dm'); +SELECT DropGeometryColumn('public', 'compoundcurve', 'the_geom_2d'); +DROP TABLE public.compoundcurve; + +SELECT 'valid wkt compound curve 1', ST_GeomFromEWKT('COMPOUNDCURVE((153.72942375 -27.21757040, 152.29285719 -29.23940482, 154.74034096 -30.51635287),(154.74034096 -30.51635287, 152.39926953 -32.16574411, 155.11278414 -34.08116619, 151.86720784 -35.62414508))'); +SELECT 'valid wkt compound curve 2', ST_GeomFromEWKT('COMPOUNDCURVE((153.72942375 -27.21757040, 152.29285719 -29.23940482, 154.74034096 -30.51635287, 152.39926953 -32.16574411, 155.11278414 -34.08116619, 151.86720784 -35.62414508))'); +SELECT 'valid wkt compound curve 3', ST_GeomFromEWKT('COMPOUNDCURVE((151.60117699 -27.32398274, 151.22873381 -35.94338210, 150.74987829 -27.80283826))'); +SELECT 'valid wkt compound curve 4', ST_GeomFromEWKT('COMPOUNDCURVE((153.72942375 -27.21757040, 152.29285719 -29.23940482, 154.74034096 -30.51635287),CIRCULARSTRING(154.74034096 -30.51635287, 154.74034096 -30.51635287, 152.39926953 -32.16574411, 155.11278414 -34.08116619, 151.86720784 -35.62414508))'); +SELECT 'valid wkt compound curve 5', ST_GeomFromEWKT('COMPOUNDCURVE(CIRCULARSTRING(157.87950492 -27.59001358, 156.01728901 -28.28169378, 155.59163966 -26.52589021),(155.59163966 -26.52589021, 153.72942375 -27.21757040, 152.29285719 -29.23940482, 154.74034096 -30.51635287),CIRCULARSTRING(154.74034096 -30.51635287, 154.74034096 -30.51635287, 152.39926953 -32.16574411, 155.11278414 -34.08116619, 151.86720784 -35.62414508))'); +SELECT 'invalid wkt compound curve 1', ST_GeomFromEWKT('COMPOUNDCURVE((153.72942375 -27.21757040, 152.29285719 -29.23940482, 154.74034096 -30.51635287),(152.39926953 -32.16574411, 155.11278414 -34.08116619, 151.86720784 -35.62414508))'); +SELECT 'invalid wkt compound curve 2', ST_GeomFromEWKT('COMPOUNDCURVE((153.72942375 -27.21757040, 152.29285719 -29.23940482),CIRCULARSTRING(154.74034096 -30.51635287, 154.74034096 -30.51635287, 152.39926953 -32.16574411, 155.11278414 -34.08116619, 151.86720784 -35.62414508))'); +SELECT 'invalid wkt compound curve 3', ST_GeomFromEWKT('COMPOUNDCURVE(CIRCULARSTRING(157.87950492 -27.59001358, 156.01728901 -28.28169378, 155.59163966 -26.52589021, 153.72942375 -27.21757040),(153.72942375 -27.21757040, 152.29285719 -29.23940482),CIRCULARSTRING(154.74034096 -30.51635287, 154.74034096 -30.51635287, 152.39926953 -32.16574411, 155.11278414 -34.08116619, 151.86720784 -35.62414508))'); +SELECT 'valid wkb compound curve 1', ST_asEWKT(ST_GeomFromEWKB(decode('0109000000020000000102000000030000009FE5797057376340E09398B1B2373BC05AAE0A165F0963409F6760A2493D3DC0DB6286DFB057634082D8A1B32F843EC0010200000004000000DB6286DFB057634082D8A1B32F843EC075B4E4D0C60C634031FA5D1A371540C0D7197CED9B636340A3CB59A7630A41C050F4A72AC0FB6240974769FCE3CF41C0', 'hex'))); +SELECT 'valid wkb compound curve 2', ST_asEWKT(ST_GeomFromEWKB(decode('0109000000010000000102000000060000009FE5797057376340E09398B1B2373BC05AAE0A165F0963409F6760A2493D3DC0DB6286DFB057634082D8A1B32F843EC075B4E4D0C60C634031FA5D1A371540C0D7197CED9B636340A3CB59A7630A41C050F4A72AC0FB6240974769FCE3CF41C0', 'hex'))); +SELECT 'valid wkb compound curve 3', ST_asEWKT(ST_GeomFromEWKB(decode('0109000000010000000102000000030000000CE586D73CF36240BBC46888F0523BC0102E91C951E76240DF90A1BEC0F841C0F970C100FFD7624074ADE6CE86CD3BC0', 'hex'))); +SELECT 'valid wkb compound curve 4', ST_asEWKT(ST_GeomFromEWKB(decode('0109000000020000000102000000030000009FE5797057376340E09398B1B2373BC05AAE0A165F0963409F6760A2493D3DC0DB6286DFB057634082D8A1B32F843EC0010800000005000000DB6286DFB057634082D8A1B32F843EC0DB6286DFB057634082D8A1B32F843EC075B4E4D0C60C634031FA5D1A371540C0D7197CED9B636340A3CB59A7630A41C050F4A72AC0FB6240974769FCE3CF41C0', 'hex'))); +SELECT 'valid wkb compound curve 5', ST_asEWKT(ST_GeomFromEWKB(decode('010900000003000000010800000003000000468280E724BC6340BF4B46210B973BC0F890AEA18D8063402D9664151D483CC0EED64BB6EE726340903CA5BDA0863AC0010200000004000000EED64BB6EE726340903CA5BDA0863AC09FE5797057376340E09398B1B2373BC05AAE0A165F0963409F6760A2493D3DC0DB6286DFB057634082D8A1B32F843EC0010800000005000000DB6286DFB057634082D8A1B32F843EC0DB6286DFB057634082D8A1B32F843EC075B4E4D0C60C634031FA5D1A371540C0D7197CED9B636340A3CB59A7630A41C050F4A72AC0FB6240974769FCE3CF41C0', 'hex'))); +SELECT 'null response', ST_NumPoints(ST_GeomFromEWKT('COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0))')); +SELECT 'minpoints issues - pass', ST_GeomFromText('COMPOUNDCURVE((0 0,1 1))'); +SELECT 'minpoints issues - pass', ST_GeomFromText('COMPOUNDCURVE(CIRCULARSTRING(0 0,0 1,1 1))'); +SELECT 'minpoints issues - fail', ST_GeomFromText('COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1))'); +SELECT 'minpoints issues - fail', ST_GeomFromText('COMPOUNDCURVE(CIRCULARSTRING(0 0))'); +SELECT 'minpoints issues - fail', ST_GeomFromText('COMPOUNDCURVE((0 0),(0 0,1 1))'); diff --git a/regress/sql-mm-curvepoly.sql b/regress/sql-mm-curvepoly.sql index eab40ccc6..fa04dc1e9 100644 --- a/regress/sql-mm-curvepoly.sql +++ b/regress/sql-mm-curvepoly.sql @@ -1,342 +1,342 @@ --- Repeat tests with new function names. -SELECT 'ndims01', ST_ndims(ST_geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( - -2 0 0 0, - -1 -1 1 2, - 0 0 2 4, - 1 -1 3 6, - 2 0 4 8, - 0 2 2 4, - -2 0 0 0), - (-1 0 1 2, - 0 0.5 2 4, - 1 0 3 6, - 0 1 3 4, - -1 0 1 2))')); -SELECT 'geometrytype01', geometrytype(ST_geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( - -2 0 0 0, - -1 -1 1 2, - 0 0 2 4, - 1 -1 3 6, - 2 0 4 8, - 0 2 2 4, - -2 0 0 0), - (-1 0 1 2, - 0 0.5 2 4, - 1 0 3 6, - 0 1 3 4, - -1 0 1 2))')); -SELECT 'ndims02', ST_ndims(ST_geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( - -2 0 0, - -1 -1 1, - 0 0 2, - 1 -1 3, - 2 0 4, - 0 2 2, - -2 0 0), - (-1 0 1, - 0 0.5 2, - 1 0 3, - 0 1 3, - -1 0 1))')); -SELECT 'geometrytype02', geometrytype(ST_geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( - -2 0 0, - -1 -1 1, - 0 0 2, - 1 -1 3, - 2 0 4, - 0 2 2, - -2 0 0), - (-1 0 1, - 0 0.5 2, - 1 0 3, - 0 1 3, - -1 0 1))')); -SELECT 'ndims03', ST_ndims(ST_geomfromewkt('CURVEPOLYGONM(CIRCULARSTRING( - -2 0 0, - -1 -1 2, - 0 0 4, - 1 -1 6, - 2 0 8, - 0 2 4, - -2 0 0), - (-1 0 2, - 0 0.5 4, - 1 0 6, - 0 1 4, - -1 0 2))')); -SELECT 'geometrytype03', geometrytype(ST_geomfromewkt('CURVEPOLYGONM(CIRCULARSTRING( - -2 0 0, - -1 -1 2, - 0 0 4, - 1 -1 6, - 2 0 8, - 0 2 4, - -2 0 0), - (-1 0 2, - 0 0.5 4, - 1 0 6, - 0 1 4, - -1 0 2))')); -SELECT 'ndims04', ST_ndims(ST_geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( - -2 0, - -1 -1, - 0 0, - 1 -1, - 2 0, - 0 2, - -2 0), - (-1 0, - 0 0.5, - 1 0, - 0 1, - -1 0))')); -SELECT 'geometrytype04', geometrytype(ST_geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( - -2 0, - -1 -1, - 0 0, - 1 -1, - 2 0, - 0 2, - -2 0), - (-1 0, - 0 0.5, - 1 0, - 0 1, - -1 0))')); - -SELECT 'ndims05', ST_Ndims(ST_geomfromewkt('CURVEPOLYGON( - COMPOUNDCURVE( - (5 5 1 0,5 0 1 1,0 0 1 2,0 5 1 3), - CIRCULARSTRING(0 5 1 3,1.5 7.5 1 4,5 5 1 0)), - (1.5 5 2 0,2.5 6 3 1,3.5 5 2 2,1.5 5 2 0), - COMPOUNDCURVE( - CIRCULARSTRING(1.5 2 2 0,1 2.5 3 1,3.5 2 2 2), - (3.5 2 2 2,3.5 4 1 3,1.5 4 1 4,1.5 2 2 0)))')); - -CREATE TABLE public.curvepolygon (id INTEGER, description VARCHAR, -the_geom_2d GEOMETRY(CURVEPOLYGON), -the_geom_3dm GEOMETRY(CURVEPOLYGONM), -the_geom_3dz GEOMETRY(CURVEPOLYGONZ), -the_geom_4d GEOMETRY(CURVEPOLYGONZM)); - -INSERT INTO public.curvepolygon ( - id, - description - ) VALUES ( - 1, 'curvepolygon'); -UPDATE public.curvepolygon - SET the_geom_4d = ST_Geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( - -2 0 0 0, - -1 -1 1 2, - 0 0 2 4, - 1 -1 3 6, - 2 0 4 8, - 0 2 2 4, - -2 0 0 0), - (-1 0 1 2, - 0 0.5 2 4, - 1 0 3 6, - 0 1 3 4, - -1 0 1 2))'); -UPDATE public.curvepolygon - SET the_geom_3dz = ST_Geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( - -2 0 0, - -1 -1 1, - 0 0 2, - 1 -1 3, - 2 0 4, - 0 2 2, - -2 0 0), - (-1 0 1, - 0 0.5 2, - 1 0 3, - 0 1 3, - -1 0 1))'); -UPDATE public.curvepolygon - SET the_geom_3dm = ST_Geomfromewkt('CURVEPOLYGONM(CIRCULARSTRING( - -2 0 0, - -1 -1 2, - 0 0 4, - 1 -1 6, - 2 0 8, - 0 2 4, - -2 0 0), - (-1 0 2, - 0 0.5 4, - 1 0 6, - 0 1 4, - -1 0 2))'); -UPDATE public.curvepolygon - SET the_geom_2d = ST_Geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( - -2 0, - -1 -1, - 0 0, - 1 -1, - 2 0, - 0 2, - -2 0), - (-1 0, - 0 0.5, - 1 0, - 0 1, - -1 0))'); - --- These tests will fail on different architectures --- We need a way to handle multiple byte orderings ---SELECT 'asbinary01', encode(asbinary(the_geom_2d), 'hex') FROM public.curvepolygon; ---SELECT 'asbinary02', encode(asbinary(the_geom_3dm), 'hex') FROM public.curvepolygon; ---SELECT 'asbinary03', encode(asbinary(the_geom_3dz), 'hex') FROM public.curvepolygon; ---SELECT 'asbinary04', encode(asbinary(the_geom_4d), 'hex') FROM public.curvepolygon; --- ---SELECT 'asewkb01', encode(asewkb(the_geom_2d), 'hex') FROM public.curvepolygon; ---SELECT 'asewkb02', encode(asewkb(the_geom_3dm), 'hex') FROM public.curvepolygon; ---SELECT 'asewkb03', encode(asewkb(the_geom_3dz), 'hex') FROM public.curvepolygon; ---SELECT 'asewkb04', encode(asewkb(the_geom_4d), 'hex') FROM public.curvepolygon; - -SELECT 'ST_CurveToLine-201',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; -SELECT 'ST_CurveToLine-202',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; -SELECT 'ST_CurveToLine-203',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; -SELECT 'ST_CurveToLine-204',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; - -SELECT 'ST_CurveToLine-401',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; -SELECT 'ST_CurveToLine-402',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; -SELECT 'ST_CurveToLine-403',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; -SELECT 'ST_CurveToLine-404',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; - -SELECT 'ST_CurveToLine01',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; -SELECT 'ST_CurveToLine02',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; -SELECT 'ST_CurveToLine03',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; -SELECT 'ST_CurveToLine04',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; - --- Removed due to descrepencies between hardware ---SELECT 'box2d01', box2d(the_geom_2d) FROM public.curvepolygon; ---SELECT 'box2d02', box2d(the_geom_3dm) FROM public.curvepolygon; ---SELECT 'box2d03', box2d(the_geom_3dz) FROM public.curvepolygon; ---SELECT 'box2d04', box2d(the_geom_4d) FROM public.curvepolygon; - ---SELECT 'box3d01', box3d(the_geom_2d) FROM public.curvepolygon; ---SELECT 'box3d02', box3d(the_geom_3dm) FROM public.curvepolygon; ---SELECT 'box3d03', box3d(the_geom_3dz) FROM public.curvepolygon; ---SELECT 'box3d04', box3d(the_geom_4d) FROM public.curvepolygon; - --- TODO: ST_SnapToGrid is required to remove platform dependent precision --- issues. Until ST_SnapToGrid is updated to work against curves, these --- tests cannot be run. ---SELECT 'ST_LineToCurve01',ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_2d))) FROM public.curvepolygon; ---SELECT 'ST_LineToCurve02',ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dm))) FROM public.curvepolygon; ---SELECT 'ST_LineToCurve03',ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dz))) FROM public.curvepolygon; ---SELECT 'ST_LineToCurve04',ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_4d))) FROM public.curvepolygon; - --- Repeat tests with new function names. -SELECT 'astext01', ST_astext(the_geom_2d) FROM public.curvepolygon; -SELECT 'astext02', ST_astext(the_geom_3dm) FROM public.curvepolygon; -SELECT 'astext03', ST_astext(the_geom_3dz) FROM public.curvepolygon; -SELECT 'astext04', ST_astext(the_geom_4d) FROM public.curvepolygon; - -SELECT 'asewkt01', ST_asewkt(the_geom_2d) FROM public.curvepolygon; -SELECT 'asewkt02', ST_asewkt(the_geom_3dm) FROM public.curvepolygon; -SELECT 'asewkt03', ST_asewkt(the_geom_3dz) FROM public.curvepolygon; -SELECT 'asewkt04', ST_asewkt(the_geom_4d) FROM public.curvepolygon; - --- These tests will fail on different architectures --- We need a way to handle multiple byte orderings ---SELECT 'asbinary01', encode(ST_asbinary(the_geom_2d), 'hex') FROM public.curvepolygon; ---SELECT 'asbinary02', encode(ST_asbinary(the_geom_3dm), 'hex') FROM public.curvepolygon; ---SELECT 'asbinary03', encode(ST_asbinary(the_geom_3dz), 'hex') FROM public.curvepolygon; ---SELECT 'asbinary04', encode(ST_asbinary(the_geom_4d), 'hex') FROM public.curvepolygon; --- ---SELECT 'asewkb01', encode(ST_asewkb(the_geom_2d), 'hex') FROM public.curvepolygon; ---SELECT 'asewkb02', encode(ST_asewkb(the_geom_3dm), 'hex') FROM public.curvepolygon; ---SELECT 'asewkb03', encode(ST_asewkb(the_geom_3dz), 'hex') FROM public.curvepolygon; ---SELECT 'asewkb04', encode(ST_asewkb(the_geom_4d), 'hex') FROM public.curvepolygon; - --- Removed due to descrepencies between hardware ---SELECT 'box2d01', ST_box2d(the_geom_2d) FROM public.curvepolygon; ---SELECT 'box2d02', ST_box2d(the_geom_3dm) FROM public.curvepolygon; ---SELECT 'box2d03', ST_box2d(the_geom_3dz) FROM public.curvepolygon; ---SELECT 'box2d04', ST_box2d(the_geom_4d) FROM public.curvepolygon; - ---SELECT 'box3d01', ST_box3d(the_geom_2d) FROM public.curvepolygon; ---SELECT 'box3d02', ST_box3d(the_geom_3dm) FROM public.curvepolygon; ---SELECT 'box3d03', ST_box3d(the_geom_3dz) FROM public.curvepolygon; ---SELECT 'box3d04', ST_box3d(the_geom_4d) FROM public.curvepolygon; - -SELECT 'isValid01', ST_isValid(the_geom_2d) FROM public.curvepolygon; -SELECT 'isValid02', ST_isValid(the_geom_3dm) FROM public.curvepolygon; -SELECT 'isValid03', ST_isValid(the_geom_3dz) FROM public.curvepolygon; -SELECT 'isValid04', ST_isValid(the_geom_4d) FROM public.curvepolygon; - -SELECT 'dimension01', ST_dimension(the_geom_2d) FROM public.curvepolygon; -SELECT 'dimension02', ST_dimension(the_geom_3dm) FROM public.curvepolygon; -SELECT 'dimension03', ST_dimension(the_geom_3dz) FROM public.curvepolygon; -SELECT 'dimension04', ST_dimension(the_geom_4d) FROM public.curvepolygon; - -SELECT 'SRID01', ST_SRID(the_geom_2d) FROM public.curvepolygon; -SELECT 'SRID02', ST_SRID(the_geom_3dm) FROM public.curvepolygon; -SELECT 'SRID03', ST_SRID(the_geom_3dz) FROM public.curvepolygon; -SELECT 'SRID04', ST_SRID(the_geom_4d) FROM public.curvepolygon; - -SELECT 'envelope01', ST_asText(ST_snapToGrid(ST_envelope(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; -SELECT 'envelope02', ST_asText(ST_snapToGrid(ST_envelope(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; -SELECT 'envelope03', ST_asText(ST_snapToGrid(ST_envelope(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; -SELECT 'envelope04', ST_asText(ST_snapToGrid(ST_envelope(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; - -SELECT 'startPoint01', (ST_startPoint(the_geom_2d) is null) FROM public.curvepolygon; -SELECT 'startPoint02', (ST_startPoint(the_geom_3dm) is null) FROM public.curvepolygon; -SELECT 'startPoint03', (ST_startPoint(the_geom_3dz) is null) FROM public.curvepolygon; -SELECT 'startPoint04', (ST_startPoint(the_geom_4d) is null) FROM public.curvepolygon; - -SELECT 'endPoint01', (ST_endPoint(the_geom_2d) is null) FROM public.curvepolygon; -SELECT 'endPoint02', (ST_endPoint(the_geom_3dm) is null) FROM public.curvepolygon; -SELECT 'endPoint03', (ST_endPoint(the_geom_3dz) is null) FROM public.curvepolygon; -SELECT 'endPoint04', (ST_endPoint(the_geom_4d) is null) FROM public.curvepolygon; - -SELECT 'exteriorRing01', ST_asEWKT(ST_exteriorRing(the_geom_2d)) FROM public.curvepolygon; -SELECT 'exteriorRing02', ST_asEWKT(ST_exteriorRing(the_geom_3dm)) FROM public.curvepolygon; -SELECT 'exteriorRing03', ST_asEWKT(ST_exteriorRing(the_geom_3dz)) FROM public.curvepolygon; -SELECT 'exteriorRing04', ST_asEWKT(ST_exteriorRing(the_geom_4d)) FROM public.curvepolygon; - -SELECT 'numInteriorRings01', ST_numInteriorRings(the_geom_2d) FROM public.curvepolygon; -SELECT 'numInteriorRings02', ST_numInteriorRings(the_geom_3dm) FROM public.curvepolygon; -SELECT 'numInteriorRings03', ST_numInteriorRings(the_geom_3dz) FROM public.curvepolygon; -SELECT 'numInteriorRings04', ST_numInteriorRings(the_geom_4d) FROM public.curvepolygon; - -SELECT 'interiorRingN-101', ST_asEWKT(ST_interiorRingN(the_geom_2d, 1)) FROM public.curvepolygon; -SELECT 'interiorRingN-102', ST_asEWKT(ST_interiorRingN(the_geom_3dm, 1)) FROM public.curvepolygon; -SELECT 'interiorRingN-103', ST_asEWKT(ST_interiorRingN(the_geom_3dz, 1)) FROM public.curvepolygon; -SELECT 'interiorRingN-104', ST_asEWKT(ST_interiorRingN(the_geom_4d, 1)) FROM public.curvepolygon; - -SELECT 'interiorRingN-201', ST_asEWKT(ST_interiorRingN(the_geom_2d, 2)) FROM public.curvepolygon; -SELECT 'interiorRingN-202', ST_asEWKT(ST_interiorRingN(the_geom_3dm, 2)) FROM public.curvepolygon; -SELECT 'interiorRingN-203', ST_asEWKT(ST_interiorRingN(the_geom_3dz, 2)) FROM public.curvepolygon; -SELECT 'interiorRingN-204', ST_asEWKT(ST_interiorRingN(the_geom_4d, 2)) FROM public.curvepolygon; - -SELECT DropGeometryColumn('public', 'curvepolygon', 'the_geom_2d'); -SELECT DropGeometryColumn('public', 'curvepolygon', 'the_geom_3dm'); -SELECT DropGeometryColumn('public', 'curvepolygon', 'the_geom_3dz'); -SELECT DropGeometryColumn('public', 'curvepolygon', 'the_geom_4d'); -DROP TABLE public.curvepolygon; - -SELECT 'valid wkt curve polygon 1', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827))'); -SELECT 'valid wkt curve polygon 2', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827),(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664, 147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -31.26123924022086))'); -SELECT 'valid wkt curve polygon 3', ST_GeomFromEWKT('CURVEPOLYGON(CIRCULARSTRING(143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827))'); -SELECT 'valid wkt curve polygon 4', - ST_GeomFromEWKT('CURVEPOLYGON(CIRCULARSTRING(143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827),(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664, 147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -31.26123924022086))'); -SELECT 'valid wkt curve polygon 5', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827),COMPOUNDCURVE(CIRCULARSTRING(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664), (145.55230712890625 -33.49203872680664, 147.97080993652344 -32.03618621826172),CIRCULARSTRING(147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -31.26123924022086)))'); -SELECT 'invalid wkt curve polygon 4', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076))'); -SELECT 'invalid wkt curve polygon 5', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827),(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664, 147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417))'); -SELECT 'invalid wkt curve polygon 6', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431),(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664, 147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -31.26123924022086))'); -SELECT 'invalid wkt curve polygon 7', ST_GeomFromEWKT('CURVEPOLYGON(CIRCULARSTRING(143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 143.62025166838282 -30.037497356076827))'); -SELECT 'invalid wkt curve polygon 8', ST_GeomFromEWKT('CURVEPOLYGON(CIRCULARSTRING(143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431),(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664, 147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -31.26123924022086))'); -SELECT 'invalid wkt curve polygon 9', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827),COMPOUNDCURVE(CIRCULARSTRING(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664),CIRCULARSTRING(147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -31.26123924022086))'); -SELECT 'invalid wkt curve polygon a', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827),COMPOUNDCURVE(CIRCULARSTRING(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664),(145.55230712890625 -33.49203872680664, 147.97080993652344 -32.03618621826172),CIRCULARSTRING(147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -30.76123924022086))'); -SELECT 'invalid wkt curve polygon b', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827),COMPOUNDCURVE(CIRCULARSTRING(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664),(145.55230712890625 -33.49203872680664),CIRCULARSTRING(147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -31.26123924022086))'); -SELECT 'valid ewkb curve polygon 1', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000001000000010200000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec0', 'hex'))); -SELECT 'valid ewkb curve polygon 2', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000002000000010200000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec00102000000060000006844c4fe011b6240342e2993e0423fc0d45daf9d93066240c4a0c305d62240c000000080ac31624000000020fbbe40c0000000e0107f6240000000c0a10440c04e1c0c14624c6240bf3fb6405c793fc06844c4fe011b6240342e2993e0423fc0', 'hex'))); -SELECT 'valid ewkb curve polygon 3', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000001000000010800000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec0', 'hex'))); -SELECT 'valid ewkb curve polygon 4', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000002000000010800000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec00102000000060000006844c4fe011b6240342e2993e0423fc0d45daf9d93066240c4a0c305d62240c000000080ac31624000000020fbbe40c0000000e0107f6240000000c0a10440c04e1c0c14624c6240bf3fb6405c793fc06844c4fe011b6240342e2993e0423fc0', 'hex'))); -SELECT 'valid ewkb curve polygon 5', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000002000000010200000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec00109000000030000000108000000030000006844c4fe011b6240342e2993e0423fc0d45daf9d93066240c4a0c305d62240c000000080ac31624000000020fbbe40c001020000000200000000000080ac31624000000020fbbe40c0000000e0107f6240000000c0a10440c0010800000003000000000000e0107f6240000000c0a10440c04e1c0c14624c6240bf3fb6405c793fc06844c4fe011b6240342e2993e0423fc0', 'hex'))); -SELECT 'valid curve 6', ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )'); -SELECT 'valid curve 7', ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), (1.7 1, 1.4 0.4, 1.7 1) )'); -SELECT 'valid curve 8', ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )'); -SELECT 'null response', ST_NumPoints(ST_GeomFromEWKT('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )')); +-- Repeat tests with new function names. +SELECT 'ndims01', ST_ndims(ST_geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( + -2 0 0 0, + -1 -1 1 2, + 0 0 2 4, + 1 -1 3 6, + 2 0 4 8, + 0 2 2 4, + -2 0 0 0), + (-1 0 1 2, + 0 0.5 2 4, + 1 0 3 6, + 0 1 3 4, + -1 0 1 2))')); +SELECT 'geometrytype01', geometrytype(ST_geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( + -2 0 0 0, + -1 -1 1 2, + 0 0 2 4, + 1 -1 3 6, + 2 0 4 8, + 0 2 2 4, + -2 0 0 0), + (-1 0 1 2, + 0 0.5 2 4, + 1 0 3 6, + 0 1 3 4, + -1 0 1 2))')); +SELECT 'ndims02', ST_ndims(ST_geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( + -2 0 0, + -1 -1 1, + 0 0 2, + 1 -1 3, + 2 0 4, + 0 2 2, + -2 0 0), + (-1 0 1, + 0 0.5 2, + 1 0 3, + 0 1 3, + -1 0 1))')); +SELECT 'geometrytype02', geometrytype(ST_geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( + -2 0 0, + -1 -1 1, + 0 0 2, + 1 -1 3, + 2 0 4, + 0 2 2, + -2 0 0), + (-1 0 1, + 0 0.5 2, + 1 0 3, + 0 1 3, + -1 0 1))')); +SELECT 'ndims03', ST_ndims(ST_geomfromewkt('CURVEPOLYGONM(CIRCULARSTRING( + -2 0 0, + -1 -1 2, + 0 0 4, + 1 -1 6, + 2 0 8, + 0 2 4, + -2 0 0), + (-1 0 2, + 0 0.5 4, + 1 0 6, + 0 1 4, + -1 0 2))')); +SELECT 'geometrytype03', geometrytype(ST_geomfromewkt('CURVEPOLYGONM(CIRCULARSTRING( + -2 0 0, + -1 -1 2, + 0 0 4, + 1 -1 6, + 2 0 8, + 0 2 4, + -2 0 0), + (-1 0 2, + 0 0.5 4, + 1 0 6, + 0 1 4, + -1 0 2))')); +SELECT 'ndims04', ST_ndims(ST_geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( + -2 0, + -1 -1, + 0 0, + 1 -1, + 2 0, + 0 2, + -2 0), + (-1 0, + 0 0.5, + 1 0, + 0 1, + -1 0))')); +SELECT 'geometrytype04', geometrytype(ST_geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( + -2 0, + -1 -1, + 0 0, + 1 -1, + 2 0, + 0 2, + -2 0), + (-1 0, + 0 0.5, + 1 0, + 0 1, + -1 0))')); + +SELECT 'ndims05', ST_Ndims(ST_geomfromewkt('CURVEPOLYGON( + COMPOUNDCURVE( + (5 5 1 0,5 0 1 1,0 0 1 2,0 5 1 3), + CIRCULARSTRING(0 5 1 3,1.5 7.5 1 4,5 5 1 0)), + (1.5 5 2 0,2.5 6 3 1,3.5 5 2 2,1.5 5 2 0), + COMPOUNDCURVE( + CIRCULARSTRING(1.5 2 2 0,1 2.5 3 1,3.5 2 2 2), + (3.5 2 2 2,3.5 4 1 3,1.5 4 1 4,1.5 2 2 0)))')); + +CREATE TABLE public.curvepolygon (id INTEGER, description VARCHAR, +the_geom_2d GEOMETRY(CURVEPOLYGON), +the_geom_3dm GEOMETRY(CURVEPOLYGONM), +the_geom_3dz GEOMETRY(CURVEPOLYGONZ), +the_geom_4d GEOMETRY(CURVEPOLYGONZM)); + +INSERT INTO public.curvepolygon ( + id, + description + ) VALUES ( + 1, 'curvepolygon'); +UPDATE public.curvepolygon + SET the_geom_4d = ST_Geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( + -2 0 0 0, + -1 -1 1 2, + 0 0 2 4, + 1 -1 3 6, + 2 0 4 8, + 0 2 2 4, + -2 0 0 0), + (-1 0 1 2, + 0 0.5 2 4, + 1 0 3 6, + 0 1 3 4, + -1 0 1 2))'); +UPDATE public.curvepolygon + SET the_geom_3dz = ST_Geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( + -2 0 0, + -1 -1 1, + 0 0 2, + 1 -1 3, + 2 0 4, + 0 2 2, + -2 0 0), + (-1 0 1, + 0 0.5 2, + 1 0 3, + 0 1 3, + -1 0 1))'); +UPDATE public.curvepolygon + SET the_geom_3dm = ST_Geomfromewkt('CURVEPOLYGONM(CIRCULARSTRING( + -2 0 0, + -1 -1 2, + 0 0 4, + 1 -1 6, + 2 0 8, + 0 2 4, + -2 0 0), + (-1 0 2, + 0 0.5 4, + 1 0 6, + 0 1 4, + -1 0 2))'); +UPDATE public.curvepolygon + SET the_geom_2d = ST_Geomfromewkt('CURVEPOLYGON(CIRCULARSTRING( + -2 0, + -1 -1, + 0 0, + 1 -1, + 2 0, + 0 2, + -2 0), + (-1 0, + 0 0.5, + 1 0, + 0 1, + -1 0))'); + +-- These tests will fail on different architectures +-- We need a way to handle multiple byte orderings +--SELECT 'asbinary01', encode(asbinary(the_geom_2d), 'hex') FROM public.curvepolygon; +--SELECT 'asbinary02', encode(asbinary(the_geom_3dm), 'hex') FROM public.curvepolygon; +--SELECT 'asbinary03', encode(asbinary(the_geom_3dz), 'hex') FROM public.curvepolygon; +--SELECT 'asbinary04', encode(asbinary(the_geom_4d), 'hex') FROM public.curvepolygon; +-- +--SELECT 'asewkb01', encode(asewkb(the_geom_2d), 'hex') FROM public.curvepolygon; +--SELECT 'asewkb02', encode(asewkb(the_geom_3dm), 'hex') FROM public.curvepolygon; +--SELECT 'asewkb03', encode(asewkb(the_geom_3dz), 'hex') FROM public.curvepolygon; +--SELECT 'asewkb04', encode(asewkb(the_geom_4d), 'hex') FROM public.curvepolygon; + +SELECT 'ST_CurveToLine-201',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; +SELECT 'ST_CurveToLine-202',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; +SELECT 'ST_CurveToLine-203',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; +SELECT 'ST_CurveToLine-204',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; + +SELECT 'ST_CurveToLine-401',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; +SELECT 'ST_CurveToLine-402',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; +SELECT 'ST_CurveToLine-403',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; +SELECT 'ST_CurveToLine-404',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; + +SELECT 'ST_CurveToLine01',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; +SELECT 'ST_CurveToLine02',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; +SELECT 'ST_CurveToLine03',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; +SELECT 'ST_CurveToLine04',ST_asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; + +-- Removed due to descrepencies between hardware +--SELECT 'box2d01', box2d(the_geom_2d) FROM public.curvepolygon; +--SELECT 'box2d02', box2d(the_geom_3dm) FROM public.curvepolygon; +--SELECT 'box2d03', box2d(the_geom_3dz) FROM public.curvepolygon; +--SELECT 'box2d04', box2d(the_geom_4d) FROM public.curvepolygon; + +--SELECT 'box3d01', box3d(the_geom_2d) FROM public.curvepolygon; +--SELECT 'box3d02', box3d(the_geom_3dm) FROM public.curvepolygon; +--SELECT 'box3d03', box3d(the_geom_3dz) FROM public.curvepolygon; +--SELECT 'box3d04', box3d(the_geom_4d) FROM public.curvepolygon; + +-- TODO: ST_SnapToGrid is required to remove platform dependent precision +-- issues. Until ST_SnapToGrid is updated to work against curves, these +-- tests cannot be run. +--SELECT 'ST_LineToCurve01',ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_2d))) FROM public.curvepolygon; +--SELECT 'ST_LineToCurve02',ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dm))) FROM public.curvepolygon; +--SELECT 'ST_LineToCurve03',ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dz))) FROM public.curvepolygon; +--SELECT 'ST_LineToCurve04',ST_asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_4d))) FROM public.curvepolygon; + +-- Repeat tests with new function names. +SELECT 'astext01', ST_astext(the_geom_2d) FROM public.curvepolygon; +SELECT 'astext02', ST_astext(the_geom_3dm) FROM public.curvepolygon; +SELECT 'astext03', ST_astext(the_geom_3dz) FROM public.curvepolygon; +SELECT 'astext04', ST_astext(the_geom_4d) FROM public.curvepolygon; + +SELECT 'asewkt01', ST_asewkt(the_geom_2d) FROM public.curvepolygon; +SELECT 'asewkt02', ST_asewkt(the_geom_3dm) FROM public.curvepolygon; +SELECT 'asewkt03', ST_asewkt(the_geom_3dz) FROM public.curvepolygon; +SELECT 'asewkt04', ST_asewkt(the_geom_4d) FROM public.curvepolygon; + +-- These tests will fail on different architectures +-- We need a way to handle multiple byte orderings +--SELECT 'asbinary01', encode(ST_asbinary(the_geom_2d), 'hex') FROM public.curvepolygon; +--SELECT 'asbinary02', encode(ST_asbinary(the_geom_3dm), 'hex') FROM public.curvepolygon; +--SELECT 'asbinary03', encode(ST_asbinary(the_geom_3dz), 'hex') FROM public.curvepolygon; +--SELECT 'asbinary04', encode(ST_asbinary(the_geom_4d), 'hex') FROM public.curvepolygon; +-- +--SELECT 'asewkb01', encode(ST_asewkb(the_geom_2d), 'hex') FROM public.curvepolygon; +--SELECT 'asewkb02', encode(ST_asewkb(the_geom_3dm), 'hex') FROM public.curvepolygon; +--SELECT 'asewkb03', encode(ST_asewkb(the_geom_3dz), 'hex') FROM public.curvepolygon; +--SELECT 'asewkb04', encode(ST_asewkb(the_geom_4d), 'hex') FROM public.curvepolygon; + +-- Removed due to descrepencies between hardware +--SELECT 'box2d01', ST_box2d(the_geom_2d) FROM public.curvepolygon; +--SELECT 'box2d02', ST_box2d(the_geom_3dm) FROM public.curvepolygon; +--SELECT 'box2d03', ST_box2d(the_geom_3dz) FROM public.curvepolygon; +--SELECT 'box2d04', ST_box2d(the_geom_4d) FROM public.curvepolygon; + +--SELECT 'box3d01', ST_box3d(the_geom_2d) FROM public.curvepolygon; +--SELECT 'box3d02', ST_box3d(the_geom_3dm) FROM public.curvepolygon; +--SELECT 'box3d03', ST_box3d(the_geom_3dz) FROM public.curvepolygon; +--SELECT 'box3d04', ST_box3d(the_geom_4d) FROM public.curvepolygon; + +SELECT 'isValid01', ST_isValid(the_geom_2d) FROM public.curvepolygon; +SELECT 'isValid02', ST_isValid(the_geom_3dm) FROM public.curvepolygon; +SELECT 'isValid03', ST_isValid(the_geom_3dz) FROM public.curvepolygon; +SELECT 'isValid04', ST_isValid(the_geom_4d) FROM public.curvepolygon; + +SELECT 'dimension01', ST_dimension(the_geom_2d) FROM public.curvepolygon; +SELECT 'dimension02', ST_dimension(the_geom_3dm) FROM public.curvepolygon; +SELECT 'dimension03', ST_dimension(the_geom_3dz) FROM public.curvepolygon; +SELECT 'dimension04', ST_dimension(the_geom_4d) FROM public.curvepolygon; + +SELECT 'SRID01', ST_SRID(the_geom_2d) FROM public.curvepolygon; +SELECT 'SRID02', ST_SRID(the_geom_3dm) FROM public.curvepolygon; +SELECT 'SRID03', ST_SRID(the_geom_3dz) FROM public.curvepolygon; +SELECT 'SRID04', ST_SRID(the_geom_4d) FROM public.curvepolygon; + +SELECT 'envelope01', ST_asText(ST_snapToGrid(ST_envelope(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; +SELECT 'envelope02', ST_asText(ST_snapToGrid(ST_envelope(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; +SELECT 'envelope03', ST_asText(ST_snapToGrid(ST_envelope(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; +SELECT 'envelope04', ST_asText(ST_snapToGrid(ST_envelope(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.curvepolygon; + +SELECT 'startPoint01', (ST_startPoint(the_geom_2d) is null) FROM public.curvepolygon; +SELECT 'startPoint02', (ST_startPoint(the_geom_3dm) is null) FROM public.curvepolygon; +SELECT 'startPoint03', (ST_startPoint(the_geom_3dz) is null) FROM public.curvepolygon; +SELECT 'startPoint04', (ST_startPoint(the_geom_4d) is null) FROM public.curvepolygon; + +SELECT 'endPoint01', (ST_endPoint(the_geom_2d) is null) FROM public.curvepolygon; +SELECT 'endPoint02', (ST_endPoint(the_geom_3dm) is null) FROM public.curvepolygon; +SELECT 'endPoint03', (ST_endPoint(the_geom_3dz) is null) FROM public.curvepolygon; +SELECT 'endPoint04', (ST_endPoint(the_geom_4d) is null) FROM public.curvepolygon; + +SELECT 'exteriorRing01', ST_asEWKT(ST_exteriorRing(the_geom_2d)) FROM public.curvepolygon; +SELECT 'exteriorRing02', ST_asEWKT(ST_exteriorRing(the_geom_3dm)) FROM public.curvepolygon; +SELECT 'exteriorRing03', ST_asEWKT(ST_exteriorRing(the_geom_3dz)) FROM public.curvepolygon; +SELECT 'exteriorRing04', ST_asEWKT(ST_exteriorRing(the_geom_4d)) FROM public.curvepolygon; + +SELECT 'numInteriorRings01', ST_numInteriorRings(the_geom_2d) FROM public.curvepolygon; +SELECT 'numInteriorRings02', ST_numInteriorRings(the_geom_3dm) FROM public.curvepolygon; +SELECT 'numInteriorRings03', ST_numInteriorRings(the_geom_3dz) FROM public.curvepolygon; +SELECT 'numInteriorRings04', ST_numInteriorRings(the_geom_4d) FROM public.curvepolygon; + +SELECT 'interiorRingN-101', ST_asEWKT(ST_interiorRingN(the_geom_2d, 1)) FROM public.curvepolygon; +SELECT 'interiorRingN-102', ST_asEWKT(ST_interiorRingN(the_geom_3dm, 1)) FROM public.curvepolygon; +SELECT 'interiorRingN-103', ST_asEWKT(ST_interiorRingN(the_geom_3dz, 1)) FROM public.curvepolygon; +SELECT 'interiorRingN-104', ST_asEWKT(ST_interiorRingN(the_geom_4d, 1)) FROM public.curvepolygon; + +SELECT 'interiorRingN-201', ST_asEWKT(ST_interiorRingN(the_geom_2d, 2)) FROM public.curvepolygon; +SELECT 'interiorRingN-202', ST_asEWKT(ST_interiorRingN(the_geom_3dm, 2)) FROM public.curvepolygon; +SELECT 'interiorRingN-203', ST_asEWKT(ST_interiorRingN(the_geom_3dz, 2)) FROM public.curvepolygon; +SELECT 'interiorRingN-204', ST_asEWKT(ST_interiorRingN(the_geom_4d, 2)) FROM public.curvepolygon; + +SELECT DropGeometryColumn('public', 'curvepolygon', 'the_geom_2d'); +SELECT DropGeometryColumn('public', 'curvepolygon', 'the_geom_3dm'); +SELECT DropGeometryColumn('public', 'curvepolygon', 'the_geom_3dz'); +SELECT DropGeometryColumn('public', 'curvepolygon', 'the_geom_4d'); +DROP TABLE public.curvepolygon; + +SELECT 'valid wkt curve polygon 1', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827))'); +SELECT 'valid wkt curve polygon 2', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827),(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664, 147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -31.26123924022086))'); +SELECT 'valid wkt curve polygon 3', ST_GeomFromEWKT('CURVEPOLYGON(CIRCULARSTRING(143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827))'); +SELECT 'valid wkt curve polygon 4', + ST_GeomFromEWKT('CURVEPOLYGON(CIRCULARSTRING(143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827),(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664, 147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -31.26123924022086))'); +SELECT 'valid wkt curve polygon 5', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827),COMPOUNDCURVE(CIRCULARSTRING(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664), (145.55230712890625 -33.49203872680664, 147.97080993652344 -32.03618621826172),CIRCULARSTRING(147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -31.26123924022086)))'); +SELECT 'invalid wkt curve polygon 4', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076))'); +SELECT 'invalid wkt curve polygon 5', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827),(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664, 147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417))'); +SELECT 'invalid wkt curve polygon 6', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431),(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664, 147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -31.26123924022086))'); +SELECT 'invalid wkt curve polygon 7', ST_GeomFromEWKT('CURVEPOLYGON(CIRCULARSTRING(143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 143.62025166838282 -30.037497356076827))'); +SELECT 'invalid wkt curve polygon 8', ST_GeomFromEWKT('CURVEPOLYGON(CIRCULARSTRING(143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431),(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664, 147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -31.26123924022086))'); +SELECT 'invalid wkt curve polygon 9', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827),COMPOUNDCURVE(CIRCULARSTRING(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664),CIRCULARSTRING(147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -31.26123924022086))'); +SELECT 'invalid wkt curve polygon a', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827),COMPOUNDCURVE(CIRCULARSTRING(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664),(145.55230712890625 -33.49203872680664, 147.97080993652344 -32.03618621826172),CIRCULARSTRING(147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -30.76123924022086))'); +SELECT 'invalid wkt curve polygon b', ST_GeomFromEWKT('CURVEPOLYGON((143.62025166838282 -30.037497356076827, 142.92857147299705 -32.75101196874403, 145.96132309891922 -34.985671061528784, 149.57565307617188 -33.41153335571289, 149.41972407584802 -29.824672680573517, 146.1209416055467 -30.19711586270431, 143.62025166838282 -30.037497356076827),COMPOUNDCURVE(CIRCULARSTRING(144.84399355252685 -31.26123924022086, 144.20551952601693 -32.27215644886158, 145.55230712890625 -33.49203872680664),(145.55230712890625 -33.49203872680664),CIRCULARSTRING(147.97080993652344 -32.03618621826172, 146.38697244992585 -31.47406391572417, 144.84399355252685 -31.26123924022086))'); +SELECT 'valid ewkb curve polygon 1', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000001000000010200000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec0', 'hex'))); +SELECT 'valid ewkb curve polygon 2', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000002000000010200000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec00102000000060000006844c4fe011b6240342e2993e0423fc0d45daf9d93066240c4a0c305d62240c000000080ac31624000000020fbbe40c0000000e0107f6240000000c0a10440c04e1c0c14624c6240bf3fb6405c793fc06844c4fe011b6240342e2993e0423fc0', 'hex'))); +SELECT 'valid ewkb curve polygon 3', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000001000000010800000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec0', 'hex'))); +SELECT 'valid ewkb curve polygon 4', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000002000000010800000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec00102000000060000006844c4fe011b6240342e2993e0423fc0d45daf9d93066240c4a0c305d62240c000000080ac31624000000020fbbe40c0000000e0107f6240000000c0a10440c04e1c0c14624c6240bf3fb6405c793fc06844c4fe011b6240342e2993e0423fc0', 'hex'))); +SELECT 'valid ewkb curve polygon 5', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000002000000010200000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec00109000000030000000108000000030000006844c4fe011b6240342e2993e0423fc0d45daf9d93066240c4a0c305d62240c000000080ac31624000000020fbbe40c001020000000200000000000080ac31624000000020fbbe40c0000000e0107f6240000000c0a10440c0010800000003000000000000e0107f6240000000c0a10440c04e1c0c14624c6240bf3fb6405c793fc06844c4fe011b6240342e2993e0423fc0', 'hex'))); +SELECT 'valid curve 6', ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )'); +SELECT 'valid curve 7', ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), (1.7 1, 1.4 0.4, 1.7 1) )'); +SELECT 'valid curve 8', ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )'); +SELECT 'null response', ST_NumPoints(ST_GeomFromEWKT('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )')); diff --git a/regress/sql-mm-general.sql b/regress/sql-mm-general.sql index 8c8fc9a3a..73ec31c79 100644 --- a/regress/sql-mm-general.sql +++ b/regress/sql-mm-general.sql @@ -1,86 +1,86 @@ -SELECT ST_HasArc(ST_GeomFromText('POINT(0 0)')); -SELECT ST_HasArc(ST_GeomFromText('LINESTRING(0 0, 1 1, 1 0)')); -SELECT ST_HasArc(ST_GeomFromEWKT('CIRCULARSTRING( - 0 0 0 0, - 0.26794919243112270647255365849413 1 3 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2)')); -SELECT ST_HasArc(ST_GeomFromEWKT('COMPOUNDCURVE(CIRCULARSTRING( - 0 0 0 0, - 0.26794919243112270647255365849413 1 3 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2), - (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2, - 2 0 0 0, - 0 0 0 0))')); -SELECT ST_HasArc(ST_GeomFromEWKT('POLYGON( - (-10 -10, 10 -10, 10 10, -10 10, -10 -10), - (5 0, 0 5, -5 0, 0 -5, 5 0))')); -SELECT ST_HasArc(ST_GeomFromEWKT('CURVEPOLYGON(CIRCULARSTRING( - -2 0 0 0, - -1 -1 1 2, - 0 0 2 4, - 1 -1 3 6, - 2 0 4 8, - 0 2 2 4, - -2 0 0 0), - (-1 0 1 2, - 0 0.5 2 4, - 1 0 3 6, - 0 1 3 4, - -1 0 1 2))')); -SELECT ST_HasArc(ST_GeomFromEWKT('MULTIPOINT((0 0), (3 2))')); -SELECT ST_HasArc(ST_GeomFromEWKT('MULTILINESTRING( - (0 0, 3 2), - (4 8, 9 8), - (2 9, 4 8))')); -SELECT ST_HasArc(ST_GeomFromEWKT('MULTICURVE( - (0 0, 3 2), - (4 8, 9 8), - (2 9, 4 8))')); -SELECT ST_HasArc(ST_GeomFromEWKT('MULTICURVE(( - 5 5 1 3, - 3 5 2 2, - 3 3 3 1, - 0 3 1 1) - ,CIRCULARSTRING( - 0 0 0 0, - 0.26794919243112270647255365849413 1 3 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2))')); -SELECT ST_HasArc(ST_GeomFromEWKT('MULTIPOLYGON( - ((-10 -10, 10 -10, 10 10, -10 10, -10 -10), - (5 0, 0 5, -5 0, 0 -5, 5 0)), - ((9 2, 3 8, 9 4, 9 2)))')); -SELECT ST_HasArc(ST_GeomFromEWKT('MULTISURFACE( - ((-10 -10, 10 -10, 10 10, -10 10, -10 -10), - (5 0, 0 5, -5 0, 0 -5, 5 0)), - ((9 2, 3 8, 9 4, 9 2)))')); -SELECT ST_HasArc(ST_GeomFromEWKT('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( - -2 0 0 0, - -1 -1 1 2, - 0 0 2 4, - 1 -1 3 6, - 2 0 4 8, - 0 2 2 4, - -2 0 0 0), - (-1 0 1 2, - 0 0.5 2 4, - 1 0 3 6, - 0 1 3 4, - -1 0 1 2)), - ((7 8 7 8, - 10 10 5 5, - 6 14 3 1, - 4 11 4 6, - 7 8 7 8), - (9 9 7 8, - 8 12 7 8, - 7 10 7 8, - 9 9 7 8)))')); -SELECT ST_AsEWKT(ST_LineToCurve('LINESTRING( - -13151357.927248 3913656.64539871, - -13151419.0845266 3913664.12016378, - -13151441.323537 3913666.61175286, - -13151456.8908442 3913666.61175286, - -13151476.9059536 3913666.61175286, - -13151496.921063 3913666.61175287, - -13151521.3839744 3913666.61175287, - -13151591.4368571 3913665.36595828)')); +SELECT ST_HasArc(ST_GeomFromText('POINT(0 0)')); +SELECT ST_HasArc(ST_GeomFromText('LINESTRING(0 0, 1 1, 1 0)')); +SELECT ST_HasArc(ST_GeomFromEWKT('CIRCULARSTRING( + 0 0 0 0, + 0.26794919243112270647255365849413 1 3 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2)')); +SELECT ST_HasArc(ST_GeomFromEWKT('COMPOUNDCURVE(CIRCULARSTRING( + 0 0 0 0, + 0.26794919243112270647255365849413 1 3 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2), + (0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2, + 2 0 0 0, + 0 0 0 0))')); +SELECT ST_HasArc(ST_GeomFromEWKT('POLYGON( + (-10 -10, 10 -10, 10 10, -10 10, -10 -10), + (5 0, 0 5, -5 0, 0 -5, 5 0))')); +SELECT ST_HasArc(ST_GeomFromEWKT('CURVEPOLYGON(CIRCULARSTRING( + -2 0 0 0, + -1 -1 1 2, + 0 0 2 4, + 1 -1 3 6, + 2 0 4 8, + 0 2 2 4, + -2 0 0 0), + (-1 0 1 2, + 0 0.5 2 4, + 1 0 3 6, + 0 1 3 4, + -1 0 1 2))')); +SELECT ST_HasArc(ST_GeomFromEWKT('MULTIPOINT((0 0), (3 2))')); +SELECT ST_HasArc(ST_GeomFromEWKT('MULTILINESTRING( + (0 0, 3 2), + (4 8, 9 8), + (2 9, 4 8))')); +SELECT ST_HasArc(ST_GeomFromEWKT('MULTICURVE( + (0 0, 3 2), + (4 8, 9 8), + (2 9, 4 8))')); +SELECT ST_HasArc(ST_GeomFromEWKT('MULTICURVE(( + 5 5 1 3, + 3 5 2 2, + 3 3 3 1, + 0 3 1 1) + ,CIRCULARSTRING( + 0 0 0 0, + 0.26794919243112270647255365849413 1 3 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2))')); +SELECT ST_HasArc(ST_GeomFromEWKT('MULTIPOLYGON( + ((-10 -10, 10 -10, 10 10, -10 10, -10 -10), + (5 0, 0 5, -5 0, 0 -5, 5 0)), + ((9 2, 3 8, 9 4, 9 2)))')); +SELECT ST_HasArc(ST_GeomFromEWKT('MULTISURFACE( + ((-10 -10, 10 -10, 10 10, -10 10, -10 -10), + (5 0, 0 5, -5 0, 0 -5, 5 0)), + ((9 2, 3 8, 9 4, 9 2)))')); +SELECT ST_HasArc(ST_GeomFromEWKT('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( + -2 0 0 0, + -1 -1 1 2, + 0 0 2 4, + 1 -1 3 6, + 2 0 4 8, + 0 2 2 4, + -2 0 0 0), + (-1 0 1 2, + 0 0.5 2 4, + 1 0 3 6, + 0 1 3 4, + -1 0 1 2)), + ((7 8 7 8, + 10 10 5 5, + 6 14 3 1, + 4 11 4 6, + 7 8 7 8), + (9 9 7 8, + 8 12 7 8, + 7 10 7 8, + 9 9 7 8)))')); +SELECT ST_AsEWKT(ST_LineToCurve('LINESTRING( + -13151357.927248 3913656.64539871, + -13151419.0845266 3913664.12016378, + -13151441.323537 3913666.61175286, + -13151456.8908442 3913666.61175286, + -13151476.9059536 3913666.61175286, + -13151496.921063 3913666.61175287, + -13151521.3839744 3913666.61175287, + -13151591.4368571 3913665.36595828)')); diff --git a/regress/sql-mm-multicurve.sql b/regress/sql-mm-multicurve.sql index 3671f5268..044631c4d 100644 --- a/regress/sql-mm-multicurve.sql +++ b/regress/sql-mm-multicurve.sql @@ -1,236 +1,236 @@ --- Repeat the tests with the new function names. -SELECT 'ndims01', ST_ndims(ST_geomfromewkt('MULTICURVE(( - 5 5 1 3, - 3 5 2 2, - 3 3 3 1, - 0 3 1 1) - ,CIRCULARSTRING( - 0 0 0 0, - 0.26794919243112270647255365849413 1 3 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2))')); -SELECT 'geometrytype01', geometrytype(ST_geomfromewkt('MULTICURVE(( - 5 5 1 3, - 3 5 2 2, - 3 3 3 1, - 0 3 1 1) - ,CIRCULARSTRING( - 0 0 0 0, - 0.26794919243112270647255365849413 1 3 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2))')); -SELECT 'ndims02', ST_ndims(ST_geomfromewkt('MULTICURVE(( - 5 5 1, - 3 5 2, - 3 3 3, - 0 3 1) - ,CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 3, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1))')); -SELECT 'geometrytype02', geometrytype(ST_geomfromewkt('MULTICURVE(( - 5 5 1, - 3 5 2, - 3 3 3, - 0 3 1) - ,CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 3, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1))')); -SELECT 'ndims03', ST_ndims(ST_geomfromewkt('MULTICURVEM(( - 5 5 3, - 3 5 2, - 3 3 1, - 0 3 1) - ,CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2))')); -SELECT 'geometrytype03', geometrytype(ST_geomfromewkt('MULTICURVEM(( - 5 5 3, - 3 5 2, - 3 3 1, - 0 3 1) - ,CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2))')); -SELECT 'ndims04', ST_ndims(ST_geomfromewkt('MULTICURVE(( - 5 5, - 3 5, - 3 3, - 0 3) - ,CIRCULARSTRING( - 0 0, - 0.26794919243112270647255365849413 1, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097))')); -SELECT 'geometrytype04', geometrytype(ST_geomfromewkt('MULTICURVE(( - 5 5, - 3 5, - 3 3, - 0 3) - ,CIRCULARSTRING( - 0 0, - 0.26794919243112270647255365849413 1, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097))')); - -CREATE TABLE public.multicurve (id INTEGER, description VARCHAR, -the_geom_2d GEOMETRY(MULTICURVE), -the_geom_3dm GEOMETRY(MULTICURVEM), -the_geom_3dz GEOMETRY(MULTICURVEZ), -the_geom_4d GEOMETRY(MULTICURVEZM)); - -INSERT INTO public.multicurve ( - id, - description - ) VALUES ( - 1, 'multicurve'); -UPDATE public.multicurve - SET the_geom_4d = ST_Geomfromewkt('MULTICURVE(( - 5 5 1 3, - 3 5 2 2, - 3 3 3 1, - 0 3 1 1) - ,CIRCULARSTRING( - 0 0 0 0, - 0.26794919243112270647255365849413 1 3 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2))'); -UPDATE public.multicurve - SET the_geom_3dz = ST_Geomfromewkt('MULTICURVE(( - 5 5 1, - 3 5 2, - 3 3 3, - 0 3 1) - ,CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 3, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1))'); -UPDATE public.multicurve - SET the_geom_3dm = ST_Geomfromewkt('MULTICURVEM(( - 5 5 3, - 3 5 2, - 3 3 1, - 0 3 1) - ,CIRCULARSTRING( - 0 0 0, - 0.26794919243112270647255365849413 1 -2, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2))'); -UPDATE public.multicurve - SET the_geom_2d = ST_Geomfromewkt('MULTICURVE(( - 5 5, - 3 5, - 3 3, - 0 3) - ,CIRCULARSTRING( - 0 0, - 0.26794919243112270647255365849413 1, - 0.5857864376269049511983112757903 1.4142135623730950488016887242097))'); - --- These tests will fail on different architectures --- We need a way to handle multiple byte orderings ---SELECT 'asbinary01', encode(asbinary(the_geom_2d), 'hex') FROM public.multicurve; ---SELECT 'asbinary02', encode(asbinary(the_geom_3dm), 'hex') FROM public.multicurve; ---SELECT 'asbinary03', encode(asbinary(the_geom_3dz), 'hex') FROM public.multicurve; ---SELECT 'asbinary04', encode(asbinary(the_geom_4d), 'hex') FROM public.multicurve; --- ---SELECT 'asewkb01', encode(asewkb(the_geom_2d), 'hex') FROM public.multicurve; ---SELECT 'asewkb02', encode(asewkb(the_geom_3dm), 'hex') FROM public.multicurve; ---SELECT 'asewkb03', encode(asewkb(the_geom_3dz), 'hex') FROM public.multicurve; ---SELECT 'asewkb04', encode(asewkb(the_geom_4d), 'hex') FROM public.multicurve; - -SELECT 'ST_CurveToLine-201', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; -SELECT 'ST_CurveToLine-202', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; -SELECT 'ST_CurveToLine-203', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; -SELECT 'ST_CurveToLine-204', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; - -SELECT 'ST_CurveToLine-401', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; -SELECT 'ST_CurveToLine-402', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; -SELECT 'ST_CurveToLine-403', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; -SELECT 'ST_CurveToLine-404', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; - -SELECT 'ST_CurveToLine01', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; -SELECT 'ST_CurveToLine02', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; -SELECT 'ST_CurveToLine03', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; -SELECT 'ST_CurveToLine04', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; - --- Removed due to descrepencies between hardware ---SELECT 'box2d01', box2d(the_geom_2d) FROM public.multicurve; ---SELECT 'box2d02', box2d(the_geom_3dm) FROM public.multicurve; ---SELECT 'box2d03', box2d(the_geom_3dz) FROM public.multicurve; ---SELECT 'box2d04', box2d(the_geom_4d) FROM public.multicurve; - ---SELECT 'box3d01', box3d(the_geom_2d) FROM public.multicurve; ---SELECT 'box3d02', box3d(the_geom_3dm) FROM public.multicurve; ---SELECT 'box3d03', box3d(the_geom_3dz) FROM public.multicurve; ---SELECT 'box3d04', box3d(the_geom_4d) FROM public.multicurve; --- TODO: ST_SnapToGrid is required to remove platform dependent precision --- issues. Until ST_SnapToGrid is updated to work against curves, these --- tests cannot be run. ---SELECT 'ST_LineToCurve01', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_2d))) FROM public.multicurve; ---SELECT 'ST_LineToCurve02', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dm))) FROM public.multicurve; ---SELECT 'ST_LineToCurve03', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dz))) FROM public.multicurve; ---SELECT 'ST_LineToCurve04', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_4d))) FROM public.multicurve; - --- Repeat all tests with the new function names. -SELECT 'astext01', ST_astext(the_geom_2d) FROM public.multicurve; -SELECT 'astext02', ST_astext(the_geom_3dm) FROM public.multicurve; -SELECT 'astext03', ST_astext(the_geom_3dz) FROM public.multicurve; -SELECT 'astext04', ST_astext(the_geom_4d) FROM public.multicurve; - -SELECT 'asewkt01', ST_asewkt(the_geom_2d) FROM public.multicurve; -SELECT 'asewkt02', ST_asewkt(the_geom_3dm) FROM public.multicurve; -SELECT 'asewkt03', ST_asewkt(the_geom_3dz) FROM public.multicurve; -SELECT 'asewkt04', ST_asewkt(the_geom_4d) FROM public.multicurve; - --- These tests will fail on different architectures --- We need a way to handle multiple byte orderings ---SELECT 'asbinary01', encode(ST_asbinary(the_geom_2d), 'hex') FROM public.multicurve; ---SELECT 'asbinary02', encode(ST_asbinary(the_geom_3dm), 'hex') FROM public.multicurve; ---SELECT 'asbinary03', encode(ST_asbinary(the_geom_3dz), 'hex') FROM public.multicurve; ---SELECT 'asbinary04', encode(ST_asbinary(the_geom_4d), 'hex') FROM public.multicurve; --- ---SELECT 'asewkb01', encode(ST_asewkb(the_geom_2d), 'hex') FROM public.multicurve; ---SELECT 'asewkb02', encode(ST_asewkb(the_geom_3dm), 'hex') FROM public.multicurve; ---SELECT 'asewkb03', encode(ST_asewkb(the_geom_3dz), 'hex') FROM public.multicurve; ---SELECT 'asewkb04', encode(ST_asewkb(the_geom_4d), 'hex') FROM public.multicurve; - --- Removed due to descrepencies between hardware ---SELECT 'box2d01', ST_box2d(the_geom_2d) FROM public.multicurve; ---SELECT 'box2d02', ST_box2d(the_geom_3dm) FROM public.multicurve; ---SELECT 'box2d03', ST_box2d(the_geom_3dz) FROM public.multicurve; ---SELECT 'box2d04', ST_box2d(the_geom_4d) FROM public.multicurve; - ---SELECT 'box3d01', ST_box3d(the_geom_2d) FROM public.multicurve; ---SELECT 'box3d02', ST_box3d(the_geom_3dm) FROM public.multicurve; ---SELECT 'box3d03', ST_box3d(the_geom_3dz) FROM public.multicurve; ---SELECT 'box3d04', ST_box3d(the_geom_4d) FROM public.multicurve; - -SELECT 'isValid01', ST_isValid(the_geom_2d) FROM public.multicurve; -SELECT 'isValid02', ST_isValid(the_geom_3dm) FROM public.multicurve; -SELECT 'isValid03', ST_isValid(the_geom_3dz) FROM public.multicurve; -SELECT 'isValid04', ST_isValid(the_geom_4d) FROM public.multicurve; - -SELECT 'dimension01', ST_dimension(the_geom_2d) FROM public.multicurve; -SELECT 'dimension02', ST_dimension(the_geom_3dm) FROM public.multicurve; -SELECT 'dimension03', ST_dimension(the_geom_3dz) FROM public.multicurve; -SELECT 'dimension04', ST_dimension(the_geom_4d) FROM public.multicurve; - -SELECT 'numGeometries01', ST_numGeometries(the_geom_2d) FROM public.multicurve; -SELECT 'numGeometries02', ST_numGeometries(the_geom_3dm) FROM public.multicurve; -SELECT 'numGeometries03', ST_numGeometries(the_geom_3dz) FROM public.multicurve; -SELECT 'numGeometries04', ST_numGeometries(the_geom_4d) FROM public.multicurve; - -SELECT 'geometryN-201', ST_asEWKT(ST_geometryN(the_geom_2d, 2)) FROM public.multicurve; -SELECT 'geometryN-202', ST_asEWKT(ST_geometryN(the_geom_3dm, 2)) FROM public.multicurve; -SELECT 'geometryN-203', ST_asEWKT(ST_geometryN(the_geom_3dz, 2)) FROM public.multicurve; -SELECT 'geometryN-204', ST_asEWKT(ST_geometryN(the_geom_4d, 2)) FROM public.multicurve; - -SELECT 'geometryN-301', (ST_asEWKT(ST_geometryN(the_geom_2d, 3)) is null) FROM public.multicurve; -SELECT 'geometryN-302', (ST_asEWKT(ST_geometryN(the_geom_3dm, 3)) is null) FROM public.multicurve; -SELECT 'geometryN-303', (ST_asEWKT(ST_geometryN(the_geom_3dz, 3)) is null) FROM public.multicurve; -SELECT 'geometryN-304', (ST_asEWKT(ST_geometryN(the_geom_4d, 3)) is null) FROM public.multicurve; - -SELECT DropGeometryColumn('public', 'multicurve', 'the_geom_2d'); -SELECT DropGeometryColumn('public', 'multicurve', 'the_geom_3dm'); -SELECT DropGeometryColumn('public', 'multicurve', 'the_geom_3dz'); -SELECT DropGeometryColumn('public', 'multicurve', 'the_geom_4d'); -DROP TABLE public.multicurve; - +-- Repeat the tests with the new function names. +SELECT 'ndims01', ST_ndims(ST_geomfromewkt('MULTICURVE(( + 5 5 1 3, + 3 5 2 2, + 3 3 3 1, + 0 3 1 1) + ,CIRCULARSTRING( + 0 0 0 0, + 0.26794919243112270647255365849413 1 3 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2))')); +SELECT 'geometrytype01', geometrytype(ST_geomfromewkt('MULTICURVE(( + 5 5 1 3, + 3 5 2 2, + 3 3 3 1, + 0 3 1 1) + ,CIRCULARSTRING( + 0 0 0 0, + 0.26794919243112270647255365849413 1 3 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2))')); +SELECT 'ndims02', ST_ndims(ST_geomfromewkt('MULTICURVE(( + 5 5 1, + 3 5 2, + 3 3 3, + 0 3 1) + ,CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 3, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1))')); +SELECT 'geometrytype02', geometrytype(ST_geomfromewkt('MULTICURVE(( + 5 5 1, + 3 5 2, + 3 3 3, + 0 3 1) + ,CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 3, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1))')); +SELECT 'ndims03', ST_ndims(ST_geomfromewkt('MULTICURVEM(( + 5 5 3, + 3 5 2, + 3 3 1, + 0 3 1) + ,CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2))')); +SELECT 'geometrytype03', geometrytype(ST_geomfromewkt('MULTICURVEM(( + 5 5 3, + 3 5 2, + 3 3 1, + 0 3 1) + ,CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2))')); +SELECT 'ndims04', ST_ndims(ST_geomfromewkt('MULTICURVE(( + 5 5, + 3 5, + 3 3, + 0 3) + ,CIRCULARSTRING( + 0 0, + 0.26794919243112270647255365849413 1, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097))')); +SELECT 'geometrytype04', geometrytype(ST_geomfromewkt('MULTICURVE(( + 5 5, + 3 5, + 3 3, + 0 3) + ,CIRCULARSTRING( + 0 0, + 0.26794919243112270647255365849413 1, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097))')); + +CREATE TABLE public.multicurve (id INTEGER, description VARCHAR, +the_geom_2d GEOMETRY(MULTICURVE), +the_geom_3dm GEOMETRY(MULTICURVEM), +the_geom_3dz GEOMETRY(MULTICURVEZ), +the_geom_4d GEOMETRY(MULTICURVEZM)); + +INSERT INTO public.multicurve ( + id, + description + ) VALUES ( + 1, 'multicurve'); +UPDATE public.multicurve + SET the_geom_4d = ST_Geomfromewkt('MULTICURVE(( + 5 5 1 3, + 3 5 2 2, + 3 3 3 1, + 0 3 1 1) + ,CIRCULARSTRING( + 0 0 0 0, + 0.26794919243112270647255365849413 1 3 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1 2))'); +UPDATE public.multicurve + SET the_geom_3dz = ST_Geomfromewkt('MULTICURVE(( + 5 5 1, + 3 5 2, + 3 3 3, + 0 3 1) + ,CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 3, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1))'); +UPDATE public.multicurve + SET the_geom_3dm = ST_Geomfromewkt('MULTICURVEM(( + 5 5 3, + 3 5 2, + 3 3 1, + 0 3 1) + ,CIRCULARSTRING( + 0 0 0, + 0.26794919243112270647255365849413 1 -2, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097 2))'); +UPDATE public.multicurve + SET the_geom_2d = ST_Geomfromewkt('MULTICURVE(( + 5 5, + 3 5, + 3 3, + 0 3) + ,CIRCULARSTRING( + 0 0, + 0.26794919243112270647255365849413 1, + 0.5857864376269049511983112757903 1.4142135623730950488016887242097))'); + +-- These tests will fail on different architectures +-- We need a way to handle multiple byte orderings +--SELECT 'asbinary01', encode(asbinary(the_geom_2d), 'hex') FROM public.multicurve; +--SELECT 'asbinary02', encode(asbinary(the_geom_3dm), 'hex') FROM public.multicurve; +--SELECT 'asbinary03', encode(asbinary(the_geom_3dz), 'hex') FROM public.multicurve; +--SELECT 'asbinary04', encode(asbinary(the_geom_4d), 'hex') FROM public.multicurve; +-- +--SELECT 'asewkb01', encode(asewkb(the_geom_2d), 'hex') FROM public.multicurve; +--SELECT 'asewkb02', encode(asewkb(the_geom_3dm), 'hex') FROM public.multicurve; +--SELECT 'asewkb03', encode(asewkb(the_geom_3dz), 'hex') FROM public.multicurve; +--SELECT 'asewkb04', encode(asewkb(the_geom_4d), 'hex') FROM public.multicurve; + +SELECT 'ST_CurveToLine-201', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; +SELECT 'ST_CurveToLine-202', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; +SELECT 'ST_CurveToLine-203', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; +SELECT 'ST_CurveToLine-204', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; + +SELECT 'ST_CurveToLine-401', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; +SELECT 'ST_CurveToLine-402', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; +SELECT 'ST_CurveToLine-403', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; +SELECT 'ST_CurveToLine-404', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; + +SELECT 'ST_CurveToLine01', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; +SELECT 'ST_CurveToLine02', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; +SELECT 'ST_CurveToLine03', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; +SELECT 'ST_CurveToLine04', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multicurve; + +-- Removed due to descrepencies between hardware +--SELECT 'box2d01', box2d(the_geom_2d) FROM public.multicurve; +--SELECT 'box2d02', box2d(the_geom_3dm) FROM public.multicurve; +--SELECT 'box2d03', box2d(the_geom_3dz) FROM public.multicurve; +--SELECT 'box2d04', box2d(the_geom_4d) FROM public.multicurve; + +--SELECT 'box3d01', box3d(the_geom_2d) FROM public.multicurve; +--SELECT 'box3d02', box3d(the_geom_3dm) FROM public.multicurve; +--SELECT 'box3d03', box3d(the_geom_3dz) FROM public.multicurve; +--SELECT 'box3d04', box3d(the_geom_4d) FROM public.multicurve; +-- TODO: ST_SnapToGrid is required to remove platform dependent precision +-- issues. Until ST_SnapToGrid is updated to work against curves, these +-- tests cannot be run. +--SELECT 'ST_LineToCurve01', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_2d))) FROM public.multicurve; +--SELECT 'ST_LineToCurve02', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dm))) FROM public.multicurve; +--SELECT 'ST_LineToCurve03', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dz))) FROM public.multicurve; +--SELECT 'ST_LineToCurve04', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_4d))) FROM public.multicurve; + +-- Repeat all tests with the new function names. +SELECT 'astext01', ST_astext(the_geom_2d) FROM public.multicurve; +SELECT 'astext02', ST_astext(the_geom_3dm) FROM public.multicurve; +SELECT 'astext03', ST_astext(the_geom_3dz) FROM public.multicurve; +SELECT 'astext04', ST_astext(the_geom_4d) FROM public.multicurve; + +SELECT 'asewkt01', ST_asewkt(the_geom_2d) FROM public.multicurve; +SELECT 'asewkt02', ST_asewkt(the_geom_3dm) FROM public.multicurve; +SELECT 'asewkt03', ST_asewkt(the_geom_3dz) FROM public.multicurve; +SELECT 'asewkt04', ST_asewkt(the_geom_4d) FROM public.multicurve; + +-- These tests will fail on different architectures +-- We need a way to handle multiple byte orderings +--SELECT 'asbinary01', encode(ST_asbinary(the_geom_2d), 'hex') FROM public.multicurve; +--SELECT 'asbinary02', encode(ST_asbinary(the_geom_3dm), 'hex') FROM public.multicurve; +--SELECT 'asbinary03', encode(ST_asbinary(the_geom_3dz), 'hex') FROM public.multicurve; +--SELECT 'asbinary04', encode(ST_asbinary(the_geom_4d), 'hex') FROM public.multicurve; +-- +--SELECT 'asewkb01', encode(ST_asewkb(the_geom_2d), 'hex') FROM public.multicurve; +--SELECT 'asewkb02', encode(ST_asewkb(the_geom_3dm), 'hex') FROM public.multicurve; +--SELECT 'asewkb03', encode(ST_asewkb(the_geom_3dz), 'hex') FROM public.multicurve; +--SELECT 'asewkb04', encode(ST_asewkb(the_geom_4d), 'hex') FROM public.multicurve; + +-- Removed due to descrepencies between hardware +--SELECT 'box2d01', ST_box2d(the_geom_2d) FROM public.multicurve; +--SELECT 'box2d02', ST_box2d(the_geom_3dm) FROM public.multicurve; +--SELECT 'box2d03', ST_box2d(the_geom_3dz) FROM public.multicurve; +--SELECT 'box2d04', ST_box2d(the_geom_4d) FROM public.multicurve; + +--SELECT 'box3d01', ST_box3d(the_geom_2d) FROM public.multicurve; +--SELECT 'box3d02', ST_box3d(the_geom_3dm) FROM public.multicurve; +--SELECT 'box3d03', ST_box3d(the_geom_3dz) FROM public.multicurve; +--SELECT 'box3d04', ST_box3d(the_geom_4d) FROM public.multicurve; + +SELECT 'isValid01', ST_isValid(the_geom_2d) FROM public.multicurve; +SELECT 'isValid02', ST_isValid(the_geom_3dm) FROM public.multicurve; +SELECT 'isValid03', ST_isValid(the_geom_3dz) FROM public.multicurve; +SELECT 'isValid04', ST_isValid(the_geom_4d) FROM public.multicurve; + +SELECT 'dimension01', ST_dimension(the_geom_2d) FROM public.multicurve; +SELECT 'dimension02', ST_dimension(the_geom_3dm) FROM public.multicurve; +SELECT 'dimension03', ST_dimension(the_geom_3dz) FROM public.multicurve; +SELECT 'dimension04', ST_dimension(the_geom_4d) FROM public.multicurve; + +SELECT 'numGeometries01', ST_numGeometries(the_geom_2d) FROM public.multicurve; +SELECT 'numGeometries02', ST_numGeometries(the_geom_3dm) FROM public.multicurve; +SELECT 'numGeometries03', ST_numGeometries(the_geom_3dz) FROM public.multicurve; +SELECT 'numGeometries04', ST_numGeometries(the_geom_4d) FROM public.multicurve; + +SELECT 'geometryN-201', ST_asEWKT(ST_geometryN(the_geom_2d, 2)) FROM public.multicurve; +SELECT 'geometryN-202', ST_asEWKT(ST_geometryN(the_geom_3dm, 2)) FROM public.multicurve; +SELECT 'geometryN-203', ST_asEWKT(ST_geometryN(the_geom_3dz, 2)) FROM public.multicurve; +SELECT 'geometryN-204', ST_asEWKT(ST_geometryN(the_geom_4d, 2)) FROM public.multicurve; + +SELECT 'geometryN-301', (ST_asEWKT(ST_geometryN(the_geom_2d, 3)) is null) FROM public.multicurve; +SELECT 'geometryN-302', (ST_asEWKT(ST_geometryN(the_geom_3dm, 3)) is null) FROM public.multicurve; +SELECT 'geometryN-303', (ST_asEWKT(ST_geometryN(the_geom_3dz, 3)) is null) FROM public.multicurve; +SELECT 'geometryN-304', (ST_asEWKT(ST_geometryN(the_geom_4d, 3)) is null) FROM public.multicurve; + +SELECT DropGeometryColumn('public', 'multicurve', 'the_geom_2d'); +SELECT DropGeometryColumn('public', 'multicurve', 'the_geom_3dm'); +SELECT DropGeometryColumn('public', 'multicurve', 'the_geom_3dz'); +SELECT DropGeometryColumn('public', 'multicurve', 'the_geom_4d'); +DROP TABLE public.multicurve; + diff --git a/regress/sql-mm-multisurface.sql b/regress/sql-mm-multisurface.sql index cfa9ba006..3e8ac29e0 100644 --- a/regress/sql-mm-multisurface.sql +++ b/regress/sql-mm-multisurface.sql @@ -1,351 +1,351 @@ --- Repeat these tests with the new function names. -SELECT 'ndims01', ST_ndims(ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( - -2 0 0 0, - -1 -1 1 2, - 0 0 2 4, - 1 -1 3 6, - 2 0 4 8, - 0 2 2 4, - -2 0 0 0), - (-1 0 1 2, - 0 0.5 2 4, - 1 0 3 6, - 0 1 3 4, - -1 0 1 2)), - ((7 8 7 8, - 10 10 5 5, - 6 14 3 1, - 4 11 4 6, - 7 8 7 8)))')); -SELECT 'geometrytype01', geometrytype(ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( - -2 0 0 0, - -1 -1 1 2, - 0 0 2 4, - 1 -1 3 6, - 2 0 4 8, - 0 2 2 4, - -2 0 0 0), - (-1 0 1 2, - 0 0.5 2 4, - 1 0 3 6, - 0 1 3 4, - -1 0 1 2)), - ((7 8 7 8, - 10 10 5 5, - 6 14 3 1, - 4 11 4 6, - 7 8 7 8), - (9 9 7 8, - 8 12 7 8, - 7 10 7 8, - 9 9 7 8)))')); -SELECT 'ndims02', ST_ndims(ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( - -2 0 0, - -1 -1 1, - 0 0 2, - 1 -1 3, - 2 0 4, - 0 2 2, - -2 0 0), - (-1 0 1, - 0 0.5 2, - 1 0 3, - 0 1 3, - -1 0 1)), - ((7 8 7, - 10 10 5, - 6 14 3, - 4 11 4, - 7 8 7), - (9 9 7, - 8 12 7, - 7 10 7, - 9 9 7)))')); -SELECT 'geometrytype02', geometrytype(ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( - -2 0 0, - -1 -1 1, - 0 0 2, - 1 -1 3, - 2 0 4, - 0 2 2, - -2 0 0), - (-1 0 1, - 0 0.5 2, - 1 0 3, - 0 1 3, - -1 0 1)), - ((7 8 7, - 10 10 5, - 6 14 3, - 4 11 4, - 7 8 7), - (9 9 7, - 8 12 7, - 7 10 7, - 9 9 7)))')); -SELECT 'ndims03', ST_ndims(ST_geomfromewkt('MULTISURFACEM(CURVEPOLYGON(CIRCULARSTRING( - -2 0 0, - -1 -1 2, - 0 0 4, - 1 -1 6, - 2 0 8, - 0 2 4, - -2 0 0), - (-1 0 2, - 0 0.5 4, - 1 0 6, - 0 1 4, - -1 0 2)), - ((7 8 8, - 10 10 5, - 6 14 1, - 4 11 6, - 7 8 8), - (9 9 8, - 8 12 8, - 7 10 8, - 9 9 8)))')); -SELECT 'geometrytype03', geometrytype(ST_geomfromewkt('MULTISURFACEM(CURVEPOLYGON(CIRCULARSTRING( - -2 0 0, - -1 -1 2, - 0 0 4, - 1 -1 6, - 2 0 8, - 0 2 4, - -2 0 0), - (-1 0 2, - 0 0.5 4, - 1 0 6, - 0 1 4, - -1 0 2)), - ((7 8 8, - 10 10 5, - 6 14 1, - 4 11 6, - 7 8 8)))')); -SELECT 'ndims04', ST_ndims(ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( - -2 0, - -1 -1, - 0 0, - 1 -1, - 2 0, - 0 2, - -2 0), - (-1 0, - 0 0.5, - 1 0, - 0 1, - -1 0)), - ((7 8, - 10 10, - 6 14, - 4 11, - 7 8)))')); -SELECT 'geometrytype04', geometrytype(ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( - -2 0, - -1 -1, - 0 0, - 1 -1, - 2 0, - 0 2, - -2 0), - (-1 0, - 0 0.5, - 1 0, - 0 1, - -1 0)), - ((7 8, - 10 10, - 6 14, - 4 11, - 7 8)))')); - -CREATE TABLE public.multisurface (id INTEGER, description VARCHAR, -the_geom_2d GEOMETRY(MULTISURFACE), -the_geom_3dm GEOMETRY(MULTISURFACEM), -the_geom_3dz GEOMETRY(MULTISURFACEZ), -the_geom_4d GEOMETRY(MULTISURFACEZM)); - -INSERT INTO public.multisurface ( - id, description - ) VALUES ( - 1, 'multisurface'); -UPDATE public.multisurface - SET the_geom_4d = ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( - -2 0 0 0, - -1 -1 1 2, - 0 0 2 4, - 1 -1 3 6, - 2 0 4 8, - 0 2 2 4, - -2 0 0 0), - (-1 0 1 2, - 0 0.5 2 4, - 1 0 3 6, - 0 1 3 4, - -1 0 1 2)), - ((7 8 7 8, - 10 10 5 5, - 6 14 3 1, - 4 11 4 6, - 7 8 7 8)))') - WHERE id = 1; -UPDATE public.multisurface - SET the_geom_3dz = ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( - -2 0 0, - -1 -1 1, - 0 0 2, - 1 -1 3, - 2 0 4, - 0 2 2, - -2 0 0), - (-1 0 1, - 0 0.5 2, - 1 0 3, - 0 1 3, - -1 0 1)), - ((7 8 7, - 10 10 5, - 6 14 3, - 4 11 4, - 7 8 7)))') - WHERE id = 1; -UPDATE public.multisurface - SET the_geom_3dm = ST_geomfromewkt('MULTISURFACEM(CURVEPOLYGON(CIRCULARSTRING( - -2 0 0, - -1 -1 2, - 0 0 4, - 1 -1 6, - 2 0 8, - 0 2 4, - -2 0 0), - (-1 0 2, - 0 0.5 4, - 1 0 6, - 0 1 4, - -1 0 2)), - ((7 8 8, - 10 10 5, - 6 14 1, - 4 11 6, - 7 8 8)))') - WHERE id = 1; -UPDATE public.multisurface - SET the_geom_2d = ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( - -2 0, - -1 -1, - 0 0, - 1 -1, - 2 0, - 0 2, - -2 0), - (-1 0, - 0 0.5, - 1 0, - 0 1, - -1 0)), - ((7 8, - 10 10, - 6 14, - 4 11, - 7 8)))') - WHERE id = 1; --- These tests will fail on different architectures --- We need a way to handle multiple byte orderings ---SELECT 'asbinary01', encode(asbinary(the_geom_2d), 'hex') FROM public.multisurface; ---SELECT 'asbinary02', encode(asbinary(the_geom_3dm), 'hex') FROM public.multisurface; ---SELECT 'asbinary03', encode(asbinary(the_geom_3dz), 'hex') FROM public.multisurface; ---SELECT 'asbinary04', encode(asbinary(the_geom_4d), 'hex') FROM public.multisurface; --- ---SELECT 'asewkb01', encode(asewkb(the_geom_2d), 'hex') FROM public.multisurface; ---SELECT 'asewkb02', encode(asewkb(the_geom_3dm), 'hex') FROM public.multisurface; ---SELECT 'asewkb03', encode(asewkb(the_geom_3dz), 'hex') FROM public.multisurface; ---SELECT 'asewkb04', encode(asewkb(the_geom_4d), 'hex') FROM public.multisurface; - -SELECT 'ST_CurveToLine-201', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; -SELECT 'ST_CurveToLine-202', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; -SELECT 'ST_CurveToLine-203', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; -SELECT 'ST_CurveToLine-204', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; - -SELECT 'ST_CurveToLine-401', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; -SELECT 'ST_CurveToLine-402', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; -SELECT 'ST_CurveToLine-403', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; -SELECT 'ST_CurveToLine-404', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; - -SELECT 'ST_CurveToLine01', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; -SELECT 'ST_CurveToLine02', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; -SELECT 'ST_CurveToLine03', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; -SELECT 'ST_CurveToLine04', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; - --- TODO: ST_SnapToGrid is required to remove platform dependent precision --- issues. Until ST_SnapToGrid is updated to work against curves, these --- tests cannot be run. ---SELECT 'ST_LineToCurve01', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_2d))) FROM public.multisurface; ---SELECT 'ST_LineToCurve02', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dm))) FROM public.multisurface; ---SELECT 'ST_LineToCurve03', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dz))) FROM public.multisurface; ---SELECT 'ST_LineToCurve04', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_4d))) FROM public.multisurface; - --- Repeat tests with new function names. -SELECT 'astext01', ST_astext(the_geom_2d) FROM public.multisurface; -SELECT 'astext02', ST_astext(the_geom_3dm) FROM public.multisurface; -SELECT 'astext03', ST_astext(the_geom_3dz) FROM public.multisurface; -SELECT 'astext04', ST_astext(the_geom_4d) FROM public.multisurface; - -SELECT 'asewkt01', ST_asewkt(the_geom_2d) FROM public.multisurface; -SELECT 'asewkt02', ST_asewkt(the_geom_3dm) FROM public.multisurface; -SELECT 'asewkt03', ST_asewkt(the_geom_3dz) FROM public.multisurface; -SELECT 'asewkt04', ST_asewkt(the_geom_4d) FROM public.multisurface; - --- These tests will fail on different architectures --- We need a way to handle multiple byte orderings ---SELECT 'asbinary01', encode(ST_asbinary(the_geom_2d), 'hex') FROM public.multisurface; ---SELECT 'asbinary02', encode(ST_asbinary(the_geom_3dm), 'hex') FROM public.multisurface; ---SELECT 'asbinary03', encode(ST_asbinary(the_geom_3dz), 'hex') FROM public.multisurface; ---SELECT 'asbinary04', encode(ST_asbinary(the_geom_4d), 'hex') FROM public.multisurface; --- ---SELECT 'asewkb01', encode(ST_asewkb(the_geom_2d), 'hex') FROM public.multisurface; ---SELECT 'asewkb02', encode(ST_asewkb(the_geom_3dm), 'hex') FROM public.multisurface; ---SELECT 'asewkb03', encode(ST_asewkb(the_geom_3dz), 'hex') FROM public.multisurface; ---SELECT 'asewkb04', encode(ST_asewkb(the_geom_4d), 'hex') FROM public.multisurface; - -SELECT 'box2d01', box2d(the_geom_2d) FROM public.multisurface; -SELECT 'box2d02', box2d(the_geom_3dm) FROM public.multisurface; -SELECT 'box2d03', box2d(the_geom_3dz) FROM public.multisurface; -SELECT 'box2d04', box2d(the_geom_4d) FROM public.multisurface; - -SELECT 'box3d01', box3d(the_geom_2d) FROM public.multisurface; -SELECT 'box3d02', box3d(the_geom_3dm) FROM public.multisurface; -SELECT 'box3d03', box3d(the_geom_3dz) FROM public.multisurface; -SELECT 'box3d04', box3d(the_geom_4d) FROM public.multisurface; - -SELECT 'isValid01', ST_IsValid(the_geom_2d) FROM public.multisurface; -SELECT 'isValid02', ST_IsValid(the_geom_3dm) FROM public.multisurface; -SELECT 'isValid03', ST_IsValid(the_geom_3dz) FROM public.multisurface; -SELECT 'isValid04', ST_IsValid(the_geom_4d) FROM public.multisurface; - -SELECT 'dimension01', ST_dimension(the_geom_2d) FROM public.multisurface; -SELECT 'dimension02', ST_dimension(the_geom_3dm) FROM public.multisurface; -SELECT 'dimension03', ST_dimension(the_geom_3dz) FROM public.multisurface; -SELECT 'dimension04', ST_dimension(the_geom_4d) FROM public.multisurface; - -SELECT 'numGeometries01', ST_numGeometries(the_geom_2d) FROM public.multisurface; -SELECT 'numGeometries02', ST_numGeometries(the_geom_3dm) FROM public.multisurface; -SELECT 'numGeometries03', ST_numGeometries(the_geom_3dz) FROM public.multisurface; -SELECT 'numGeometries04', ST_numGeometries(the_geom_4d) FROM public.multisurface; - -SELECT 'geometryN-201', ST_asEWKT(ST_geometryN(the_geom_2d, 2)) FROM public.multisurface; -SELECT 'geometryN-202', ST_asEWKT(ST_geometryN(the_geom_3dm, 2)) FROM public.multisurface; -SELECT 'geometryN-203', ST_asEWKT(ST_geometryN(the_geom_3dz, 2)) FROM public.multisurface; -SELECT 'geometryN-204', ST_asEWKT(ST_geometryN(the_geom_4d, 2)) FROM public.multisurface; - -SELECT 'geometryN-301', (ST_geometryN(the_geom_2d, 3) is null) FROM public.multisurface; -SELECT 'geometryN-302', (ST_geometryN(the_geom_3dm, 3) is null) FROM public.multisurface; -SELECT 'geometryN-303', (ST_geometryN(the_geom_3dz, 3) is null) FROM public.multisurface; -SELECT 'geometryN-304', (ST_geometryN(the_geom_4d, 3) is null) FROM public.multisurface; - -SELECT DropGeometryColumn('public', 'multisurface', 'the_geom_2d'); -SELECT DropGeometryColumn('public', 'multisurface', 'the_geom_3dm'); -SELECT DropGeometryColumn('public', 'multisurface', 'the_geom_3dz'); -SELECT DropGeometryColumn('public', 'multisurface', 'the_geom_4d'); -DROP TABLE public.multisurface; - +-- Repeat these tests with the new function names. +SELECT 'ndims01', ST_ndims(ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( + -2 0 0 0, + -1 -1 1 2, + 0 0 2 4, + 1 -1 3 6, + 2 0 4 8, + 0 2 2 4, + -2 0 0 0), + (-1 0 1 2, + 0 0.5 2 4, + 1 0 3 6, + 0 1 3 4, + -1 0 1 2)), + ((7 8 7 8, + 10 10 5 5, + 6 14 3 1, + 4 11 4 6, + 7 8 7 8)))')); +SELECT 'geometrytype01', geometrytype(ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( + -2 0 0 0, + -1 -1 1 2, + 0 0 2 4, + 1 -1 3 6, + 2 0 4 8, + 0 2 2 4, + -2 0 0 0), + (-1 0 1 2, + 0 0.5 2 4, + 1 0 3 6, + 0 1 3 4, + -1 0 1 2)), + ((7 8 7 8, + 10 10 5 5, + 6 14 3 1, + 4 11 4 6, + 7 8 7 8), + (9 9 7 8, + 8 12 7 8, + 7 10 7 8, + 9 9 7 8)))')); +SELECT 'ndims02', ST_ndims(ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( + -2 0 0, + -1 -1 1, + 0 0 2, + 1 -1 3, + 2 0 4, + 0 2 2, + -2 0 0), + (-1 0 1, + 0 0.5 2, + 1 0 3, + 0 1 3, + -1 0 1)), + ((7 8 7, + 10 10 5, + 6 14 3, + 4 11 4, + 7 8 7), + (9 9 7, + 8 12 7, + 7 10 7, + 9 9 7)))')); +SELECT 'geometrytype02', geometrytype(ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( + -2 0 0, + -1 -1 1, + 0 0 2, + 1 -1 3, + 2 0 4, + 0 2 2, + -2 0 0), + (-1 0 1, + 0 0.5 2, + 1 0 3, + 0 1 3, + -1 0 1)), + ((7 8 7, + 10 10 5, + 6 14 3, + 4 11 4, + 7 8 7), + (9 9 7, + 8 12 7, + 7 10 7, + 9 9 7)))')); +SELECT 'ndims03', ST_ndims(ST_geomfromewkt('MULTISURFACEM(CURVEPOLYGON(CIRCULARSTRING( + -2 0 0, + -1 -1 2, + 0 0 4, + 1 -1 6, + 2 0 8, + 0 2 4, + -2 0 0), + (-1 0 2, + 0 0.5 4, + 1 0 6, + 0 1 4, + -1 0 2)), + ((7 8 8, + 10 10 5, + 6 14 1, + 4 11 6, + 7 8 8), + (9 9 8, + 8 12 8, + 7 10 8, + 9 9 8)))')); +SELECT 'geometrytype03', geometrytype(ST_geomfromewkt('MULTISURFACEM(CURVEPOLYGON(CIRCULARSTRING( + -2 0 0, + -1 -1 2, + 0 0 4, + 1 -1 6, + 2 0 8, + 0 2 4, + -2 0 0), + (-1 0 2, + 0 0.5 4, + 1 0 6, + 0 1 4, + -1 0 2)), + ((7 8 8, + 10 10 5, + 6 14 1, + 4 11 6, + 7 8 8)))')); +SELECT 'ndims04', ST_ndims(ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( + -2 0, + -1 -1, + 0 0, + 1 -1, + 2 0, + 0 2, + -2 0), + (-1 0, + 0 0.5, + 1 0, + 0 1, + -1 0)), + ((7 8, + 10 10, + 6 14, + 4 11, + 7 8)))')); +SELECT 'geometrytype04', geometrytype(ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( + -2 0, + -1 -1, + 0 0, + 1 -1, + 2 0, + 0 2, + -2 0), + (-1 0, + 0 0.5, + 1 0, + 0 1, + -1 0)), + ((7 8, + 10 10, + 6 14, + 4 11, + 7 8)))')); + +CREATE TABLE public.multisurface (id INTEGER, description VARCHAR, +the_geom_2d GEOMETRY(MULTISURFACE), +the_geom_3dm GEOMETRY(MULTISURFACEM), +the_geom_3dz GEOMETRY(MULTISURFACEZ), +the_geom_4d GEOMETRY(MULTISURFACEZM)); + +INSERT INTO public.multisurface ( + id, description + ) VALUES ( + 1, 'multisurface'); +UPDATE public.multisurface + SET the_geom_4d = ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( + -2 0 0 0, + -1 -1 1 2, + 0 0 2 4, + 1 -1 3 6, + 2 0 4 8, + 0 2 2 4, + -2 0 0 0), + (-1 0 1 2, + 0 0.5 2 4, + 1 0 3 6, + 0 1 3 4, + -1 0 1 2)), + ((7 8 7 8, + 10 10 5 5, + 6 14 3 1, + 4 11 4 6, + 7 8 7 8)))') + WHERE id = 1; +UPDATE public.multisurface + SET the_geom_3dz = ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( + -2 0 0, + -1 -1 1, + 0 0 2, + 1 -1 3, + 2 0 4, + 0 2 2, + -2 0 0), + (-1 0 1, + 0 0.5 2, + 1 0 3, + 0 1 3, + -1 0 1)), + ((7 8 7, + 10 10 5, + 6 14 3, + 4 11 4, + 7 8 7)))') + WHERE id = 1; +UPDATE public.multisurface + SET the_geom_3dm = ST_geomfromewkt('MULTISURFACEM(CURVEPOLYGON(CIRCULARSTRING( + -2 0 0, + -1 -1 2, + 0 0 4, + 1 -1 6, + 2 0 8, + 0 2 4, + -2 0 0), + (-1 0 2, + 0 0.5 4, + 1 0 6, + 0 1 4, + -1 0 2)), + ((7 8 8, + 10 10 5, + 6 14 1, + 4 11 6, + 7 8 8)))') + WHERE id = 1; +UPDATE public.multisurface + SET the_geom_2d = ST_geomfromewkt('MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING( + -2 0, + -1 -1, + 0 0, + 1 -1, + 2 0, + 0 2, + -2 0), + (-1 0, + 0 0.5, + 1 0, + 0 1, + -1 0)), + ((7 8, + 10 10, + 6 14, + 4 11, + 7 8)))') + WHERE id = 1; +-- These tests will fail on different architectures +-- We need a way to handle multiple byte orderings +--SELECT 'asbinary01', encode(asbinary(the_geom_2d), 'hex') FROM public.multisurface; +--SELECT 'asbinary02', encode(asbinary(the_geom_3dm), 'hex') FROM public.multisurface; +--SELECT 'asbinary03', encode(asbinary(the_geom_3dz), 'hex') FROM public.multisurface; +--SELECT 'asbinary04', encode(asbinary(the_geom_4d), 'hex') FROM public.multisurface; +-- +--SELECT 'asewkb01', encode(asewkb(the_geom_2d), 'hex') FROM public.multisurface; +--SELECT 'asewkb02', encode(asewkb(the_geom_3dm), 'hex') FROM public.multisurface; +--SELECT 'asewkb03', encode(asewkb(the_geom_3dz), 'hex') FROM public.multisurface; +--SELECT 'asewkb04', encode(asewkb(the_geom_4d), 'hex') FROM public.multisurface; + +SELECT 'ST_CurveToLine-201', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; +SELECT 'ST_CurveToLine-202', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; +SELECT 'ST_CurveToLine-203', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; +SELECT 'ST_CurveToLine-204', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 2), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; + +SELECT 'ST_CurveToLine-401', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; +SELECT 'ST_CurveToLine-402', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; +SELECT 'ST_CurveToLine-403', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; +SELECT 'ST_CurveToLine-404', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d, 4), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; + +SELECT 'ST_CurveToLine01', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_2d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; +SELECT 'ST_CurveToLine02', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dm), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; +SELECT 'ST_CurveToLine03', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_3dz), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; +SELECT 'ST_CurveToLine04', ST_Asewkt(ST_SnapToGrid(ST_CurveToLine(the_geom_4d), 'POINT(0 0 0 0)'::geometry, 1e-8, 1e-8, 1e-8, 1e-8)) FROM public.multisurface; + +-- TODO: ST_SnapToGrid is required to remove platform dependent precision +-- issues. Until ST_SnapToGrid is updated to work against curves, these +-- tests cannot be run. +--SELECT 'ST_LineToCurve01', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_2d))) FROM public.multisurface; +--SELECT 'ST_LineToCurve02', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dm))) FROM public.multisurface; +--SELECT 'ST_LineToCurve03', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_3dz))) FROM public.multisurface; +--SELECT 'ST_LineToCurve04', ST_Asewkt(ST_LineToCurve(ST_CurveToLine(the_geom_4d))) FROM public.multisurface; + +-- Repeat tests with new function names. +SELECT 'astext01', ST_astext(the_geom_2d) FROM public.multisurface; +SELECT 'astext02', ST_astext(the_geom_3dm) FROM public.multisurface; +SELECT 'astext03', ST_astext(the_geom_3dz) FROM public.multisurface; +SELECT 'astext04', ST_astext(the_geom_4d) FROM public.multisurface; + +SELECT 'asewkt01', ST_asewkt(the_geom_2d) FROM public.multisurface; +SELECT 'asewkt02', ST_asewkt(the_geom_3dm) FROM public.multisurface; +SELECT 'asewkt03', ST_asewkt(the_geom_3dz) FROM public.multisurface; +SELECT 'asewkt04', ST_asewkt(the_geom_4d) FROM public.multisurface; + +-- These tests will fail on different architectures +-- We need a way to handle multiple byte orderings +--SELECT 'asbinary01', encode(ST_asbinary(the_geom_2d), 'hex') FROM public.multisurface; +--SELECT 'asbinary02', encode(ST_asbinary(the_geom_3dm), 'hex') FROM public.multisurface; +--SELECT 'asbinary03', encode(ST_asbinary(the_geom_3dz), 'hex') FROM public.multisurface; +--SELECT 'asbinary04', encode(ST_asbinary(the_geom_4d), 'hex') FROM public.multisurface; +-- +--SELECT 'asewkb01', encode(ST_asewkb(the_geom_2d), 'hex') FROM public.multisurface; +--SELECT 'asewkb02', encode(ST_asewkb(the_geom_3dm), 'hex') FROM public.multisurface; +--SELECT 'asewkb03', encode(ST_asewkb(the_geom_3dz), 'hex') FROM public.multisurface; +--SELECT 'asewkb04', encode(ST_asewkb(the_geom_4d), 'hex') FROM public.multisurface; + +SELECT 'box2d01', box2d(the_geom_2d) FROM public.multisurface; +SELECT 'box2d02', box2d(the_geom_3dm) FROM public.multisurface; +SELECT 'box2d03', box2d(the_geom_3dz) FROM public.multisurface; +SELECT 'box2d04', box2d(the_geom_4d) FROM public.multisurface; + +SELECT 'box3d01', box3d(the_geom_2d) FROM public.multisurface; +SELECT 'box3d02', box3d(the_geom_3dm) FROM public.multisurface; +SELECT 'box3d03', box3d(the_geom_3dz) FROM public.multisurface; +SELECT 'box3d04', box3d(the_geom_4d) FROM public.multisurface; + +SELECT 'isValid01', ST_IsValid(the_geom_2d) FROM public.multisurface; +SELECT 'isValid02', ST_IsValid(the_geom_3dm) FROM public.multisurface; +SELECT 'isValid03', ST_IsValid(the_geom_3dz) FROM public.multisurface; +SELECT 'isValid04', ST_IsValid(the_geom_4d) FROM public.multisurface; + +SELECT 'dimension01', ST_dimension(the_geom_2d) FROM public.multisurface; +SELECT 'dimension02', ST_dimension(the_geom_3dm) FROM public.multisurface; +SELECT 'dimension03', ST_dimension(the_geom_3dz) FROM public.multisurface; +SELECT 'dimension04', ST_dimension(the_geom_4d) FROM public.multisurface; + +SELECT 'numGeometries01', ST_numGeometries(the_geom_2d) FROM public.multisurface; +SELECT 'numGeometries02', ST_numGeometries(the_geom_3dm) FROM public.multisurface; +SELECT 'numGeometries03', ST_numGeometries(the_geom_3dz) FROM public.multisurface; +SELECT 'numGeometries04', ST_numGeometries(the_geom_4d) FROM public.multisurface; + +SELECT 'geometryN-201', ST_asEWKT(ST_geometryN(the_geom_2d, 2)) FROM public.multisurface; +SELECT 'geometryN-202', ST_asEWKT(ST_geometryN(the_geom_3dm, 2)) FROM public.multisurface; +SELECT 'geometryN-203', ST_asEWKT(ST_geometryN(the_geom_3dz, 2)) FROM public.multisurface; +SELECT 'geometryN-204', ST_asEWKT(ST_geometryN(the_geom_4d, 2)) FROM public.multisurface; + +SELECT 'geometryN-301', (ST_geometryN(the_geom_2d, 3) is null) FROM public.multisurface; +SELECT 'geometryN-302', (ST_geometryN(the_geom_3dm, 3) is null) FROM public.multisurface; +SELECT 'geometryN-303', (ST_geometryN(the_geom_3dz, 3) is null) FROM public.multisurface; +SELECT 'geometryN-304', (ST_geometryN(the_geom_4d, 3) is null) FROM public.multisurface; + +SELECT DropGeometryColumn('public', 'multisurface', 'the_geom_2d'); +SELECT DropGeometryColumn('public', 'multisurface', 'the_geom_3dm'); +SELECT DropGeometryColumn('public', 'multisurface', 'the_geom_3dz'); +SELECT DropGeometryColumn('public', 'multisurface', 'the_geom_4d'); +DROP TABLE public.multisurface; + diff --git a/regress/sql-mm-serialize.sql b/regress/sql-mm-serialize.sql index 2189e5f32..7c5082b34 100644 --- a/regress/sql-mm-serialize.sql +++ b/regress/sql-mm-serialize.sql @@ -1,164 +1,164 @@ - -CREATE TABLE serialize_test ( - id INTEGER, - description VARCHAR, - ewkt VARCHAR, - serialized TEXT); - -INSERT INTO serialize_test ( - id, description, ewkt, serialized - ) VALUES ( - 1, 'Circular String', - 'CIRCULARSTRING(-2 0,0 2,2 0,0 2,2 4)', - '01080000000500000000000000000000C0000000000000000000000000000000000000000000000040000000000000004000000000000000000000000000000000000000000000004000000000000000400000000000001040'); -INSERT INTO serialize_test ( - id, description, ewkt, serialized - ) VALUES ( - 2, 'Circular String, SRID=4326', - 'SRID=4326;CIRCULARSTRING(-2 0,0 2,2 0,0 2,2 4)', - '0108000020E61000000500000000000000000000C0000000000000000000000000000000000000000000000040000000000000004000000000000000000000000000000000000000000000004000000000000000400000000000001040'); -INSERT INTO serialize_test ( - id, description, ewkt, serialized - ) VALUES ( - 3, 'Circular String 3dz, SRID=4326', - 'SRID=4326;CIRCULARSTRING(-2 0 1,0 2 1,2 0 1,0 2 1,2 4 1)', - '01080000A0E61000000500000000000000000000C00000000000000000000000000000F03F00000000000000000000000000000040000000000000F03F00000000000000400000000000000000000000000000F03F00000000000000000000000000000040000000000000F03F00000000000000400000000000001040000000000000F03F'); -INSERT INTO serialize_test ( - id, description, ewkt, serialized - ) VALUES ( - 4, 'Circular String 3dm, SRID=4326', - 'SRID=4326;CIRCULARSTRINGM(-2 0 1,0 2 1,2 0 1,0 2 1,2 4 1)', - '0108000060E61000000500000000000000000000C00000000000000000000000000000F03F00000000000000000000000000000040000000000000F03F00000000000000400000000000000000000000000000F03F00000000000000000000000000000040000000000000F03F00000000000000400000000000001040000000000000F03F'); -INSERT INTO serialize_test ( - id, description, ewkt, serialized - ) VALUES ( - 5, 'Circular String 4d, SRID=4326', - 'SRID=4326;CIRCULARSTRING(-2 0 1 0,0 2 1 0,2 0 1 0,0 2 1 0,2 4 1 0)', - '01080000E0E61000000500000000000000000000C00000000000000000000000000000F03F000000000000000000000000000000000000000000000040000000000000F03F000000000000000000000000000000400000000000000000000000000000F03F000000000000000000000000000000000000000000000040000000000000F03F000000000000000000000000000000400000000000001040000000000000F03F0000000000000000'); -INSERT INTO serialize_test ( - id, description, ewkt, serialized - ) VALUES ( - 6, 'Compound Curve', - 'COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))', - '01090000000200000001080000000300000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F0000000000000000010200000002000000000000000000F03F00000000000000000000000000000000000000000000F03F'); -INSERT INTO serialize_test ( - id, description, ewkt, serialized - ) VALUES ( - 7, 'Compound Curve, SRID=4326', - 'SRID=4326;COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))', - '0109000020E61000000200000001080000000300000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F0000000000000000010200000002000000000000000000F03F00000000000000000000000000000000000000000000F03F'); -INSERT INTO serialize_test ( - id, description, ewkt, serialized - ) VALUES ( - 8, 'Compound Curve 3dz, SRID=4326', - 'SRID=4326;COMPOUNDCURVE(CIRCULARSTRING(0 0 2,1 1 2,1 0 2),(1 0 2,0 1 2))', - '01090000A0E610000002000000010800008003000000000000000000000000000000000000000000000000000040000000000000F03F000000000000F03F0000000000000040000000000000F03F00000000000000000000000000000040010200008002000000000000000000F03F000000000000000000000000000000400000000000000000000000000000F03F0000000000000040'); -INSERT INTO serialize_test ( - id, description, ewkt, serialized - ) VALUES ( - 9, 'Compound Curve 3dm, SRID=4326', - 'SRID=4326;COMPOUNDCURVEM(CIRCULARSTRINGM(0 0 2,1 1 2,1 0 2),(1 0 2,0 1 2))', - '0109000060E610000002000000010800004003000000000000000000000000000000000000000000000000000040000000000000F03F000000000000F03F0000000000000040000000000000F03F00000000000000000000000000000040010200004002000000000000000000F03F000000000000000000000000000000400000000000000000000000000000F03F0000000000000040'); -INSERT INTO serialize_test ( - id, description, ewkt, serialized - ) VALUES ( - 10, 'Compound Curve 4d, SRID=4326', - 'SRID=4326;COMPOUNDCURVE(CIRCULARSTRING(0 0 2 5,1 1 2 5,1 0 2 5),(1 0 2 5,0 1 2 2))', - '01090000E0E61000000200000001080000C0030000000000000000000000000000000000000000000000000000400000000000001440000000000000F03F000000000000F03F00000000000000400000000000001440000000000000F03F00000000000000000000000000000040000000000000144001020000C002000000000000000000F03F0000000000000000000000000000004000000000000014400000000000000000000000000000F03F00000000000000400000000000000040'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 11, 'Curve Polygon', - 'CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0))', - '010A0000000200000001080000000700000000000000000000C00000000000000000000000000000F0BF000000000000F0BF00000000000000000000000000000000000000000000F03F000000000000F0BF000000000000004000000000000000000000000000000000000000000000004000000000000000C00000000000000000010200000005000000000000000000F0BF00000000000000000000000000000000000000000000E03F000000000000F03F00000000000000000000000000000000000000000000F03F000000000000F0BF0000000000000000'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 12, 'Curve Polygon, SRID=4326', - 'SRID=4326;CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0))', - '010A000020E61000000200000001080000000700000000000000000000C00000000000000000000000000000F0BF000000000000F0BF00000000000000000000000000000000000000000000F03F000000000000F0BF000000000000004000000000000000000000000000000000000000000000004000000000000000C00000000000000000010200000005000000000000000000F0BF00000000000000000000000000000000000000000000E03F000000000000F03F00000000000000000000000000000000000000000000F03F000000000000F0BF0000000000000000'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 13, 'Curve Polygon 3dz, SRID=4326', - 'SRID=4326;CURVEPOLYGON(CIRCULARSTRING(-2 0 0,-1 -1 1,0 0 2,1 -1 3,2 0 4,0 2 2,-2 0 0),(-1 0 1,0 0.5 2,1 0 3,0 1 3,-1 0 1))', - '010A0000A0E61000000200000001080000800700000000000000000000C000000000000000000000000000000000000000000000F0BF000000000000F0BF000000000000F03F000000000000000000000000000000000000000000000040000000000000F03F000000000000F0BF000000000000084000000000000000400000000000000000000000000000104000000000000000000000000000000040000000000000004000000000000000C000000000000000000000000000000000010200008005000000000000000000F0BF0000000000000000000000000000F03F0000000000000000000000000000E03F0000000000000040000000000000F03F000000000000000000000000000008400000000000000000000000000000F03F0000000000000840000000000000F0BF0000000000000000000000000000F03F'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 14, 'Curve Polygon 3dm, SRID=4326', - 'SRID=4326;CURVEPOLYGONM(CIRCULARSTRINGM(-2 0 0,-1 -1 2,0 0 4,1 -1 6,2 0 8,0 2 4,-2 0 0),(-1 0 2,0 0.5 4,1 0 6,0 1 4,-1 0 2))', - '010A000060E61000000200000001080000400700000000000000000000C000000000000000000000000000000000000000000000F0BF000000000000F0BF0000000000000040000000000000000000000000000000000000000000001040000000000000F03F000000000000F0BF000000000000184000000000000000400000000000000000000000000000204000000000000000000000000000000040000000000000104000000000000000C000000000000000000000000000000000010200004005000000000000000000F0BF000000000000000000000000000000400000000000000000000000000000E03F0000000000001040000000000000F03F000000000000000000000000000018400000000000000000000000000000F03F0000000000001040000000000000F0BF00000000000000000000000000000040'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 15, 'Curve Polygon 4d, SRID=4326', - 'SRID=4326;CURVEPOLYGON(CIRCULARSTRING(-2 0 0 0,-1 -1 1 2,0 0 2 4,1 -1 3 6,2 0 4 8,0 2 2 4,-2 0 0 0),(-1 0 1 2,0 0.5 2 4,1 0 3 6,0 1 3 4,-1 0 1 2))', - '010A0000E0E61000000200000001080000C00700000000000000000000C0000000000000000000000000000000000000000000000000000000000000F0BF000000000000F0BF000000000000F03F00000000000000400000000000000000000000000000000000000000000000400000000000001040000000000000F03F000000000000F0BF000000000000084000000000000018400000000000000040000000000000000000000000000010400000000000002040000000000000000000000000000000400000000000000040000000000000104000000000000000C000000000000000000000000000000000000000000000000001020000C005000000000000000000F0BF0000000000000000000000000000F03F00000000000000400000000000000000000000000000E03F00000000000000400000000000001040000000000000F03F0000000000000000000000000000084000000000000018400000000000000000000000000000F03F00000000000008400000000000001040000000000000F0BF0000000000000000000000000000F03F0000000000000040'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 16, 'Multi Curve', - 'MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2))', - '010B0000000200000001020000000400000000000000000014400000000000001440000000000000084000000000000014400000000000000840000000000000084000000000000000000000000000000840010800000003000000000000000000000000000000000000000000000000000040000000000000F03F00000000000000400000000000000040'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 17, 'Multi Curve, SRID=4326', - 'SRID=4326;MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2))', - '010B000020E61000000200000001020000000400000000000000000014400000000000001440000000000000084000000000000014400000000000000840000000000000084000000000000000000000000000000840010800000003000000000000000000000000000000000000000000000000000040000000000000F03F00000000000000400000000000000040'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 18, 'Multi Curve 3dz, SRID=4326', - 'SRID=4326;MULTICURVE((5 5 1,3 5 2,3 3 3,0 3 1),CIRCULARSTRING(0 0 0,2 1 3,2 2 1))', - '010B0000A0E61000000200000001020000800400000000000000000014400000000000001440000000000000F03F00000000000008400000000000001440000000000000004000000000000008400000000000000840000000000000084000000000000000000000000000000840000000000000F03F0108000080030000000000000000000000000000000000000000000000000000000000000000000040000000000000F03F000000000000084000000000000000400000000000000040000000000000F03F'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 19, 'Multi Curve 3dm, SRID=4326', - 'SRID=4326;MULTICURVEM((5 5 3,3 5 2,3 3 1,0 3 1),CIRCULARSTRINGM(0 0 0,2 1 -2,2 2 2))', - '010B000060E61000000200000001020000400400000000000000000014400000000000001440000000000000084000000000000008400000000000001440000000000000004000000000000008400000000000000840000000000000F03F00000000000000000000000000000840000000000000F03F0108000040030000000000000000000000000000000000000000000000000000000000000000000040000000000000F03F00000000000000C0000000000000004000000000000000400000000000000040'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 20, 'Multi Curve 4d, SRID=4326', - 'SRID=4326;MULTICURVE((5 5 1 3,3 5 2 2,3 3 3 1,0 3 1 1),CIRCULARSTRING(0 0 0 0,2 1 3 -2,2 2 1 2))', - '010B0000E0E61000000200000001020000C00400000000000000000014400000000000001440000000000000F03F00000000000008400000000000000840000000000000144000000000000000400000000000000040000000000000084000000000000008400000000000000840000000000000F03F00000000000000000000000000000840000000000000F03F000000000000F03F01080000C00300000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000F03F000000000000084000000000000000C000000000000000400000000000000040000000000000F03F0000000000000040'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 21, 'Multi Surface', - 'MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)),((7 8,10 10,6 14,4 11,7 8)))', - '010C00000002000000010A0000000200000001080000000700000000000000000000C00000000000000000000000000000F0BF000000000000F0BF00000000000000000000000000000000000000000000F03F000000000000F0BF000000000000004000000000000000000000000000000000000000000000004000000000000000C00000000000000000010200000005000000000000000000F0BF00000000000000000000000000000000000000000000E03F000000000000F03F00000000000000000000000000000000000000000000F03F000000000000F0BF0000000000000000010300000001000000050000000000000000001C4000000000000020400000000000002440000000000000244000000000000018400000000000002C40000000000000104000000000000026400000000000001C400000000000002040'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 22, 'Multi Surface, SRID=4326', - 'SRID=4326;MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)),((7 8,10 10,6 14,4 11,7 8)))', - '010C000020E610000002000000010A0000000200000001080000000700000000000000000000C00000000000000000000000000000F0BF000000000000F0BF00000000000000000000000000000000000000000000F03F000000000000F0BF000000000000004000000000000000000000000000000000000000000000004000000000000000C00000000000000000010200000005000000000000000000F0BF00000000000000000000000000000000000000000000E03F000000000000F03F00000000000000000000000000000000000000000000F03F000000000000F0BF0000000000000000010300000001000000050000000000000000001C4000000000000020400000000000002440000000000000244000000000000018400000000000002C40000000000000104000000000000026400000000000001C400000000000002040'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 23, 'Multi Surface 3dz, SRID=4326', - 'SRID=4326;MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0 0,-1 -1 1,0 0 2,1 -1 3,2 0 4,0 2 2,-2 0 0),(-1 0 1,0 0.5 2,1 0 3,0 1 3,-1 0 1)),((7 8 7,10 10 5,6 14 3,4 11 4,7 8 7)))', - '010C0000A0E610000002000000010A0000800200000001080000800700000000000000000000C000000000000000000000000000000000000000000000F0BF000000000000F0BF000000000000F03F000000000000000000000000000000000000000000000040000000000000F03F000000000000F0BF000000000000084000000000000000400000000000000000000000000000104000000000000000000000000000000040000000000000004000000000000000C000000000000000000000000000000000010200008005000000000000000000F0BF0000000000000000000000000000F03F0000000000000000000000000000E03F0000000000000040000000000000F03F000000000000000000000000000008400000000000000000000000000000F03F0000000000000840000000000000F0BF0000000000000000000000000000F03F010300008001000000050000000000000000001C4000000000000020400000000000001C4000000000000024400000000000002440000000000000144000000000000018400000000000002C4000000000000008400000000000001040000000000000264000000000000010400000000000001C4000000000000020400000000000001C40'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 24, 'Multi Surface 3dm, SRID=4326', - 'SRID=4326;MULTISURFACEM(CURVEPOLYGONM(CIRCULARSTRINGM(-2 0 0,-1 -1 2,0 0 4,1 -1 6,2 0 8,0 2 4,-2 0 0),(-1 0 2,0 0.5 4,1 0 6,0 1 4,-1 0 2)),((7 8 8,10 10 5,6 14 1,4 11 6,7 8 8)))', - '010C000060E610000002000000010A0000400200000001080000400700000000000000000000C000000000000000000000000000000000000000000000F0BF000000000000F0BF0000000000000040000000000000000000000000000000000000000000001040000000000000F03F000000000000F0BF000000000000184000000000000000400000000000000000000000000000204000000000000000000000000000000040000000000000104000000000000000C000000000000000000000000000000000010200004005000000000000000000F0BF000000000000000000000000000000400000000000000000000000000000E03F0000000000001040000000000000F03F000000000000000000000000000018400000000000000000000000000000F03F0000000000001040000000000000F0BF00000000000000000000000000000040010300004001000000050000000000000000001C400000000000002040000000000000204000000000000024400000000000002440000000000000144000000000000018400000000000002C40000000000000F03F0000000000001040000000000000264000000000000018400000000000001C4000000000000020400000000000002040'); -INSERT INTO serialize_test( - id, description, ewkt, serialized - ) VALUES ( - 25, 'Multi Surface 4d, SRID=4326', - 'SRID=4326;MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0 0 0,-1 -1 1 2,0 0 2 4,1 -1 3 6,2 0 4 8,0 2 2 4,-2 0 0 0),(-1 0 1 2,0 0.5 2 4,1 0 3 6,0 1 3 4,-1 0 1 2)),((7 8 7 8,10 10 5 5,6 14 3 1,4 11 4 6,7 8 7 8)))', - '010C0000E0E610000002000000010A0000C00200000001080000C00700000000000000000000C0000000000000000000000000000000000000000000000000000000000000F0BF000000000000F0BF000000000000F03F00000000000000400000000000000000000000000000000000000000000000400000000000001040000000000000F03F000000000000F0BF000000000000084000000000000018400000000000000040000000000000000000000000000010400000000000002040000000000000000000000000000000400000000000000040000000000000104000000000000000C000000000000000000000000000000000000000000000000001020000C005000000000000000000F0BF0000000000000000000000000000F03F00000000000000400000000000000000000000000000E03F00000000000000400000000000001040000000000000F03F0000000000000000000000000000084000000000000018400000000000000000000000000000F03F00000000000008400000000000001040000000000000F0BF0000000000000000000000000000F03F000000000000004001030000C001000000050000000000000000001C4000000000000020400000000000001C400000000000002040000000000000244000000000000024400000000000001440000000000000144000000000000018400000000000002C400000000000000840000000000000F03F00000000000010400000000000002640000000000000104000000000000018400000000000001C4000000000000020400000000000001C400000000000002040'); - - - -SELECT id, CASE WHEN ewkt = ST_asEWKT(serialized::geometry) THEN 'pass' ELSE 'fail' END AS result FROM serialize_test ORDER BY id; -SELECT id, CASE WHEN ST_asEWKB(geomFromEWKT(ewkt)) = serialized THEN 'pass' ELSE 'fail' END AS result FROM serialize_test ORDER BY id; - -DROP TABLE serialize_test; + +CREATE TABLE serialize_test ( + id INTEGER, + description VARCHAR, + ewkt VARCHAR, + serialized TEXT); + +INSERT INTO serialize_test ( + id, description, ewkt, serialized + ) VALUES ( + 1, 'Circular String', + 'CIRCULARSTRING(-2 0,0 2,2 0,0 2,2 4)', + '01080000000500000000000000000000C0000000000000000000000000000000000000000000000040000000000000004000000000000000000000000000000000000000000000004000000000000000400000000000001040'); +INSERT INTO serialize_test ( + id, description, ewkt, serialized + ) VALUES ( + 2, 'Circular String, SRID=4326', + 'SRID=4326;CIRCULARSTRING(-2 0,0 2,2 0,0 2,2 4)', + '0108000020E61000000500000000000000000000C0000000000000000000000000000000000000000000000040000000000000004000000000000000000000000000000000000000000000004000000000000000400000000000001040'); +INSERT INTO serialize_test ( + id, description, ewkt, serialized + ) VALUES ( + 3, 'Circular String 3dz, SRID=4326', + 'SRID=4326;CIRCULARSTRING(-2 0 1,0 2 1,2 0 1,0 2 1,2 4 1)', + '01080000A0E61000000500000000000000000000C00000000000000000000000000000F03F00000000000000000000000000000040000000000000F03F00000000000000400000000000000000000000000000F03F00000000000000000000000000000040000000000000F03F00000000000000400000000000001040000000000000F03F'); +INSERT INTO serialize_test ( + id, description, ewkt, serialized + ) VALUES ( + 4, 'Circular String 3dm, SRID=4326', + 'SRID=4326;CIRCULARSTRINGM(-2 0 1,0 2 1,2 0 1,0 2 1,2 4 1)', + '0108000060E61000000500000000000000000000C00000000000000000000000000000F03F00000000000000000000000000000040000000000000F03F00000000000000400000000000000000000000000000F03F00000000000000000000000000000040000000000000F03F00000000000000400000000000001040000000000000F03F'); +INSERT INTO serialize_test ( + id, description, ewkt, serialized + ) VALUES ( + 5, 'Circular String 4d, SRID=4326', + 'SRID=4326;CIRCULARSTRING(-2 0 1 0,0 2 1 0,2 0 1 0,0 2 1 0,2 4 1 0)', + '01080000E0E61000000500000000000000000000C00000000000000000000000000000F03F000000000000000000000000000000000000000000000040000000000000F03F000000000000000000000000000000400000000000000000000000000000F03F000000000000000000000000000000000000000000000040000000000000F03F000000000000000000000000000000400000000000001040000000000000F03F0000000000000000'); +INSERT INTO serialize_test ( + id, description, ewkt, serialized + ) VALUES ( + 6, 'Compound Curve', + 'COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))', + '01090000000200000001080000000300000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F0000000000000000010200000002000000000000000000F03F00000000000000000000000000000000000000000000F03F'); +INSERT INTO serialize_test ( + id, description, ewkt, serialized + ) VALUES ( + 7, 'Compound Curve, SRID=4326', + 'SRID=4326;COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))', + '0109000020E61000000200000001080000000300000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F0000000000000000010200000002000000000000000000F03F00000000000000000000000000000000000000000000F03F'); +INSERT INTO serialize_test ( + id, description, ewkt, serialized + ) VALUES ( + 8, 'Compound Curve 3dz, SRID=4326', + 'SRID=4326;COMPOUNDCURVE(CIRCULARSTRING(0 0 2,1 1 2,1 0 2),(1 0 2,0 1 2))', + '01090000A0E610000002000000010800008003000000000000000000000000000000000000000000000000000040000000000000F03F000000000000F03F0000000000000040000000000000F03F00000000000000000000000000000040010200008002000000000000000000F03F000000000000000000000000000000400000000000000000000000000000F03F0000000000000040'); +INSERT INTO serialize_test ( + id, description, ewkt, serialized + ) VALUES ( + 9, 'Compound Curve 3dm, SRID=4326', + 'SRID=4326;COMPOUNDCURVEM(CIRCULARSTRINGM(0 0 2,1 1 2,1 0 2),(1 0 2,0 1 2))', + '0109000060E610000002000000010800004003000000000000000000000000000000000000000000000000000040000000000000F03F000000000000F03F0000000000000040000000000000F03F00000000000000000000000000000040010200004002000000000000000000F03F000000000000000000000000000000400000000000000000000000000000F03F0000000000000040'); +INSERT INTO serialize_test ( + id, description, ewkt, serialized + ) VALUES ( + 10, 'Compound Curve 4d, SRID=4326', + 'SRID=4326;COMPOUNDCURVE(CIRCULARSTRING(0 0 2 5,1 1 2 5,1 0 2 5),(1 0 2 5,0 1 2 2))', + '01090000E0E61000000200000001080000C0030000000000000000000000000000000000000000000000000000400000000000001440000000000000F03F000000000000F03F00000000000000400000000000001440000000000000F03F00000000000000000000000000000040000000000000144001020000C002000000000000000000F03F0000000000000000000000000000004000000000000014400000000000000000000000000000F03F00000000000000400000000000000040'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 11, 'Curve Polygon', + 'CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0))', + '010A0000000200000001080000000700000000000000000000C00000000000000000000000000000F0BF000000000000F0BF00000000000000000000000000000000000000000000F03F000000000000F0BF000000000000004000000000000000000000000000000000000000000000004000000000000000C00000000000000000010200000005000000000000000000F0BF00000000000000000000000000000000000000000000E03F000000000000F03F00000000000000000000000000000000000000000000F03F000000000000F0BF0000000000000000'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 12, 'Curve Polygon, SRID=4326', + 'SRID=4326;CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0))', + '010A000020E61000000200000001080000000700000000000000000000C00000000000000000000000000000F0BF000000000000F0BF00000000000000000000000000000000000000000000F03F000000000000F0BF000000000000004000000000000000000000000000000000000000000000004000000000000000C00000000000000000010200000005000000000000000000F0BF00000000000000000000000000000000000000000000E03F000000000000F03F00000000000000000000000000000000000000000000F03F000000000000F0BF0000000000000000'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 13, 'Curve Polygon 3dz, SRID=4326', + 'SRID=4326;CURVEPOLYGON(CIRCULARSTRING(-2 0 0,-1 -1 1,0 0 2,1 -1 3,2 0 4,0 2 2,-2 0 0),(-1 0 1,0 0.5 2,1 0 3,0 1 3,-1 0 1))', + '010A0000A0E61000000200000001080000800700000000000000000000C000000000000000000000000000000000000000000000F0BF000000000000F0BF000000000000F03F000000000000000000000000000000000000000000000040000000000000F03F000000000000F0BF000000000000084000000000000000400000000000000000000000000000104000000000000000000000000000000040000000000000004000000000000000C000000000000000000000000000000000010200008005000000000000000000F0BF0000000000000000000000000000F03F0000000000000000000000000000E03F0000000000000040000000000000F03F000000000000000000000000000008400000000000000000000000000000F03F0000000000000840000000000000F0BF0000000000000000000000000000F03F'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 14, 'Curve Polygon 3dm, SRID=4326', + 'SRID=4326;CURVEPOLYGONM(CIRCULARSTRINGM(-2 0 0,-1 -1 2,0 0 4,1 -1 6,2 0 8,0 2 4,-2 0 0),(-1 0 2,0 0.5 4,1 0 6,0 1 4,-1 0 2))', + '010A000060E61000000200000001080000400700000000000000000000C000000000000000000000000000000000000000000000F0BF000000000000F0BF0000000000000040000000000000000000000000000000000000000000001040000000000000F03F000000000000F0BF000000000000184000000000000000400000000000000000000000000000204000000000000000000000000000000040000000000000104000000000000000C000000000000000000000000000000000010200004005000000000000000000F0BF000000000000000000000000000000400000000000000000000000000000E03F0000000000001040000000000000F03F000000000000000000000000000018400000000000000000000000000000F03F0000000000001040000000000000F0BF00000000000000000000000000000040'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 15, 'Curve Polygon 4d, SRID=4326', + 'SRID=4326;CURVEPOLYGON(CIRCULARSTRING(-2 0 0 0,-1 -1 1 2,0 0 2 4,1 -1 3 6,2 0 4 8,0 2 2 4,-2 0 0 0),(-1 0 1 2,0 0.5 2 4,1 0 3 6,0 1 3 4,-1 0 1 2))', + '010A0000E0E61000000200000001080000C00700000000000000000000C0000000000000000000000000000000000000000000000000000000000000F0BF000000000000F0BF000000000000F03F00000000000000400000000000000000000000000000000000000000000000400000000000001040000000000000F03F000000000000F0BF000000000000084000000000000018400000000000000040000000000000000000000000000010400000000000002040000000000000000000000000000000400000000000000040000000000000104000000000000000C000000000000000000000000000000000000000000000000001020000C005000000000000000000F0BF0000000000000000000000000000F03F00000000000000400000000000000000000000000000E03F00000000000000400000000000001040000000000000F03F0000000000000000000000000000084000000000000018400000000000000000000000000000F03F00000000000008400000000000001040000000000000F0BF0000000000000000000000000000F03F0000000000000040'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 16, 'Multi Curve', + 'MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2))', + '010B0000000200000001020000000400000000000000000014400000000000001440000000000000084000000000000014400000000000000840000000000000084000000000000000000000000000000840010800000003000000000000000000000000000000000000000000000000000040000000000000F03F00000000000000400000000000000040'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 17, 'Multi Curve, SRID=4326', + 'SRID=4326;MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2))', + '010B000020E61000000200000001020000000400000000000000000014400000000000001440000000000000084000000000000014400000000000000840000000000000084000000000000000000000000000000840010800000003000000000000000000000000000000000000000000000000000040000000000000F03F00000000000000400000000000000040'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 18, 'Multi Curve 3dz, SRID=4326', + 'SRID=4326;MULTICURVE((5 5 1,3 5 2,3 3 3,0 3 1),CIRCULARSTRING(0 0 0,2 1 3,2 2 1))', + '010B0000A0E61000000200000001020000800400000000000000000014400000000000001440000000000000F03F00000000000008400000000000001440000000000000004000000000000008400000000000000840000000000000084000000000000000000000000000000840000000000000F03F0108000080030000000000000000000000000000000000000000000000000000000000000000000040000000000000F03F000000000000084000000000000000400000000000000040000000000000F03F'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 19, 'Multi Curve 3dm, SRID=4326', + 'SRID=4326;MULTICURVEM((5 5 3,3 5 2,3 3 1,0 3 1),CIRCULARSTRINGM(0 0 0,2 1 -2,2 2 2))', + '010B000060E61000000200000001020000400400000000000000000014400000000000001440000000000000084000000000000008400000000000001440000000000000004000000000000008400000000000000840000000000000F03F00000000000000000000000000000840000000000000F03F0108000040030000000000000000000000000000000000000000000000000000000000000000000040000000000000F03F00000000000000C0000000000000004000000000000000400000000000000040'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 20, 'Multi Curve 4d, SRID=4326', + 'SRID=4326;MULTICURVE((5 5 1 3,3 5 2 2,3 3 3 1,0 3 1 1),CIRCULARSTRING(0 0 0 0,2 1 3 -2,2 2 1 2))', + '010B0000E0E61000000200000001020000C00400000000000000000014400000000000001440000000000000F03F00000000000008400000000000000840000000000000144000000000000000400000000000000040000000000000084000000000000008400000000000000840000000000000F03F00000000000000000000000000000840000000000000F03F000000000000F03F01080000C00300000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000F03F000000000000084000000000000000C000000000000000400000000000000040000000000000F03F0000000000000040'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 21, 'Multi Surface', + 'MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)),((7 8,10 10,6 14,4 11,7 8)))', + '010C00000002000000010A0000000200000001080000000700000000000000000000C00000000000000000000000000000F0BF000000000000F0BF00000000000000000000000000000000000000000000F03F000000000000F0BF000000000000004000000000000000000000000000000000000000000000004000000000000000C00000000000000000010200000005000000000000000000F0BF00000000000000000000000000000000000000000000E03F000000000000F03F00000000000000000000000000000000000000000000F03F000000000000F0BF0000000000000000010300000001000000050000000000000000001C4000000000000020400000000000002440000000000000244000000000000018400000000000002C40000000000000104000000000000026400000000000001C400000000000002040'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 22, 'Multi Surface, SRID=4326', + 'SRID=4326;MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)),((7 8,10 10,6 14,4 11,7 8)))', + '010C000020E610000002000000010A0000000200000001080000000700000000000000000000C00000000000000000000000000000F0BF000000000000F0BF00000000000000000000000000000000000000000000F03F000000000000F0BF000000000000004000000000000000000000000000000000000000000000004000000000000000C00000000000000000010200000005000000000000000000F0BF00000000000000000000000000000000000000000000E03F000000000000F03F00000000000000000000000000000000000000000000F03F000000000000F0BF0000000000000000010300000001000000050000000000000000001C4000000000000020400000000000002440000000000000244000000000000018400000000000002C40000000000000104000000000000026400000000000001C400000000000002040'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 23, 'Multi Surface 3dz, SRID=4326', + 'SRID=4326;MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0 0,-1 -1 1,0 0 2,1 -1 3,2 0 4,0 2 2,-2 0 0),(-1 0 1,0 0.5 2,1 0 3,0 1 3,-1 0 1)),((7 8 7,10 10 5,6 14 3,4 11 4,7 8 7)))', + '010C0000A0E610000002000000010A0000800200000001080000800700000000000000000000C000000000000000000000000000000000000000000000F0BF000000000000F0BF000000000000F03F000000000000000000000000000000000000000000000040000000000000F03F000000000000F0BF000000000000084000000000000000400000000000000000000000000000104000000000000000000000000000000040000000000000004000000000000000C000000000000000000000000000000000010200008005000000000000000000F0BF0000000000000000000000000000F03F0000000000000000000000000000E03F0000000000000040000000000000F03F000000000000000000000000000008400000000000000000000000000000F03F0000000000000840000000000000F0BF0000000000000000000000000000F03F010300008001000000050000000000000000001C4000000000000020400000000000001C4000000000000024400000000000002440000000000000144000000000000018400000000000002C4000000000000008400000000000001040000000000000264000000000000010400000000000001C4000000000000020400000000000001C40'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 24, 'Multi Surface 3dm, SRID=4326', + 'SRID=4326;MULTISURFACEM(CURVEPOLYGONM(CIRCULARSTRINGM(-2 0 0,-1 -1 2,0 0 4,1 -1 6,2 0 8,0 2 4,-2 0 0),(-1 0 2,0 0.5 4,1 0 6,0 1 4,-1 0 2)),((7 8 8,10 10 5,6 14 1,4 11 6,7 8 8)))', + '010C000060E610000002000000010A0000400200000001080000400700000000000000000000C000000000000000000000000000000000000000000000F0BF000000000000F0BF0000000000000040000000000000000000000000000000000000000000001040000000000000F03F000000000000F0BF000000000000184000000000000000400000000000000000000000000000204000000000000000000000000000000040000000000000104000000000000000C000000000000000000000000000000000010200004005000000000000000000F0BF000000000000000000000000000000400000000000000000000000000000E03F0000000000001040000000000000F03F000000000000000000000000000018400000000000000000000000000000F03F0000000000001040000000000000F0BF00000000000000000000000000000040010300004001000000050000000000000000001C400000000000002040000000000000204000000000000024400000000000002440000000000000144000000000000018400000000000002C40000000000000F03F0000000000001040000000000000264000000000000018400000000000001C4000000000000020400000000000002040'); +INSERT INTO serialize_test( + id, description, ewkt, serialized + ) VALUES ( + 25, 'Multi Surface 4d, SRID=4326', + 'SRID=4326;MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0 0 0,-1 -1 1 2,0 0 2 4,1 -1 3 6,2 0 4 8,0 2 2 4,-2 0 0 0),(-1 0 1 2,0 0.5 2 4,1 0 3 6,0 1 3 4,-1 0 1 2)),((7 8 7 8,10 10 5 5,6 14 3 1,4 11 4 6,7 8 7 8)))', + '010C0000E0E610000002000000010A0000C00200000001080000C00700000000000000000000C0000000000000000000000000000000000000000000000000000000000000F0BF000000000000F0BF000000000000F03F00000000000000400000000000000000000000000000000000000000000000400000000000001040000000000000F03F000000000000F0BF000000000000084000000000000018400000000000000040000000000000000000000000000010400000000000002040000000000000000000000000000000400000000000000040000000000000104000000000000000C000000000000000000000000000000000000000000000000001020000C005000000000000000000F0BF0000000000000000000000000000F03F00000000000000400000000000000000000000000000E03F00000000000000400000000000001040000000000000F03F0000000000000000000000000000084000000000000018400000000000000000000000000000F03F00000000000008400000000000001040000000000000F0BF0000000000000000000000000000F03F000000000000004001030000C001000000050000000000000000001C4000000000000020400000000000001C400000000000002040000000000000244000000000000024400000000000001440000000000000144000000000000018400000000000002C400000000000000840000000000000F03F00000000000010400000000000002640000000000000104000000000000018400000000000001C4000000000000020400000000000001C400000000000002040'); + + + +SELECT id, CASE WHEN ewkt = ST_asEWKT(serialized::geometry) THEN 'pass' ELSE 'fail' END AS result FROM serialize_test ORDER BY id; +SELECT id, CASE WHEN ST_asEWKB(geomFromEWKT(ewkt)) = serialized THEN 'pass' ELSE 'fail' END AS result FROM serialize_test ORDER BY id; + +DROP TABLE serialize_test;