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開始 字元位置 字元在串中的序...
資料結構基礎知識的理解(演算法和演算法分析)
演算法是為了解決某類問題而規定的乙個有限長的操作序列,簡而言之,演算法就是解決問題的方法和步驟。程式使用某種程式語言對演算法的具體實現。程式 資料結構 演算法,資料結構通過演算法實現操作,演算法根據資料結構設計程式。乙個演算法必須有五個重要特性 有窮性,確定性,可行性,輸入,輸出。評價演算法優劣的基...