mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2026-02-01 17:20:51 +00:00
to version 2.1.5
This commit is contained in:
parent
8d610b6d3c
commit
8fa63a7d39
@ -7,7 +7,6 @@
|
||||
<RecentFolder Folder="D:\Run"/>
|
||||
<RecentFolder Folder="D:\Run\verification"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\micaps"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
|
||||
@ -15,23 +14,24 @@
|
||||
<RecentFolder Folder="D:\Run\verification\air_force\script"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\dataframe"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\traj"/>
|
||||
</Path>
|
||||
<File>
|
||||
<OpenedFiles>
|
||||
<OpenedFile File="D:\Run\verification\air_force\script\vf_vis_continuous.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\dataframe\dataframe_groupby_2.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\traj\plot_traj_multi_files.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\traj_relief_1.py"/>
|
||||
</OpenedFiles>
|
||||
<RecentFiles>
|
||||
<RecentFile File="D:\Run\verification\air_force\script\vf_vis_continuous.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\dataframe\dataframe_groupby_2.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\traj\plot_traj_multi_files.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\traj_relief_1.py"/>
|
||||
</RecentFiles>
|
||||
</File>
|
||||
<Font>
|
||||
<TextFont FontName="YaHei Consolas Hybrid" FontSize="14"/>
|
||||
</Font>
|
||||
<LookFeel Name="FlatDarkLaf"/>
|
||||
<Startup MainFormLocation="-7,0" MainFormSize="1399,823"/>
|
||||
<Startup MainFormLocation="-7,-7" MainFormSize="1293,693"/>
|
||||
</MeteoInfo>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.meteothink</groupId>
|
||||
<artifactId>MeteoInfo</artifactId>
|
||||
<version>2.1.4</version>
|
||||
<version>2.1.5</version>
|
||||
</parent>
|
||||
<artifactId>MeteoInfoLab</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
Binary file not shown.
@ -1,501 +1,493 @@
|
||||
#-----------------------------------------------------
|
||||
# Author: Yaqiang Wang
|
||||
# Date: 2015-9-20
|
||||
# Purpose: MeteoInfoLab layer module
|
||||
# Note: Jython
|
||||
#-----------------------------------------------------
|
||||
from org.meteoinfo.data import TableUtil, XYListDataset
|
||||
from org.meteoinfo.layer import LayerTypes, VectorLayer, ChartSet
|
||||
from org.meteoinfo.projection import ProjectionUtil, KnownCoordinateSystems
|
||||
from org.meteoinfo.shape import PolygonShape, ShapeTypes
|
||||
from org.meteoinfo.legend import LegendType
|
||||
from java.util import Date, Calendar
|
||||
from java.awt import Font
|
||||
from datetime import datetime
|
||||
import mipylib.miutil as miutil
|
||||
import mipylib.numeric as np
|
||||
import geoutil
|
||||
|
||||
class MILayer(object):
|
||||
'''
|
||||
Map layer
|
||||
|
||||
:param layer: (*MapLayer*) MapLayer object.
|
||||
:param shapetype: (*ShapeTypes*) Shape type ['point' | 'line' | 'polygon']
|
||||
'''
|
||||
def __init__(self, layer=None, shapetype=None):
|
||||
if layer is None:
|
||||
if shapetype is None:
|
||||
print 'shapetype must be specified!'
|
||||
else:
|
||||
type = ShapeTypes.Point
|
||||
if shapetype == 'line':
|
||||
type = ShapeTypes.Polyline
|
||||
elif shapetype == 'polygon':
|
||||
type = ShapeTypes.Polygon
|
||||
self.layer = VectorLayer(type)
|
||||
self.shapetype = type
|
||||
self.proj = KnownCoordinateSystems.geographic.world.WGS1984
|
||||
else:
|
||||
self.layer = layer
|
||||
self.shapetype = layer.getShapeType()
|
||||
self.proj = layer.getProjInfo()
|
||||
|
||||
def __repr__(self):
|
||||
return self.layer.getLayerInfo()
|
||||
|
||||
def isvectorlayer(self):
|
||||
'''
|
||||
Check this layer is VectorLayer or not.
|
||||
|
||||
:returns: (*boolean*) Is VectorLayer or not.
|
||||
'''
|
||||
return self.layer.getLayerType() == LayerTypes.VectorLayer
|
||||
|
||||
def get_encoding(self):
|
||||
'''
|
||||
Get encoding.
|
||||
|
||||
:returns: (*string*) Encoding
|
||||
'''
|
||||
return self.layer.getAttributeTable().getEncoding()
|
||||
|
||||
def gettable(self):
|
||||
'''
|
||||
Get attribute table.
|
||||
|
||||
:returns: (*PyTableData') Attribute table.
|
||||
'''
|
||||
r = self.layer.getAttributeTable().getTable()
|
||||
return np.datatable(r)
|
||||
|
||||
def cellvalue(self, fieldname, shapeindex):
|
||||
'''
|
||||
Get attribute table cell value.
|
||||
|
||||
:param fieldname: (*string*) Field name.
|
||||
:param shapeindex: (*int*) Shape index.
|
||||
|
||||
:returns: The value in attribute table identified by field name and shape index.
|
||||
'''
|
||||
v = self.layer.getCellValue(fieldname, shapeindex)
|
||||
if isinstance(v, Date):
|
||||
cal = Calendar.getInstance()
|
||||
cal.setTime(v)
|
||||
year = cal.get(Calendar.YEAR)
|
||||
month = cal.get(Calendar.MONTH) + 1
|
||||
day = cal.get(Calendar.DAY_OF_MONTH)
|
||||
hour = cal.get(Calendar.HOUR_OF_DAY)
|
||||
minute = cal.get(Calendar.MINUTE)
|
||||
second = cal.get(Calendar.SECOND)
|
||||
dt = datetime(year, month, day, hour, minute, second)
|
||||
return dt
|
||||
else:
|
||||
return v
|
||||
|
||||
def setcellvalue(self, fieldname, shapeindex, value):
|
||||
'''
|
||||
Set cell value in attribute table.
|
||||
|
||||
:param fieldname: (*string*) Field name.
|
||||
:param shapeindex: (*int*) Shape index.
|
||||
:param value: (*object*) Cell value to be asigned.
|
||||
'''
|
||||
self.layer.editCellValue(fieldname, shapeindex, value)
|
||||
|
||||
def shapes(self):
|
||||
'''
|
||||
Get shapes.
|
||||
'''
|
||||
return self.layer.getShapes()
|
||||
|
||||
def shapenum(self):
|
||||
'''
|
||||
Get shape number
|
||||
'''
|
||||
return self.layer.getShapeNum()
|
||||
|
||||
def legend(self):
|
||||
'''
|
||||
Get legend scheme.
|
||||
'''
|
||||
return self.layer.getLegendScheme()
|
||||
|
||||
def setlegend(self, legend):
|
||||
'''
|
||||
Set legend scheme.
|
||||
|
||||
:param legend: (*LegendScheme*) Legend scheme.
|
||||
'''
|
||||
self.layer.setLegendScheme(legend)
|
||||
|
||||
def update_legend(self, ltype, fieldname):
|
||||
'''
|
||||
Update legend scheme.
|
||||
|
||||
:param ltype: (*string*) Legend type [single | unique | graduate].
|
||||
:param fieldname: (*string*) Field name.
|
||||
'''
|
||||
if ltype == 'single':
|
||||
ltype = LegendType.SingleSymbol
|
||||
elif ltype == 'unique':
|
||||
ltype = LegendType.UniqueValue
|
||||
elif ltyp == 'graduate':
|
||||
ltype = LegendType.GraduatedColor
|
||||
else:
|
||||
raise ValueError(ltype)
|
||||
self.layer.updateLegendScheme(ltype, fieldname)
|
||||
return self.layer.getLegendScheme()
|
||||
|
||||
def addfield(self, fieldname, dtype, values=None):
|
||||
'''
|
||||
Add a field into the attribute table.
|
||||
|
||||
:param fieldname: (*string*) Field name.
|
||||
:param dtype: (*string*) Field data type [string | int | float | double].
|
||||
:param values: (*array_like*) Field values.
|
||||
'''
|
||||
dt = TableUtil.toDataTypes(dtype)
|
||||
self.layer.editAddField(fieldname, dt)
|
||||
if not values is None:
|
||||
n = self.shapenum()
|
||||
for i in range(n):
|
||||
if i < len(values):
|
||||
self.layer.editCellValue(fieldname, i, values[i])
|
||||
|
||||
def delfield(self, fieldname):
|
||||
'''
|
||||
Delete a field from the attribute table.
|
||||
|
||||
:param fieldname: (*string*) Filed name.
|
||||
'''
|
||||
self.layer.editRemoveField(fieldname)
|
||||
|
||||
def renamefield(self, fieldname, newfieldname):
|
||||
'''
|
||||
Rename the field.
|
||||
|
||||
:param fieldname: (*string*) The old field name.
|
||||
:param newfieldname: (*string*) The new field name.
|
||||
'''
|
||||
self.layer.editRenameField(fieldname, newfieldname)
|
||||
|
||||
def addshape(self, x, y, fields=None, z=None, m=None):
|
||||
'''
|
||||
Add a shape.
|
||||
|
||||
:param x: (*array_like*) X coordinates of the shape points.
|
||||
:param y: (*array_like*) Y coordinates of the shape points.
|
||||
:param fields: (*array_like*) Field values of the shape.
|
||||
:param z: (*array_like*) Optional, Z coordinates of the shape points.
|
||||
:param m: (*array_like*) Optional, M coordinates of the shape points.
|
||||
'''
|
||||
type = 'point'
|
||||
if self.shapetype == ShapeTypes.Polyline:
|
||||
type = 'line'
|
||||
elif self.shapetype == ShapeTypes.Polygon:
|
||||
type = 'polygon'
|
||||
shapes = geoutil.makeshapes(x, y, type, z, m)
|
||||
if len(shapes) == 1:
|
||||
self.layer.editAddShape(shapes[0], fields)
|
||||
else:
|
||||
for shape, field in zip(shapes, fields):
|
||||
self.layer.editAddShape(shape, field)
|
||||
|
||||
def addlabels(self, fieldname, **kwargs):
|
||||
'''
|
||||
Add labels
|
||||
|
||||
:param fieldname: (*string*) Field name
|
||||
:param fontname: (*string*) Font name. Default is ``Arial``.
|
||||
:param fontsize: (*string*) Font size. Default is ``14``.
|
||||
:param bold: (*boolean*) Font bold or not. Default is ``False``.
|
||||
:param color: (*color*) Label color. Default is ``None`` with black color.
|
||||
:param xoffset: (*int*) X coordinate offset. Default is ``0``.
|
||||
:param yoffset: (*int*) Y coordinate offset. Default is ``0``.
|
||||
:param avoidcoll: (*boolean*) Avoid labels collision or not. Default is ``True``.
|
||||
:param decimals: (*int*) Number of decimals of labels.
|
||||
'''
|
||||
labelset = self.layer.getLabelSet()
|
||||
labelset.setFieldName(fieldname)
|
||||
fontname = kwargs.pop('fontname', 'Arial')
|
||||
fontsize = kwargs.pop('fontsize', 14)
|
||||
bold = kwargs.pop('bold', False)
|
||||
if bold:
|
||||
font = Font(fontname, Font.BOLD, fontsize)
|
||||
else:
|
||||
font = Font(fontname, Font.PLAIN, fontsize)
|
||||
labelset.setLabelFont(font)
|
||||
color = kwargs.pop('color', None)
|
||||
if not color is None:
|
||||
color = miutil.getcolor(color)
|
||||
labelset.setLabelColor(color)
|
||||
xoffset = kwargs.pop('xoffset', 0)
|
||||
labelset.setXOffset(xoffset)
|
||||
yoffset = kwargs.pop('yoffset', 0)
|
||||
labelset.setYOffset(yoffset)
|
||||
avoidcoll = kwargs.pop('avoidcoll', True)
|
||||
labelset.setAvoidCollision(avoidcoll)
|
||||
decimals = kwargs.pop('decimals', None)
|
||||
if not decimals is None:
|
||||
labelset.setAutoDecimal(False)
|
||||
labelset.setDecimalDigits(decimals)
|
||||
self.layer.addLabels()
|
||||
|
||||
def getlabel(self, text):
|
||||
'''
|
||||
Get a label.
|
||||
|
||||
:param text: (*string*) The label text.
|
||||
'''
|
||||
return self.layer.getLabel(text)
|
||||
|
||||
def movelabel(self, label, x=0, y=0):
|
||||
'''
|
||||
Move a label.
|
||||
|
||||
:param label: (*string*) The label text.
|
||||
:param x: (*float*) X shift for moving in pixel unit.
|
||||
:param y: (*float*) Y shift for moving in pixel unit.
|
||||
'''
|
||||
self.layer.moveLabel(label, x, y)
|
||||
|
||||
def add_charts(self, fieldnames, legend=None, **kwargs):
|
||||
'''
|
||||
Add charts
|
||||
|
||||
:param fieldnames: (*list of string*) Field name list.
|
||||
:param legend: (*LegendScheme*) Chart legend.
|
||||
:param charttype: (*string*) Chart type [bar | pie]. Default is ``bar``.
|
||||
:param minsize: (*int*) Minimum chart size. Default is ``0``.
|
||||
:param maxsize: (*int*) Maximum chart size. Default is ``50``.
|
||||
:param barwidth: (*int*) Bar width. Only valid for bar chart. Default is ``8``.
|
||||
:param xoffset: (*int*) X coordinate offset. Default is ``0``.
|
||||
:param yoffset: (*int*) Y coordinate offset. Default is ``0``.
|
||||
:param avoidcoll: (*boolean*) Avoid labels collision or not. Default is ``True``.
|
||||
:param align: (*string*) Chart align type [center | left | right | none], Default is ``center``.
|
||||
:param view3d: (*boolean*) Draw chart as 3D or not. Default is ``False``.
|
||||
:param thickness: (*int*) 3D chart thickness. Default is ``5``.
|
||||
:param drawlabel: (*boolean*) Draw label or not. Default is ``False``.
|
||||
:param fontname: (*string*) Label font name.
|
||||
:param fontsize: (*int*) Label font size.
|
||||
:param bold: (*boolean*) Font bold or not. Default is ``False``.
|
||||
:param labelcolor: (*color*) Label color.
|
||||
:param decimals: (*int*) Number of decimals of labels.
|
||||
'''
|
||||
charttype = kwargs.pop('charttype', None)
|
||||
minsize = kwargs.pop('minsize', None)
|
||||
maxsize = kwargs.pop('maxsize', None)
|
||||
barwidth = kwargs.pop('barwidth', None)
|
||||
xoffset = kwargs.pop('xoffset', None)
|
||||
yoffset = kwargs.pop('yoffset', None)
|
||||
avoidcoll = kwargs.pop('avoidcoll', None)
|
||||
align = kwargs.pop('align', None)
|
||||
view3d = kwargs.pop('view3d', None)
|
||||
thickness = kwargs.pop('thickness', None)
|
||||
drawlabel = kwargs.pop('drawlabel', None)
|
||||
fontname = kwargs.pop('fontname', 'Arial')
|
||||
fontsize = kwargs.pop('fontsize', 12)
|
||||
bold = kwargs.pop('bold', False)
|
||||
if bold:
|
||||
font = Font(fontname, Font.BOLD, fontsize)
|
||||
else:
|
||||
font = Font(fontname, Font.PLAIN, fontsize)
|
||||
labelcolor = kwargs.pop('labelcolor', None)
|
||||
decimals = kwargs.pop('decimals', None)
|
||||
|
||||
chartset = self.layer.getChartSet()
|
||||
chartset.setFieldNames(fieldnames)
|
||||
chartset.setLegendScheme(legend)
|
||||
if not charttype is None:
|
||||
chartset.setChartType(charttype)
|
||||
if not minsize is None:
|
||||
chartset.setMinSize(minsize)
|
||||
if not maxsize is None:
|
||||
chartset.setMaxSize(maxsize)
|
||||
if not barwidth is None:
|
||||
chartset.setBarWidth(barwidth)
|
||||
if not xoffset is None:
|
||||
chartset.setXShift(xoffset)
|
||||
if not yoffset is None:
|
||||
chartset.setYShift(yoffset)
|
||||
if not avoidcoll is None:
|
||||
chartset.setAvoidCollision(avoidcoll)
|
||||
if not align is None:
|
||||
chartset.setAlignType(align)
|
||||
if not view3d is None:
|
||||
chartset.setView3D(view3d)
|
||||
if not thickness is None:
|
||||
chartset.setThickness(thickness)
|
||||
if not drawlabel is None:
|
||||
chartset.setDrawLabel(drawlabel)
|
||||
chartset.setLabelFont(font)
|
||||
if not labelcolor is None:
|
||||
chartset.setLabelColor(miutil.getcolor(labelcolor))
|
||||
if not decimals is None:
|
||||
chartset.setDecimalDigits(decimals)
|
||||
self.layer.updateChartSet()
|
||||
self.layer.addCharts()
|
||||
return chartset
|
||||
|
||||
def get_chartlegend(self):
|
||||
'''
|
||||
Get legend of the chart graphics.
|
||||
'''
|
||||
return self.layer.getChartSet().getLegendScheme()
|
||||
|
||||
def get_chart(self, index):
|
||||
'''
|
||||
Get a chart graphic.
|
||||
|
||||
:param index: (*int*) Chart index.
|
||||
|
||||
:returns: Chart graphic
|
||||
'''
|
||||
return self.layer.getChartPoints()[index]
|
||||
|
||||
def move_chart(self, index, x=0, y=0):
|
||||
'''
|
||||
Move a chart graphic.
|
||||
|
||||
:param index: (*int*) Chart index.
|
||||
:param x: (*float*) X shift for moving.
|
||||
:param y: (*float*) Y shift for moving.
|
||||
'''
|
||||
s = self.layer.getChartPoints()[index].getShape()
|
||||
p = s.getPoint()
|
||||
p.X = p.X + x
|
||||
p.Y = p.Y + y
|
||||
s.setPoint(p)
|
||||
|
||||
def set_avoidcoll(self, avoidcoll):
|
||||
'''
|
||||
Set if avoid collision or not. Only valid for VectorLayer with Point shapes.
|
||||
|
||||
:param avoidcoll: (*boolean*) Avoid collision or not.
|
||||
'''
|
||||
self.layer.setAvoidCollision(avoidcoll)
|
||||
|
||||
def project(self, toproj):
|
||||
'''
|
||||
Project to another projection.
|
||||
|
||||
:param toproj: (*ProjectionInfo*) The projection to be projected.
|
||||
'''
|
||||
ProjectionUtil.projectLayer(self.layer, toproj)
|
||||
|
||||
def buffer(self, dist=0, merge=False):
|
||||
'''
|
||||
Get the buffer layer.
|
||||
|
||||
:param dist: (*float*) Buffer value.
|
||||
:param merge: (*boolean*) Merge the buffered shapes or not.
|
||||
|
||||
:returns: (*MILayer*) Buffered layer.
|
||||
'''
|
||||
r = self.layer.buffer(dist, False, merge)
|
||||
return MILayer(r)
|
||||
|
||||
def clip(self, clipobj):
|
||||
'''
|
||||
Clip this layer by polygon or another polygon layer.
|
||||
|
||||
:param clipobj: (*PolygonShape or MILayer*) Clip object.
|
||||
|
||||
:returns: (*MILayer*) Clipped layer.
|
||||
'''
|
||||
if isinstance(clipobj, PolygonShape):
|
||||
clipobj = [clipobj]
|
||||
elif isinstance(clipobj, MILayer):
|
||||
clipobj = clipobj.layer
|
||||
r = self.layer.clip(clipobj)
|
||||
return MILayer(r)
|
||||
|
||||
def select(self, expression, seltype='new'):
|
||||
'''
|
||||
Select shapes by SQL expression.
|
||||
|
||||
:param expression: (*string*) SQL expression.
|
||||
:param seltype: (*string*) Selection type ['new' | 'add_to_current' |
|
||||
'remove_from_current' | 'select_from_current']
|
||||
|
||||
:returns: (*list of Shape*) Selected shape list.
|
||||
'''
|
||||
self.layer.sqlSelect(expression, seltype)
|
||||
return self.layer.getSelectedShapes()
|
||||
|
||||
def clear_selection(self):
|
||||
'''
|
||||
Clear shape selection.
|
||||
'''
|
||||
self.layer.clearSelectedShapes()
|
||||
|
||||
def clone(self):
|
||||
'''
|
||||
Clone self.
|
||||
'''
|
||||
return MILayer(self.layer.clone())
|
||||
|
||||
def save(self, fn=None, encoding=None):
|
||||
"""
|
||||
Save layer as shape file.
|
||||
|
||||
:param fn: (*string*) Shape file name (.shp).
|
||||
:param encoding: (*string*) Encoding.
|
||||
"""
|
||||
if fn is None:
|
||||
fn = self.layer.getFileName()
|
||||
|
||||
if fn.strip() == '':
|
||||
print 'File name is needed to save the layer!'
|
||||
raise IOError
|
||||
else:
|
||||
if encoding is None:
|
||||
self.layer.saveFile(fn)
|
||||
else:
|
||||
self.layer.saveFile(fn, encoding)
|
||||
|
||||
def savekml(self, fn):
|
||||
"""
|
||||
Save layer as KML file.
|
||||
|
||||
:param fn: (*string*) KML file name.
|
||||
"""
|
||||
self.layer.saveAsKMLFile(fn)
|
||||
|
||||
|
||||
class MIXYListData():
|
||||
def __init__(self, data=None):
|
||||
if data is None:
|
||||
self.data = XYListDataset()
|
||||
else:
|
||||
self.data = data
|
||||
|
||||
def __getitem__(self, indices):
|
||||
if not isinstance(indices, tuple):
|
||||
inds = []
|
||||
inds.append(indices)
|
||||
indices = inds
|
||||
|
||||
if isinstance(indices[0], int):
|
||||
if isinstance(indices[1], int):
|
||||
x = self.data.getX(indices[0], indices[1])
|
||||
y = self.data.getY(indices[0], indices[1])
|
||||
return x, y
|
||||
else:
|
||||
return self.data.getXValues(indices[0]), self.data.getXValues(indices[0])
|
||||
|
||||
def size(self, series=None):
|
||||
if series is None:
|
||||
return self.data.getSeriesCount()
|
||||
else:
|
||||
return self.data.getItemCount(series)
|
||||
|
||||
def addseries(self, xdata, ydata, key=None):
|
||||
if key is None:
|
||||
key = 'Series_' + str(self.size())
|
||||
if isinstance(xdata, list):
|
||||
self.data.addSeries(key, xdata, ydata)
|
||||
else:
|
||||
self.data.addSeries(key, xdata.asarray(), ydata.asarray())
|
||||
#-----------------------------------------------------
|
||||
# Author: Yaqiang Wang
|
||||
# Date: 2015-9-20
|
||||
# Purpose: MeteoInfoLab layer module
|
||||
# Note: Jython
|
||||
#-----------------------------------------------------
|
||||
from org.meteoinfo.data import TableUtil, XYListDataset
|
||||
from org.meteoinfo.layer import LayerTypes, VectorLayer, ChartSet
|
||||
from org.meteoinfo.projection import ProjectionUtil, KnownCoordinateSystems
|
||||
from org.meteoinfo.shape import PolygonShape, ShapeTypes
|
||||
from org.meteoinfo.legend import LegendType
|
||||
from java.time import LocalDateTime
|
||||
from java.awt import Font
|
||||
from datetime import datetime
|
||||
import mipylib.miutil as miutil
|
||||
import mipylib.numeric as np
|
||||
import geoutil
|
||||
|
||||
class MILayer(object):
|
||||
'''
|
||||
Map layer
|
||||
|
||||
:param layer: (*MapLayer*) MapLayer object.
|
||||
:param shapetype: (*ShapeTypes*) Shape type ['point' | 'line' | 'polygon']
|
||||
'''
|
||||
def __init__(self, layer=None, shapetype=None):
|
||||
if layer is None:
|
||||
if shapetype is None:
|
||||
print 'shapetype must be specified!'
|
||||
else:
|
||||
type = ShapeTypes.Point
|
||||
if shapetype == 'line':
|
||||
type = ShapeTypes.Polyline
|
||||
elif shapetype == 'polygon':
|
||||
type = ShapeTypes.Polygon
|
||||
self.layer = VectorLayer(type)
|
||||
self.shapetype = type
|
||||
self.proj = KnownCoordinateSystems.geographic.world.WGS1984
|
||||
else:
|
||||
self.layer = layer
|
||||
self.shapetype = layer.getShapeType()
|
||||
self.proj = layer.getProjInfo()
|
||||
|
||||
def __repr__(self):
|
||||
return self.layer.getLayerInfo()
|
||||
|
||||
def isvectorlayer(self):
|
||||
'''
|
||||
Check this layer is VectorLayer or not.
|
||||
|
||||
:returns: (*boolean*) Is VectorLayer or not.
|
||||
'''
|
||||
return self.layer.getLayerType() == LayerTypes.VectorLayer
|
||||
|
||||
def get_encoding(self):
|
||||
'''
|
||||
Get encoding.
|
||||
|
||||
:returns: (*string*) Encoding
|
||||
'''
|
||||
return self.layer.getAttributeTable().getEncoding()
|
||||
|
||||
def gettable(self):
|
||||
'''
|
||||
Get attribute table.
|
||||
|
||||
:returns: (*PyTableData') Attribute table.
|
||||
'''
|
||||
r = self.layer.getAttributeTable().getTable()
|
||||
return np.datatable(r)
|
||||
|
||||
def cellvalue(self, fieldname, shapeindex):
|
||||
'''
|
||||
Get attribute table cell value.
|
||||
|
||||
:param fieldname: (*string*) Field name.
|
||||
:param shapeindex: (*int*) Shape index.
|
||||
|
||||
:returns: The value in attribute table identified by field name and shape index.
|
||||
'''
|
||||
v = self.layer.getCellValue(fieldname, shapeindex)
|
||||
if isinstance(v, LocalDateTime):
|
||||
dt = miutil.pydate(v)
|
||||
return dt
|
||||
else:
|
||||
return v
|
||||
|
||||
def setcellvalue(self, fieldname, shapeindex, value):
|
||||
'''
|
||||
Set cell value in attribute table.
|
||||
|
||||
:param fieldname: (*string*) Field name.
|
||||
:param shapeindex: (*int*) Shape index.
|
||||
:param value: (*object*) Cell value to be asigned.
|
||||
'''
|
||||
self.layer.editCellValue(fieldname, shapeindex, value)
|
||||
|
||||
def shapes(self):
|
||||
'''
|
||||
Get shapes.
|
||||
'''
|
||||
return self.layer.getShapes()
|
||||
|
||||
def shapenum(self):
|
||||
'''
|
||||
Get shape number
|
||||
'''
|
||||
return self.layer.getShapeNum()
|
||||
|
||||
def legend(self):
|
||||
'''
|
||||
Get legend scheme.
|
||||
'''
|
||||
return self.layer.getLegendScheme()
|
||||
|
||||
def setlegend(self, legend):
|
||||
'''
|
||||
Set legend scheme.
|
||||
|
||||
:param legend: (*LegendScheme*) Legend scheme.
|
||||
'''
|
||||
self.layer.setLegendScheme(legend)
|
||||
|
||||
def update_legend(self, ltype, fieldname):
|
||||
'''
|
||||
Update legend scheme.
|
||||
|
||||
:param ltype: (*string*) Legend type [single | unique | graduate].
|
||||
:param fieldname: (*string*) Field name.
|
||||
'''
|
||||
if ltype == 'single':
|
||||
ltype = LegendType.SingleSymbol
|
||||
elif ltype == 'unique':
|
||||
ltype = LegendType.UniqueValue
|
||||
elif ltyp == 'graduate':
|
||||
ltype = LegendType.GraduatedColor
|
||||
else:
|
||||
raise ValueError(ltype)
|
||||
self.layer.updateLegendScheme(ltype, fieldname)
|
||||
return self.layer.getLegendScheme()
|
||||
|
||||
def addfield(self, fieldname, dtype, values=None):
|
||||
'''
|
||||
Add a field into the attribute table.
|
||||
|
||||
:param fieldname: (*string*) Field name.
|
||||
:param dtype: (*string*) Field data type [string | int | float | double].
|
||||
:param values: (*array_like*) Field values.
|
||||
'''
|
||||
dt = TableUtil.toDataTypes(dtype)
|
||||
self.layer.editAddField(fieldname, dt)
|
||||
if not values is None:
|
||||
n = self.shapenum()
|
||||
for i in range(n):
|
||||
if i < len(values):
|
||||
self.layer.editCellValue(fieldname, i, values[i])
|
||||
|
||||
def delfield(self, fieldname):
|
||||
'''
|
||||
Delete a field from the attribute table.
|
||||
|
||||
:param fieldname: (*string*) Filed name.
|
||||
'''
|
||||
self.layer.editRemoveField(fieldname)
|
||||
|
||||
def renamefield(self, fieldname, newfieldname):
|
||||
'''
|
||||
Rename the field.
|
||||
|
||||
:param fieldname: (*string*) The old field name.
|
||||
:param newfieldname: (*string*) The new field name.
|
||||
'''
|
||||
self.layer.editRenameField(fieldname, newfieldname)
|
||||
|
||||
def addshape(self, x, y, fields=None, z=None, m=None):
|
||||
'''
|
||||
Add a shape.
|
||||
|
||||
:param x: (*array_like*) X coordinates of the shape points.
|
||||
:param y: (*array_like*) Y coordinates of the shape points.
|
||||
:param fields: (*array_like*) Field values of the shape.
|
||||
:param z: (*array_like*) Optional, Z coordinates of the shape points.
|
||||
:param m: (*array_like*) Optional, M coordinates of the shape points.
|
||||
'''
|
||||
type = 'point'
|
||||
if self.shapetype == ShapeTypes.Polyline:
|
||||
type = 'line'
|
||||
elif self.shapetype == ShapeTypes.Polygon:
|
||||
type = 'polygon'
|
||||
shapes = geoutil.makeshapes(x, y, type, z, m)
|
||||
if len(shapes) == 1:
|
||||
self.layer.editAddShape(shapes[0], fields)
|
||||
else:
|
||||
for shape, field in zip(shapes, fields):
|
||||
self.layer.editAddShape(shape, field)
|
||||
|
||||
def addlabels(self, fieldname, **kwargs):
|
||||
'''
|
||||
Add labels
|
||||
|
||||
:param fieldname: (*string*) Field name
|
||||
:param fontname: (*string*) Font name. Default is ``Arial``.
|
||||
:param fontsize: (*string*) Font size. Default is ``14``.
|
||||
:param bold: (*boolean*) Font bold or not. Default is ``False``.
|
||||
:param color: (*color*) Label color. Default is ``None`` with black color.
|
||||
:param xoffset: (*int*) X coordinate offset. Default is ``0``.
|
||||
:param yoffset: (*int*) Y coordinate offset. Default is ``0``.
|
||||
:param avoidcoll: (*boolean*) Avoid labels collision or not. Default is ``True``.
|
||||
:param decimals: (*int*) Number of decimals of labels.
|
||||
'''
|
||||
labelset = self.layer.getLabelSet()
|
||||
labelset.setFieldName(fieldname)
|
||||
fontname = kwargs.pop('fontname', 'Arial')
|
||||
fontsize = kwargs.pop('fontsize', 14)
|
||||
bold = kwargs.pop('bold', False)
|
||||
if bold:
|
||||
font = Font(fontname, Font.BOLD, fontsize)
|
||||
else:
|
||||
font = Font(fontname, Font.PLAIN, fontsize)
|
||||
labelset.setLabelFont(font)
|
||||
color = kwargs.pop('color', None)
|
||||
if not color is None:
|
||||
color = miutil.getcolor(color)
|
||||
labelset.setLabelColor(color)
|
||||
xoffset = kwargs.pop('xoffset', 0)
|
||||
labelset.setXOffset(xoffset)
|
||||
yoffset = kwargs.pop('yoffset', 0)
|
||||
labelset.setYOffset(yoffset)
|
||||
avoidcoll = kwargs.pop('avoidcoll', True)
|
||||
labelset.setAvoidCollision(avoidcoll)
|
||||
decimals = kwargs.pop('decimals', None)
|
||||
if not decimals is None:
|
||||
labelset.setAutoDecimal(False)
|
||||
labelset.setDecimalDigits(decimals)
|
||||
self.layer.addLabels()
|
||||
|
||||
def getlabel(self, text):
|
||||
'''
|
||||
Get a label.
|
||||
|
||||
:param text: (*string*) The label text.
|
||||
'''
|
||||
return self.layer.getLabel(text)
|
||||
|
||||
def movelabel(self, label, x=0, y=0):
|
||||
'''
|
||||
Move a label.
|
||||
|
||||
:param label: (*string*) The label text.
|
||||
:param x: (*float*) X shift for moving in pixel unit.
|
||||
:param y: (*float*) Y shift for moving in pixel unit.
|
||||
'''
|
||||
self.layer.moveLabel(label, x, y)
|
||||
|
||||
def add_charts(self, fieldnames, legend=None, **kwargs):
|
||||
'''
|
||||
Add charts
|
||||
|
||||
:param fieldnames: (*list of string*) Field name list.
|
||||
:param legend: (*LegendScheme*) Chart legend.
|
||||
:param charttype: (*string*) Chart type [bar | pie]. Default is ``bar``.
|
||||
:param minsize: (*int*) Minimum chart size. Default is ``0``.
|
||||
:param maxsize: (*int*) Maximum chart size. Default is ``50``.
|
||||
:param barwidth: (*int*) Bar width. Only valid for bar chart. Default is ``8``.
|
||||
:param xoffset: (*int*) X coordinate offset. Default is ``0``.
|
||||
:param yoffset: (*int*) Y coordinate offset. Default is ``0``.
|
||||
:param avoidcoll: (*boolean*) Avoid labels collision or not. Default is ``True``.
|
||||
:param align: (*string*) Chart align type [center | left | right | none], Default is ``center``.
|
||||
:param view3d: (*boolean*) Draw chart as 3D or not. Default is ``False``.
|
||||
:param thickness: (*int*) 3D chart thickness. Default is ``5``.
|
||||
:param drawlabel: (*boolean*) Draw label or not. Default is ``False``.
|
||||
:param fontname: (*string*) Label font name.
|
||||
:param fontsize: (*int*) Label font size.
|
||||
:param bold: (*boolean*) Font bold or not. Default is ``False``.
|
||||
:param labelcolor: (*color*) Label color.
|
||||
:param decimals: (*int*) Number of decimals of labels.
|
||||
'''
|
||||
charttype = kwargs.pop('charttype', None)
|
||||
minsize = kwargs.pop('minsize', None)
|
||||
maxsize = kwargs.pop('maxsize', None)
|
||||
barwidth = kwargs.pop('barwidth', None)
|
||||
xoffset = kwargs.pop('xoffset', None)
|
||||
yoffset = kwargs.pop('yoffset', None)
|
||||
avoidcoll = kwargs.pop('avoidcoll', None)
|
||||
align = kwargs.pop('align', None)
|
||||
view3d = kwargs.pop('view3d', None)
|
||||
thickness = kwargs.pop('thickness', None)
|
||||
drawlabel = kwargs.pop('drawlabel', None)
|
||||
fontname = kwargs.pop('fontname', 'Arial')
|
||||
fontsize = kwargs.pop('fontsize', 12)
|
||||
bold = kwargs.pop('bold', False)
|
||||
if bold:
|
||||
font = Font(fontname, Font.BOLD, fontsize)
|
||||
else:
|
||||
font = Font(fontname, Font.PLAIN, fontsize)
|
||||
labelcolor = kwargs.pop('labelcolor', None)
|
||||
decimals = kwargs.pop('decimals', None)
|
||||
|
||||
chartset = self.layer.getChartSet()
|
||||
chartset.setFieldNames(fieldnames)
|
||||
chartset.setLegendScheme(legend)
|
||||
if not charttype is None:
|
||||
chartset.setChartType(charttype)
|
||||
if not minsize is None:
|
||||
chartset.setMinSize(minsize)
|
||||
if not maxsize is None:
|
||||
chartset.setMaxSize(maxsize)
|
||||
if not barwidth is None:
|
||||
chartset.setBarWidth(barwidth)
|
||||
if not xoffset is None:
|
||||
chartset.setXShift(xoffset)
|
||||
if not yoffset is None:
|
||||
chartset.setYShift(yoffset)
|
||||
if not avoidcoll is None:
|
||||
chartset.setAvoidCollision(avoidcoll)
|
||||
if not align is None:
|
||||
chartset.setAlignType(align)
|
||||
if not view3d is None:
|
||||
chartset.setView3D(view3d)
|
||||
if not thickness is None:
|
||||
chartset.setThickness(thickness)
|
||||
if not drawlabel is None:
|
||||
chartset.setDrawLabel(drawlabel)
|
||||
chartset.setLabelFont(font)
|
||||
if not labelcolor is None:
|
||||
chartset.setLabelColor(miutil.getcolor(labelcolor))
|
||||
if not decimals is None:
|
||||
chartset.setDecimalDigits(decimals)
|
||||
self.layer.updateChartSet()
|
||||
self.layer.addCharts()
|
||||
return chartset
|
||||
|
||||
def get_chartlegend(self):
|
||||
'''
|
||||
Get legend of the chart graphics.
|
||||
'''
|
||||
return self.layer.getChartSet().getLegendScheme()
|
||||
|
||||
def get_chart(self, index):
|
||||
'''
|
||||
Get a chart graphic.
|
||||
|
||||
:param index: (*int*) Chart index.
|
||||
|
||||
:returns: Chart graphic
|
||||
'''
|
||||
return self.layer.getChartPoints()[index]
|
||||
|
||||
def move_chart(self, index, x=0, y=0):
|
||||
'''
|
||||
Move a chart graphic.
|
||||
|
||||
:param index: (*int*) Chart index.
|
||||
:param x: (*float*) X shift for moving.
|
||||
:param y: (*float*) Y shift for moving.
|
||||
'''
|
||||
s = self.layer.getChartPoints()[index].getShape()
|
||||
p = s.getPoint()
|
||||
p.X = p.X + x
|
||||
p.Y = p.Y + y
|
||||
s.setPoint(p)
|
||||
|
||||
def set_avoidcoll(self, avoidcoll):
|
||||
'''
|
||||
Set if avoid collision or not. Only valid for VectorLayer with Point shapes.
|
||||
|
||||
:param avoidcoll: (*boolean*) Avoid collision or not.
|
||||
'''
|
||||
self.layer.setAvoidCollision(avoidcoll)
|
||||
|
||||
def project(self, toproj):
|
||||
'''
|
||||
Project to another projection.
|
||||
|
||||
:param toproj: (*ProjectionInfo*) The projection to be projected.
|
||||
'''
|
||||
ProjectionUtil.projectLayer(self.layer, toproj)
|
||||
|
||||
def buffer(self, dist=0, merge=False):
|
||||
'''
|
||||
Get the buffer layer.
|
||||
|
||||
:param dist: (*float*) Buffer value.
|
||||
:param merge: (*boolean*) Merge the buffered shapes or not.
|
||||
|
||||
:returns: (*MILayer*) Buffered layer.
|
||||
'''
|
||||
r = self.layer.buffer(dist, False, merge)
|
||||
return MILayer(r)
|
||||
|
||||
def clip(self, clipobj):
|
||||
'''
|
||||
Clip this layer by polygon or another polygon layer.
|
||||
|
||||
:param clipobj: (*PolygonShape or MILayer*) Clip object.
|
||||
|
||||
:returns: (*MILayer*) Clipped layer.
|
||||
'''
|
||||
if isinstance(clipobj, PolygonShape):
|
||||
clipobj = [clipobj]
|
||||
elif isinstance(clipobj, MILayer):
|
||||
clipobj = clipobj.layer
|
||||
r = self.layer.clip(clipobj)
|
||||
return MILayer(r)
|
||||
|
||||
def select(self, expression, seltype='new'):
|
||||
'''
|
||||
Select shapes by SQL expression.
|
||||
|
||||
:param expression: (*string*) SQL expression.
|
||||
:param seltype: (*string*) Selection type ['new' | 'add_to_current' |
|
||||
'remove_from_current' | 'select_from_current']
|
||||
|
||||
:returns: (*list of Shape*) Selected shape list.
|
||||
'''
|
||||
self.layer.sqlSelect(expression, seltype)
|
||||
return self.layer.getSelectedShapes()
|
||||
|
||||
def clear_selection(self):
|
||||
'''
|
||||
Clear shape selection.
|
||||
'''
|
||||
self.layer.clearSelectedShapes()
|
||||
|
||||
def clone(self):
|
||||
'''
|
||||
Clone self.
|
||||
'''
|
||||
return MILayer(self.layer.clone())
|
||||
|
||||
def save(self, fn=None, encoding=None):
|
||||
"""
|
||||
Save layer as shape file.
|
||||
|
||||
:param fn: (*string*) Shape file name (.shp).
|
||||
:param encoding: (*string*) Encoding.
|
||||
"""
|
||||
if fn is None:
|
||||
fn = self.layer.getFileName()
|
||||
|
||||
if fn.strip() == '':
|
||||
print 'File name is needed to save the layer!'
|
||||
raise IOError
|
||||
else:
|
||||
if encoding is None:
|
||||
self.layer.saveFile(fn)
|
||||
else:
|
||||
self.layer.saveFile(fn, encoding)
|
||||
|
||||
def savekml(self, fn):
|
||||
"""
|
||||
Save layer as KML file.
|
||||
|
||||
:param fn: (*string*) KML file name.
|
||||
"""
|
||||
self.layer.saveAsKMLFile(fn)
|
||||
|
||||
|
||||
class MIXYListData():
|
||||
def __init__(self, data=None):
|
||||
if data is None:
|
||||
self.data = XYListDataset()
|
||||
else:
|
||||
self.data = data
|
||||
|
||||
def __getitem__(self, indices):
|
||||
if not isinstance(indices, tuple):
|
||||
inds = []
|
||||
inds.append(indices)
|
||||
indices = inds
|
||||
|
||||
if isinstance(indices[0], int):
|
||||
if isinstance(indices[1], int):
|
||||
x = self.data.getX(indices[0], indices[1])
|
||||
y = self.data.getY(indices[0], indices[1])
|
||||
return x, y
|
||||
else:
|
||||
return self.data.getXValues(indices[0]), self.data.getXValues(indices[0])
|
||||
|
||||
def size(self, series=None):
|
||||
if series is None:
|
||||
return self.data.getSeriesCount()
|
||||
else:
|
||||
return self.data.getItemCount(series)
|
||||
|
||||
def addseries(self, xdata, ydata, key=None):
|
||||
if key is None:
|
||||
key = 'Series_' + str(self.size())
|
||||
if isinstance(xdata, list):
|
||||
self.data.addSeries(key, xdata, ydata)
|
||||
else:
|
||||
self.data.addSeries(key, xdata.asarray(), ydata.asarray())
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.meteothink</groupId>
|
||||
<artifactId>MeteoInfo</artifactId>
|
||||
<version>2.1.4</version>
|
||||
<version>2.1.5</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>MeteoInfoLib</artifactId>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -24,7 +24,7 @@ import org.meteoinfo.shape.PolygonShape;
|
||||
* @author wyq
|
||||
*/
|
||||
public class GeometryUtil {
|
||||
// <editor-fold desc="Ellipse">
|
||||
|
||||
/**
|
||||
* Get ellipse coordinate
|
||||
* @param x0 Center x
|
||||
@ -592,5 +592,5 @@ public class GeometryUtil {
|
||||
public static boolean isConvex(Polygon polygon) {
|
||||
return isConvex(polygon.getOutLine());
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ public class GlobalUtil {
|
||||
* @return Software version
|
||||
*/
|
||||
public static String getVersion(){
|
||||
return "2.1.4";
|
||||
return "2.1.5";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.meteothink</groupId>
|
||||
<artifactId>MeteoInfo</artifactId>
|
||||
<version>2.1.4</version>
|
||||
<version>2.1.5</version>
|
||||
</parent>
|
||||
<artifactId>MeteoInfoMap</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@ -37,7 +37,7 @@ Get in touch
|
||||
License
|
||||
-------
|
||||
|
||||
Copyright 2010-2019, MeteoInfo Developers
|
||||
Copyright 2010-2020, MeteoInfo Developers
|
||||
|
||||
Licensed under the LGPL License, Version 3.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user