無先驗知識的GIS資料抓取演算法研究

2021-08-19 01:16:44 字數 3389 閱讀 3012

arcgis server將gis空間庫中的資料可以以服務的方式發布出來,服務中提供了查詢介面,可以將關心的字段等內容返回給我們,也可以選擇將所有的資料返回回來。其中有乙個小問題:服務端預設是返回查詢記錄的1000條記錄。在預設情況下,如果查詢記錄大於1000,那麼就會丟失剩餘的查詢資料,通常有兩種解決辦法:

修改服務端的預設返回值,可以修改為大於1000的資料,如2000、2500……

設計乙個簡單的演算法,分段進行檢索,因為返回結果中的編號id通常是從1開始,在查詢條件中設定為id每1000會返回一次,這樣就可以乙個不剩的獲取所有資料

id不是從0開始編號

返回結果的個數(即id個數)遠大於1000,服務端無法事先指定(指定太多可能導致返回超時)

不知返回結果中id的起止,相鄰id也可能不是連續,例如:4, 7, 15, 29, 765 …

返回結果的id分布也不清楚,有可能(2000, 5000)比(6000, 10000)分布的資料更多

正是上面條件的限制,給資料的批量抓取帶來了新的問題和挑戰。

問題的解決應該分為兩步:

第一步:通過探查法獲取id的大致範圍,這個探查不需要獲取準確範圍,同時探測時只關心id的字段,其他字段不必關心(這樣可以減小請求次數,以及請求的內容大小,從而減少處理時間)

第二步:精確獲取所有的目標結果,此時不能遺漏結果,以及各個欄位的值

演算法的思路用一句話概括起來:跨數量級,兩邊逼近

我們的目標是獲得最小id和最大id所在的數量級,前面提到的「大致範圍」就體現在這裡的「所在的數量級」上,之所有採用跨數量級是因為第一步只是初步獲取乙個範圍,時間是放在第一位的,沒有必要非要提取出準確的最大最小id值(與其將時間花費在求取準確的最大最小id上還不如花費在後面的準確抓取上)。

兩邊逼近說的是最小id從個位數開始往大的方向茶皂,最大id從乙個足夠大的數(例如1億、10億)往小的方向查詢。

查詢過程中需要注意如何判斷是否找到最大最小id值。廢話不多說,看下面**:

def estimate_interval(self):

# 估計id最大最小值所在區間

self.estimate_lower()

self.estimate_upper()

if self.lower >= self.upper:

return [false, 'self.lower >= self.upper']

else:

# 區間入棧

self.interval_stack.push([self.lower, self.upper])

return [true, 'succeed']

def estimate_upper(self):

# 確定最大id所在數量級

upper = self.iter_estimate_upper(self.max_value)

self.upper = upper

def iter_estimate_upper(self, max_value):

# 迭代確定最大id所在數量級

feature_num = self.stat_feature_num(max_value/10, max_value)

if feature_num > 0:

return max_value-1

else:

return self.iter_estimate_upper(max_value/10)

def estimate_lower(self):

# 確定最小id所在數量級

lower = self.iter_estimate_lower(1)

self.lower = lower

def iter_estimate_lower(self, min_value):

# 迭代確定最小id所在數量級

feature_num = self.stat_feature_num(min_value, min_value * 10)

if feature_num > 0:

return min_value

else:

return self.iter_estimate_lower(min_value * 10)

精確抓時,採用了二分法,用stack訪問所有區間,以及遞迴呼叫,**如下:

def fetch_features(self):

if self.interval_stack.size() < 1:

return

# 分批抓取features

[id_lower, id_upper] = self.interval_stack.pop()

print '** fetch_features() [id_lower, id_upper]=[', id_lower, ', ', id_upper, '], size=', self.interval_stack.size()

if id_upper - id_lower <= self.batch_size:

# 直接查詢、抓取入庫

self.fetch_export_togdb(id_lower, id_upper)

self.fetch_features() # 繼續迭代

else:

# 探查[lower, upper)對應的feature個數

feature_num = self.stat_feature_num(id_lower, id_upper)

if feature_num < self.batch_size:

# 直接查詢、抓取入庫

self.fetch_export_togdb(id_lower, id_upper)

self.fetch_features() # 繼續迭代

else:

# 折半探查

id_middle = (int)(id_lower + id_upper)/2

self.interval_stack.push([id_middle, id_upper])

self.interval_stack.push([id_lower, id_middle])

self.fetch_features() # 繼續迭代

資料結構的基本知識 演算法

下面的都是摘自 大話資料結構 書中的內容,記下來可以時時檢視 資料 描述客觀事物的符號,計算機可以操作的物件 資料元素 組成資料的有一定意義的基本單位,作為整體能被計算機處理 人是人類的資料元素,牛馬是牲畜類的資料元素 資料項 組成資料元素,人的眼睛耳朵就是人這個資料元素的資料項 注意 資料項是資料...

資料結構 串的知識總結,BF,KMP演算法

常見基礎概念 串長 串中字元個數,有時還常用a 0 length來儲存串長 注意空串和空格串的區別 空串是長度為0的串,而空格串是由多個或乙個空格字元組成的字串 子串與主串 串s中任意個連續字串行叫s的子串,s稱為主串 子串位置 子串的第乙個字元在主串中的序號 序號從1開始 字元位置 字元在串中的序...

資料結構基礎知識的理解(演算法和演算法分析)

演算法是為了解決某類問題而規定的乙個有限長的操作序列,簡而言之,演算法就是解決問題的方法和步驟。程式使用某種程式語言對演算法的具體實現。程式 資料結構 演算法,資料結構通過演算法實現操作,演算法根據資料結構設計程式。乙個演算法必須有五個重要特性 有窮性,確定性,可行性,輸入,輸出。評價演算法優劣的基...