Skip to content
This repository was archived by the owner on Sep 9, 2020. It is now read-only.

Commit fef1823

Browse files
committed
Merge branch 'develop'
2 parents ae9ed5c + 338f71c commit fef1823

9 files changed

+139
-43
lines changed

.gitignore

+6-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,9 @@ MANIFEST
77
*.tar.*
88
build
99
dist
10-
hex_utils/__pycache__
10+
hex_utils/__pycache__
11+
movies
12+
data
13+
docs
14+
tests
15+
helpers

.pydevproject

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<?eclipse-pydev version="1.0"?><pydev_project>
33
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
44
<path>/${PROJECT_DIR_NAME}</path>
5+
<path>/${PROJECT_DIR_NAME}/helpers</path>
56
</pydev_pathproperty>
67
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 3.0</pydev_property>
78
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>

hex_utils/asc.py

+73-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
#
1111
# [0] http://resources.esri.com/help/9.3/arcgisengine/java/GP_ToolRef/spatial_analyst_tools/esri_ascii_raster_format.htm
1212

13-
import math
13+
import sys, math
14+
from scipy import interpolate
1415
from hex_utils.grid import Grid
1516

1617
class ASC (Grid):
@@ -42,7 +43,7 @@ def init(self, ncols, nrows, xll, yll, size, nodata = ""):
4243
self._set_size(size)
4344

4445

45-
def getNearestNeighbour(self, x, y):
46+
def _getNearestNeighbourGridCoords(self, x, y):
4647

4748
if x < self._xll:
4849
x = self._xll
@@ -58,14 +59,84 @@ def getNearestNeighbour(self, x, y):
5859

5960
i = math.trunc((x - self._xll) / self._size)
6061
j = self._nrows - 1 - math.trunc((y - self._yll) / self._size)
62+
63+
return i, j
64+
65+
66+
def getNearestNeighbour(self, x, y):
67+
68+
i, j = self._getNearestNeighbourGridCoords(x, y)
6169

6270
try:
6371
return self._grid[i][j]
6472
except IndexError:
6573
raise IndexError("Wrong indexes in nearest neighbour:" +
6674
"i: " + str(i) + " j: " + str(j) + " x: " + str(x) + " y: " + str(y))
75+
76+
77+
def _getNeighbourhoodGridCoords(self, i, j):
78+
79+
ii = []
80+
jj = []
81+
82+
if i > 0:
83+
84+
if j > 0:
85+
ii.append(i-1)
86+
jj.append(j-1)
87+
88+
ii.append(i-1)
89+
jj.append(j)
90+
91+
if j < self.nrows - 1:
92+
ii.append(i-1)
93+
jj.append(j+1)
94+
95+
if j > 0:
96+
ii.append(i)
97+
jj.append(j-1)
98+
99+
ii.append(i)
100+
jj.append(j)
101+
102+
if j < self.nrows - 1:
103+
ii.append(i)
104+
jj.append(j+1)
105+
106+
if i < self.ncols - 1:
107+
108+
if j > 0:
109+
ii.append(i+1)
110+
jj.append(j-1)
111+
112+
ii.append(i+1)
113+
jj.append(j)
114+
115+
if j < self.nrows - 1:
116+
ii.append(i+1)
117+
jj.append(j+1)
118+
119+
return ii, jj
120+
67121

122+
def interpolMultiquadratic(self, x, y, epsilon=100):
123+
124+
xx = []
125+
yy = []
126+
vals = []
127+
i, j = self._getNearestNeighbourGridCoords(x, y)
128+
ii, jj = self._getNeighbourhoodGridCoords(i, j)
129+
130+
for n in range(len(ii)):
131+
if ii[n] != None and jj[n] != None and self._grid[ii[n]][jj[n]] != None:
132+
xx.append(self._xll + ii[n] * self._size + self._size / 2)
133+
yy.append(self._yll + self._nrows * self._size - jj[n] * self._size - self._size / 2)
134+
vals.append(self._grid[ii[n]][jj[n]])
135+
136+
f = interpolate.Rbf(xx, yy, vals, epsilon=epsilon)
137+
return f(x,y)
68138

139+
69140
def _loadHeader(self):
70141

71142
# Mandatory header

hex_utils/asc2hasc.py

+39-31
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
# Transforms rectangular ESRI ASCCI grids into ASCII encoded cartographic
77
# hexagonal grids (HASC) [0]. The resulting hexagonal grid is created with a
88
# spatial resolution similar to the input rectangular grid. The values of the
9-
# resulting hexagonal grid are computed using a simple nearest-neighbour
10-
# algorithm.
9+
# resulting hexagonal grid are computed using a simple nearest-neighbour or
10+
# a multi-quadratic interpolation.
1111
#
1212
# Author: Luís Moreira de Sousa (luis.de.sousa[@]protonmail.ch)
1313
# Date: 31-03-2016
@@ -18,52 +18,55 @@
1818
import math
1919
from hex_utils.asc import ASC
2020
from hex_utils.hasc import HASC
21+
import argparse
22+
from enum import Enum
2123

22-
RES_FACTOR = 1.134
24+
RES_FACTOR = 1.134
2325

24-
def wrongUsage():
25-
26-
print("\nThis programme requires three arguments:\n" +
27-
" - conversion mode \n" +
28-
" - path to an input ESRI ASCII file \n" +
29-
" - path to the output HASC file \n\n" +
30-
"The conversion can be of two types: \n" +
31-
" -a : preserve cell area \n" +
32-
" -r : preserve spatial resolution \n\n" +
33-
"Usage example: \n"
34-
" asc2hasc -r /path/to/input.asc /path/to/output.hasc\n")
35-
sys.exit()
26+
class Method(Enum):
27+
MULTIQUADRATIC = 'mq',
28+
NEAREST_NEIGHBOUR = 'nn'
3629

37-
# This method is the same as in other command line utils
38-
def processArguments(args):
30+
31+
32+
def setArguments():
3933

40-
global inputFile
41-
global outputFile
34+
parser = argparse.ArgumentParser(description='Converts an ESRI ASCII grid into an HexASCII (HASC) grid.')
35+
parser.add_argument("-a", "--area", dest="area", default = 0,
36+
type=float, help="cell area of the output grid" )
37+
parser.add_argument("-r", "--resolution", action='store_true',
38+
help = "preserve original spatial resolution")
39+
parser.add_argument("-m", "--method", default="mq",
40+
help = "Interpolation method: mq - Multiquadratic, nn - Nearest Neighbour")
41+
parser.add_argument("-i", "--input", dest="inputFile", required = True,
42+
help="input ESRI ASCII grid file" )
43+
parser.add_argument("-o", "--output", dest="outputFile", default = "out.hasc",
44+
help="output HexASCII grid file" )
4245

43-
if len(args) < 4 or (str(args[1]) != '-r' and str(args[1]) != '-a'):
44-
wrongUsage()
45-
else:
46-
inputFile = str(args[2])
47-
outputFile = str(args[3])
46+
return parser.parse_args()
47+
4848

4949
# ------------ Main ------------ #
5050
def main():
5151

52-
processArguments(sys.argv)
53-
52+
args = setArguments()
53+
5454
esriGrid = ASC()
5555
try:
56-
esriGrid.loadFromFile(inputFile)
56+
esriGrid.loadFromFile(args.inputFile)
5757
except (ValueError, IOError) as ex:
58-
print("Error loading the grid %s: %s" % (inputFile, ex))
58+
print("Error loading the grid %s: %s" % (args.inputFile, ex))
5959
sys.exit()
6060

6161
esriArea = math.pow(esriGrid.size, 2)
6262
hexArea = 0
6363

6464
# Preserve spatial resolution: increase cell area.
65-
if (sys.argv[1] == '-r'):
65+
if (args.resolution):
6666
hexArea = esriArea * RES_FACTOR
67+
# Use area provided.
68+
elif (args.area > 0):
69+
hexArea = args.area
6770
# Preserve cell area: used the same as the original grid.
6871
else:
6972
hexArea = esriArea
@@ -96,12 +99,17 @@ def main():
9699
hexGrid = HASC()
97100
hexGrid.init(hexCols, hexRows, hexXLL, hexYLL, hexSide, esriGrid.nodata)
98101

102+
if(args.method == Method.MULTIQUADRATIC):
103+
interpol = esriGrid.getNearestNeighbour
104+
else:
105+
interpol = esriGrid.interpolMultiquadratic
106+
99107
for j in range(hexGrid.nrows):
100108
for i in range(hexGrid.ncols):
101109
x, y = hexGrid.getCellCentroidCoords(i, j)
102-
hexGrid.set(i, j, esriGrid.getNearestNeighbour(x, y))
110+
hexGrid.set(i, j, interpol(x, y))
103111

104-
hexGrid.save(outputFile)
112+
hexGrid.save(args.outputFile)
105113

106114
print ("Finished successfully.")
107115

hex_utils/grid.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,10 @@ def _loadLineValues(self, values):
148148
"Expected something in the range [0.." +
149149
str(self._ncols - 1) + ", 0.." + str(self._nrows - 1) + "]")
150150

151-
self._colIdx += 1;
151+
self._colIdx += 1
152152
if self._colIdx >= self._ncols:
153-
self._colIdx = 0;
154-
self._rowIdx += 1;
153+
self._colIdx = 0
154+
self._rowIdx += 1
155155

156156

157157
def _loadValues(self):
@@ -167,7 +167,7 @@ def _loadValues(self):
167167
while (self._nextLine):
168168
self._loadLineValues(self._nextLine.split())
169169
self._nextLine = self._file.readline()
170-
170+
171171

172172
def _saveHeader(self, f):
173173
raise NotImplementedError("Please Implement this method")

requirements.txt

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
cycler==0.10.0
2+
GDAL==2.1.0
3+
hex-utils==0.2
4+
matplotlib==1.5.3
5+
numpy==1.11.1
6+
pkg-resources==0.0.0
7+
pyparsing==2.1.9
8+
python-dateutil==2.5.3
9+
pytz==2016.6.1
10+
scipy==0.18.1
11+
six==1.10.0

setup.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
'console_scripts': [
1313
'hasc2gml=hex_utils.hasc2gml:main',
1414
'asc2hasc=hex_utils.asc2hasc:main',
15-
'asc2hasc=hex_utils.surface2hasc:main',
16-
'asc2hasc=hex_utils.surface2asc:main'
15+
'surface2hasc=hex_utils.surface2hasc:main',
16+
'surface2asc=hex_utils.surface2asc:main'
1717
],
1818
},
1919

@@ -36,4 +36,4 @@
3636
],
3737

3838
# could also include long_description, download_url, classifiers, etc.
39-
)
39+
)

surfaces/surfaceGaussian.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,5 @@ def fun(x, y):
3737
return gauss.fun(x, y)
3838

3939
# Uncomment this lines for auto-plotting
40-
gauss.plot()
40+
# gauss.plot()
4141

surfaces/surfaceHubbert.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ def fun(x, y):
3939
return hubbert.fun(x, y)
4040

4141
# Uncomment these lines for auto-plotting
42-
hubbert.plot()
42+
# hubbert.plot()

0 commit comments

Comments
 (0)