Skip to content

Commit 40e28bc

Browse files
committed
initial
1 parent 9619bd3 commit 40e28bc

File tree

4 files changed

+285
-0
lines changed

4 files changed

+285
-0
lines changed

RUcut.zip

3.15 MB
Binary file not shown.

SpatialIndex_DataParser.xml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2015.3 (Build 215U)" ts="2015-09-18 03:21:40">
3+
<Class name="SpatialIndex.DataParser">
4+
<Super>%RegisteredObject</Super>
5+
<TimeChanged>63813,11950.513682</TimeChanged>
6+
<TimeCreated>63813,11943.491744</TimeCreated>
7+
8+
<Parameter name="fileName">
9+
<Default>E:\InterSystems\GeoNames\allCountries\allCountries.txt</Default>
10+
</Parameter>
11+
12+
<Method name="ParseCountryFromFile">
13+
<ClassMethod>1</ClassMethod>
14+
<ReturnType>%Status</ReturnType>
15+
<Implementation><![CDATA[
16+
kill ^tmp
17+
set st = $$$OK
18+
//Set filename = "C:\My Documents\geoname\RU\cut.txt"
19+
Set filename = "E:\InterSystems\GeoNames\allCountries\allCountries.txt"
20+
Set stream=##class(%FileCharacterStream).%New()
21+
Set stream.Filename=filename
22+
set indexer = ##class(SpatialIndex.Indexer).%New("^tmp(1)")
23+
set i=0
24+
set start=$ZHOROLOG
25+
WHILE i<90000 {
26+
Set line=stream.ReadLine()
27+
If $Length(line) > 0 {
28+
set columnList = $ListFromString(line," ")
29+
30+
/*
31+
for k=1:1:$LL(columnList)
32+
{
33+
w i_"-"_k_"............"_$List(columnList,k) ,!
34+
}
35+
*/
36+
37+
set x=$List(columnList,5)
38+
set y=$List(columnList,6)
39+
set id=$List(columnList,1)
40+
set data=$List(columnList,2)
41+
do indexer.Insert(x, y, id, data)
42+
}
43+
if i#1000=0 write "."
44+
if i#50000=0 write !
45+
set i=i+1
46+
}
47+
set finish=$ZHOROLOG
48+
49+
write !,"Success "_(finish-start) ,!
50+
return st
51+
]]></Implementation>
52+
</Method>
53+
54+
<Method name="GetFirstGlobLength">
55+
<ClassMethod>1</ClassMethod>
56+
<ReturnType>%Status</ReturnType>
57+
<Implementation><![CDATA[
58+
set x = $order(^tmp(1,""))
59+
set l=0
60+
while (x'=""){
61+
if ($LENGTH(x)>l) set l=$LENGTH(x)
62+
set x = $order(^tmp(1,x))
63+
}
64+
write l
65+
]]></Implementation>
66+
</Method>
67+
</Class>
68+
</Export>

SpatialIndex_IndexNode.xml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2015.3 (Build 215U)" ts="2015-09-18 03:21:40">
3+
<Class name="SpatialIndex.IndexNode">
4+
<Super>%RegisteredObject</Super>
5+
<TimeChanged>63813,11306.782214</TimeChanged>
6+
<TimeCreated>63813,4798.778276</TimeCreated>
7+
8+
<Property name="isLeaf">
9+
<Type>%Boolean</Type>
10+
</Property>
11+
12+
<Property name="minX">
13+
<Type>%Float</Type>
14+
</Property>
15+
16+
<Property name="minY">
17+
<Type>%Float</Type>
18+
</Property>
19+
20+
<Property name="maxX">
21+
<Type>%Float</Type>
22+
</Property>
23+
24+
<Property name="maxY">
25+
<Type>%Float</Type>
26+
</Property>
27+
28+
<Property name="size">
29+
<Type>%Integer</Type>
30+
</Property>
31+
32+
<Method name="%OnNew">
33+
<FormalSpec>minX,minY,maxX,maxY,isLeaf=$$$YES,size=0</FormalSpec>
34+
<ReturnType>%Status</ReturnType>
35+
<Implementation><![CDATA[
36+
set ..isLeaf = isLeaf
37+
set ..minX = minX
38+
set ..maxX = maxX
39+
set ..minY = minY
40+
set ..maxY = maxY
41+
set i%size = size
42+
Quit $$$OK
43+
]]></Implementation>
44+
</Method>
45+
46+
<Method name="Exists">
47+
<ClassMethod>1</ClassMethod>
48+
<FormalSpec>indexGlobal:%String,nodePath:%String</FormalSpec>
49+
<ReturnType>%Boolean</ReturnType>
50+
<Implementation><![CDATA[ return $DATA(@indexGlobal@(nodePath))>0
51+
]]></Implementation>
52+
</Method>
53+
54+
<Method name="Get">
55+
<ClassMethod>1</ClassMethod>
56+
<FormalSpec>indexGlobal:%String,nodePath:%String</FormalSpec>
57+
<ReturnType>SpatialIndex.IndexNode</ReturnType>
58+
<Implementation><![CDATA[
59+
s l = @indexGlobal@(nodePath)
60+
s $lb(minX,minY,maxX,maxY,isLeaf,size) = l
61+
/*s minY=@indexGlobal@(nodePath, "minY")
62+
s maxX=@indexGlobal@(nodePath, "maxX")
63+
s maxY=@indexGlobal@(nodePath, "maxY")
64+
s isLeaf=@indexGlobal@(nodePath, "isLeaf")
65+
s size=@indexGlobal@(nodePath, "size")*/
66+
return ..%New(minX,minY,maxX,maxY,isLeaf,size)
67+
]]></Implementation>
68+
</Method>
69+
70+
<Method name="Put">
71+
<ClassMethod>1</ClassMethod>
72+
<FormalSpec>indexGlobal:%String,nodePath:%String,node:SpatialIndex.IndexNode</FormalSpec>
73+
<Implementation><![CDATA[
74+
s @indexGlobal@(nodePath) = $lb(node.minX,node.minY,node.maxX,node.maxY,node.isLeaf,node.size)
75+
/*set @indexGlobal@(nodePath, "minX") = node.minX
76+
set @indexGlobal@(nodePath, "minY") = node.minY
77+
set @indexGlobal@(nodePath, "maxX") = node.maxX
78+
set @indexGlobal@(nodePath, "maxY") = node.maxY
79+
set @indexGlobal@(nodePath, "isLeaf") = node.isLeaf
80+
set @indexGlobal@(nodePath, "size") = node.size*/
81+
]]></Implementation>
82+
</Method>
83+
</Class>
84+
</Export>

SpatialIndex_Indexer.xml

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2015.3 (Build 215U)" ts="2015-09-18 03:21:40">
3+
<Class name="SpatialIndex.Indexer">
4+
<Super>%RegisteredObject</Super>
5+
<TimeChanged>63813,10285.724655</TimeChanged>
6+
<TimeCreated>63813,4756.736455</TimeCreated>
7+
8+
<Parameter name="NODESIZE">
9+
<Default>4</Default>
10+
</Parameter>
11+
12+
<Parameter name="ROOTNODE">
13+
<Default> </Default>
14+
</Parameter>
15+
16+
<Parameter name="EPS">
17+
<Default>0.0001</Default>
18+
</Parameter>
19+
20+
<Parameter name="MINX">
21+
<Default>-180</Default>
22+
</Parameter>
23+
24+
<Parameter name="MINY">
25+
<Default>-90</Default>
26+
</Parameter>
27+
28+
<Parameter name="MAXX">
29+
<Expression>180 + ..#EPS</Expression>
30+
</Parameter>
31+
32+
<Parameter name="MAXY">
33+
<Expression>90 + ..#EPS</Expression>
34+
</Parameter>
35+
36+
<Property name="indexPath">
37+
<Type>%String</Type>
38+
<Private>1</Private>
39+
</Property>
40+
41+
<Method name="%OnNew">
42+
<FormalSpec>indexPath:%String</FormalSpec>
43+
<ReturnType>%Status</ReturnType>
44+
<Implementation><![CDATA[
45+
set ..indexPath = indexPath
46+
if ('##class(IndexNode).Exists(indexPath, ..#ROOTNODE)){
47+
do ##class(IndexNode).Put(indexPath, ..#ROOTNODE,
48+
{"isLeaf":$$$YES, "minX":..#MINX, "maxX":..#MAXX, "minY":..#MINY, "maxY":..#MAXY, "size":0})
49+
}
50+
return $$$OK
51+
]]></Implementation>
52+
</Method>
53+
54+
<Method name="Insert">
55+
<FormalSpec>x:%Float,y:%Float,id:%String,data:%String="",block:%String=..#ROOTNODE</FormalSpec>
56+
<Implementation><![CDATA[
57+
#dim node As IndexNode
58+
set node = ##class(IndexNode).Get(..indexPath, block)
59+
if ((x<node.minX) || (x>=node.maxX) || (y<node.minY) || (y>=node.maxY)) return
60+
if (node.isLeaf){
61+
if ('..Contains(x, y, block)) {
62+
set node.size = node.size + 1
63+
do ##class(IndexNode).Put(..indexPath, block, node)
64+
}
65+
set @..indexPath@(block, "data", x, y, id) = data
66+
if (node.size > ..#NODESIZE) do ..Split(block)
67+
}
68+
else{
69+
for i=0:1:3 {
70+
do ..Insert(x, y, id, data, block_i)
71+
}
72+
}
73+
]]></Implementation>
74+
</Method>
75+
76+
<Method name="Contains">
77+
<FormalSpec>x:%Float,y:%Float,block:%String=..#ROOTNODE</FormalSpec>
78+
<ReturnType>%Boolean</ReturnType>
79+
<Implementation><![CDATA[
80+
#dim node As IndexNode
81+
set node = ##class(IndexNode).Get(..indexPath, block)
82+
if ((x<node.minX) || (x>=node.maxX) || (y<node.minY) || (y>=node.maxY)) return $$$NO
83+
if (node.isLeaf){
84+
return $DATA(@..indexPath@(block, "data", x, y))>0
85+
}
86+
for i=0:1:3 {
87+
if (..Contains(x, y, block_i)) return $$$YES
88+
}
89+
return $$$NO
90+
]]></Implementation>
91+
</Method>
92+
93+
<Method name="Split">
94+
<FormalSpec>block:%String</FormalSpec>
95+
<Implementation><![CDATA[
96+
#dim node As IndexNode
97+
set node = ##class(IndexNode).Get(..indexPath, block)
98+
set midX = (node.minX+node.maxX)/2
99+
set midY = (node.minY+node.maxY)/2
100+
101+
// Create subnodes
102+
set nodes(0) = ##class(IndexNode).%New(node.minX, node.minY, midX, midY)
103+
set nodes(1) = ##class(IndexNode).%New(midX, node.minY, node.maxX, midY)
104+
set nodes(2) = ##class(IndexNode).%New(node.minX, midY, midX, node.maxY)
105+
set nodes(3) = ##class(IndexNode).%New(midX, midY, node.maxX, node.maxY)
106+
107+
// Saving structure
108+
set node.isLeaf = $$$NO
109+
set node.size = 0
110+
do ##class(IndexNode).Put(..indexPath, block, node)
111+
for i=0:1:3 {
112+
do ##class(IndexNode).Put(..indexPath, block_i, nodes(i))
113+
}
114+
115+
// Reinsert data into node. Since it's not leaf, data will be inserted in subnodes
116+
set x = $o(@..indexPath@(block, "data", ""))
117+
while (x'=""){
118+
set y = $o(@..indexPath@(block, "data", x, ""))
119+
while (y'=""){
120+
set id = $o(@..indexPath@(block, "data", x, y, ""))
121+
while (id'=""){
122+
do ..Insert(x, y, id, @..indexPath@(block, "data", x, y, id), block)
123+
set id = $o(@..indexPath@(block, "data", x, y, id))
124+
}
125+
set y = $o(@..indexPath@(block, "data", x, y))
126+
}
127+
set x = $o(@..indexPath@(block, "data", x))
128+
}
129+
kill @..indexPath@(block, "data")
130+
]]></Implementation>
131+
</Method>
132+
</Class>
133+
</Export>

0 commit comments

Comments
 (0)