Sql-Server-2008
將空間點數據轉換為線數據,以便在 SQL Server Reporting Services (SSRS) 的線圖層中使用
我有一個返回欄位的查詢
Order, Lat, Long, SpatialData, <OtherStuff>
。SpatialData
是一個點。我想創建一個線層,根據訂單欄位在我的點之間繪製線。
根據http://technet.microsoft.com/en-us/library/ee240828.aspx#LineLayer我需要做這樣的事情:
SELECT N'Path' AS Name , CAST( 'LINESTRING( -76.5001866085881 42.4310489934743, -76.4602850815536 43.4353224527794, -73.4728622833178 44.7028831413324)' AS geography) as Route
但是我如何從我的數據變成這樣的東西呢?
下面是一種簡單的單查詢方法,可以在一個查詢中將它作為一個小 2 點線段的列表,而不使用游標。如果您使用游標和 .STUnion 方法以及點空間數據欄位在另一個表中建構和儲存您的行,則可以做更多的事情。
假設和變化: 1. 包括城市和州。2. 為了更真實,我將 lat 和 long 儲存為 decimal(10,7),因此,不幸的是,這個範例將 lat 和 long 轉換回 varchar 以建構 Well Known Text (WKT) 行。3. 我將 order 重命名為 ptorder,因為 order 是保留字。4. 源數據表中只有一條路徑或一條線,不在路徑上的城市有一個NULL ptorder。5. ptorder 是一個沒有間隙的序列,否則查詢會變得複雜得多。6. 我避免使用游標。7. 我假設您的數據如下所示:
5, 42.37, -71.03, 'Boston', 'MA' 3, 39.75, -104.87, 'Denver', 'CO' 2, 33.93, -118.40, 'Los Angeles', 'CA' 4, 25.82, -80.28, 'Miami Intl', 'FL' NULL, 40.77, -73.98, 'New York', 'NY' 1, 33.43, -112.02, 'Phoenix', 'AZ'
像這樣載入一些測試數據:
CREATE TABLE pointdatatable ( ptorder INT, lat DECIMAL(10,7), long DECIMAL(10,7), pointspatialdata GEOGRAPHY, city VARCHAR(20), state CHAR(2) ) INSERT INTO pointdatatable (ptorder, lat, long, pointspatialdata, city, state) VALUES (5, 42.37, -71.03, CAST('POINT(-71.03 42.37)' AS GEOGRAPHY), 'Boston', 'MA'), (3, 39.75, -104.87, CAST('POINT(-104.87 39.75)' AS GEOGRAPHY), 'Denver', 'CO'), (2, 33.93, -118.40, CAST('POINT(-118.40 33.93)' AS GEOGRAPHY), 'Los Angeles', 'CA'), (4, 25.82, -80.28, CAST('POINT(-80.28 25.82)' AS GEOGRAPHY), 'Miami Intl', 'FL'), (NULL, 40.77, -73.98, CAST('POINT(-73.98 40.77)' AS GEOGRAPHY), 'New York', 'NY'), (1, 33.43, -112.02, CAST('POINT(-112.02 33.43)' AS GEOGRAPHY), 'Phoenix', 'AZ')
然後此查詢使用 WKT 生成段:
SELECT a.ptorder, a.lat, a.long, a.city, b.ptorder, b.lat, b.long, b.city AS nextcity, CAST('LINESTRING(' + CAST(a.long AS VARCHAR) +' '+ CAST(a.lat AS VARCHAR) +', '+ CAST(b.long AS VARCHAR) +' '+ CAST(b.lat AS VARCHAR) + ')' AS GEOGRAPHY) AS segmentspatialdata FROM pointdatatable a LEFT OUTER JOIN pointdatatable b ON b.ptorder = a.ptorder + 1 WHERE b.ptorder IS NOT NULL ORDER BY a.ptorder