gvsig-scripting / org.gvsig.scripting.app / trunk / org.gvsig.scripting.app / org.gvsig.scripting.app.extension / src / main / resources-plugin / scripting / lib / gvsig_2_0_0.py @ 446
History | View | Annotate | Download (31.4 KB)
1 |
# -*- coding: utf-8 -*-
|
---|---|
2 |
#
|
3 |
# File: gvsig.py
|
4 |
#
|
5 |
# Copyright (c) 2011 by Model Driven Development sl and Antonio Carrasco Valero
|
6 |
#
|
7 |
# GNU General Public License (GPL)
|
8 |
#
|
9 |
# This program is free software; you can redistribute it and/or
|
10 |
# modify it under the terms of the GNU General Public License
|
11 |
# as published by the Free Software Foundation; either version 2
|
12 |
# of the License, or (at your option) any later version.
|
13 |
#
|
14 |
# This program is distributed in the hope that it will be useful,
|
15 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17 |
# GNU General Public License for more details.
|
18 |
#
|
19 |
# You should have received a copy of the GNU General Public License
|
20 |
# along with this program; if not, write to the Free Software
|
21 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
22 |
# 02110-1301, USA.
|
23 |
#
|
24 |
#
|
25 |
|
26 |
"""
|
27 |
This module contains classes and functions to manage gvSIG Project,
|
28 |
gvSIG DocumentView, gvSIG TableDocument and Layers.
|
29 |
Also contais functions to manage vectorial data and other utility
|
30 |
functions
|
31 |
"""
|
32 |
|
33 |
__author__ = """Antonio Carrasco Valero
|
34 |
Model Driven Development sl and Antonio Carrasco Valero
|
35 |
<carrasco@modeldd.org>
|
36 |
Victor Acevedo Royer <vacevedor@gvsig.com>, <vacevedor@gmail.com>
|
37 |
"""
|
38 |
|
39 |
__docformat__ = 'plaintext'
|
40 |
|
41 |
from java.awt import Color |
42 |
|
43 |
from java.lang import RuntimeException |
44 |
from java.lang import Throwable |
45 |
import java.lang.IndexOutOfBoundsException |
46 |
|
47 |
from java.util.prefs import Preferences |
48 |
|
49 |
from org.gvsig.app import ApplicationLocator |
50 |
from org.gvsig.app.project.documents.view import ViewDocument |
51 |
from org.gvsig.app.project.documents.table import TableDocument |
52 |
|
53 |
from org.gvsig.fmap.crs import CRSFactory |
54 |
|
55 |
from org.gvsig.fmap.mapcontext import MapContextLocator |
56 |
from org.gvsig.fmap.mapcontext.layers import FLayers |
57 |
|
58 |
from org.gvsig.fmap.dal import DALLocator, DataTypes |
59 |
from org.gvsig.fmap.dal.feature import EditableFeature, \ |
60 |
EditableFeatureType, FeatureQueryOrder |
61 |
from org.gvsig.fmap.dal.feature.impl import DefaultEditableFeature |
62 |
|
63 |
from org.gvsig.fmap.geom import Geometry |
64 |
|
65 |
from org.gvsig.tools import ToolsLocator |
66 |
|
67 |
import thread |
68 |
import random |
69 |
|
70 |
|
71 |
def runTask(name, function, *args): |
72 |
manager = ToolsLocator.getTaskStatusManager() |
73 |
status = manager.createDefaultSimpleTaskStatus(name) |
74 |
status.add() |
75 |
args = list(args)
|
76 |
args.append(status) |
77 |
try:
|
78 |
thread.start_new_thread(function, tuple(args))
|
79 |
status.terminate() |
80 |
except Exception,e: |
81 |
status.abort() |
82 |
raise e
|
83 |
|
84 |
|
85 |
class WrapperToJava(object): |
86 |
"""Creates a wrapper that allows python object access to the Java object
|
87 |
properties and methods
|
88 |
"""
|
89 |
def __init__(self, javaobj): |
90 |
if javaobj == None: |
91 |
raise RuntimeException("Can't create "+ self.__class__.__name__) |
92 |
self._javaobj = javaobj
|
93 |
|
94 |
def __call__(self): |
95 |
return self._javaobj |
96 |
|
97 |
def __getattr__(self,name): |
98 |
return getattr(self._javaobj,name) |
99 |
|
100 |
class Project(WrapperToJava): |
101 |
"""Represents a gvSIG project (org.gvsig.app.project.DefaultProject)"""
|
102 |
|
103 |
def __init__(self, project): |
104 |
WrapperToJava.__init__(self, project)
|
105 |
|
106 |
def getViews(self): |
107 |
views = self().getViews()
|
108 |
return ViewsIterator(views)
|
109 |
|
110 |
def getView(self, name=None): |
111 |
"""
|
112 |
Returns active view, or view called 'name' or None
|
113 |
:param name: view name
|
114 |
:type name: string
|
115 |
"""
|
116 |
if name == None: |
117 |
try:
|
118 |
activeDocument = self.getActiveDocument()
|
119 |
if activeDocument == None: |
120 |
return None |
121 |
if isinstance(activeDocument, ViewDocument): |
122 |
return View(activeDocument)
|
123 |
except Exception, ex: |
124 |
raise Exception("%s"%repr(ex)) |
125 |
else:
|
126 |
views = self.getViews()
|
127 |
if len(views) >0: |
128 |
for view in views: |
129 |
if name == view.getName():
|
130 |
return View(view)
|
131 |
|
132 |
return None |
133 |
|
134 |
def getTable(self, name=None): |
135 |
"""
|
136 |
Returns active Table Document, or Table Document called 'name' or None
|
137 |
:param name: Table Document name
|
138 |
:type name: string
|
139 |
"""
|
140 |
if name == None: |
141 |
try:
|
142 |
activeDocument = self.getActiveDocument()
|
143 |
if activeDocument == None: |
144 |
return None |
145 |
if isinstance(activeDocument, TableDocument): |
146 |
return Table(activeDocument)
|
147 |
except Exception, ex: |
148 |
raise Exception("%s"%repr(ex)) |
149 |
else:
|
150 |
tables = self.getDocuments("project.document.table") |
151 |
if len(tables) >0: |
152 |
for table in tables: |
153 |
if name == table.getName():
|
154 |
return Table(table)
|
155 |
|
156 |
return None |
157 |
|
158 |
def getProjectionCode(self): |
159 |
"""Returns Project projection code name string. This value is the
|
160 |
projects default projection that is fixed in Preferences tool, View
|
161 |
options. It's used when no view projection is defined.
|
162 |
|
163 |
"""
|
164 |
return self.getProjection().getFullCode() |
165 |
|
166 |
class ViewsIterator(object): |
167 |
|
168 |
def __init__(self,views): |
169 |
self.__views = views
|
170 |
self.__index = -1 |
171 |
|
172 |
def next(self): |
173 |
self.__index+=1 |
174 |
if self.__index >= self.__views.size() : |
175 |
raise StopIteration() |
176 |
return View(self.__views.get(self.__index)) |
177 |
|
178 |
class View(WrapperToJava): |
179 |
"""
|
180 |
Represents gvSIG view document
|
181 |
(org.gvsig.app.project.documents.view.DefaultViewDocument).
|
182 |
"""
|
183 |
def __init__(self,view): |
184 |
WrapperToJava.__init__(self,view)
|
185 |
|
186 |
def getLayer(self, name=None): |
187 |
"""
|
188 |
Returns one view layer. If name is None returns active
|
189 |
layer if the view has one, if name is not None returns layer called name
|
190 |
else returns None.
|
191 |
:param name: view name in Table Of Contents
|
192 |
:type name: string
|
193 |
:return: View
|
194 |
:return: None
|
195 |
"""
|
196 |
map = self.getMapContext();
|
197 |
if name == None: |
198 |
activeLayers = map.getLayers().getActives()
|
199 |
if len(activeLayers) != 1 : |
200 |
return None |
201 |
for layer in activeLayers: |
202 |
if not isinstance(layer, FLayers): |
203 |
return Layer(layer)
|
204 |
return None |
205 |
|
206 |
ls = self.getLayers()
|
207 |
for i in xrange(ls.getLayersCount()): |
208 |
l = ls.getLayer(i) |
209 |
if l.name == name:
|
210 |
return Layer(l)
|
211 |
|
212 |
return None |
213 |
|
214 |
def getMap(self): |
215 |
# org.gvsig.fmap.mapcontext.MapContext
|
216 |
"""Returns view mapContext"""
|
217 |
return self.getMapContext(); |
218 |
|
219 |
def addLayer(self, layer): |
220 |
"""
|
221 |
Adds a new layer to the view
|
222 |
:param layer: layer to add
|
223 |
:type layer: Layer
|
224 |
"""
|
225 |
if isinstance(layer, Layer): |
226 |
layer =layer() |
227 |
self.getMapContext().getLayers().addLayer(layer)
|
228 |
|
229 |
def getLayers(self): |
230 |
"""Returns iterable view layers set"""
|
231 |
map = self.getMapContext()
|
232 |
return Layers(map.getLayers()) |
233 |
|
234 |
def getGraphicsLayer(self): |
235 |
"""Returns view graphics layer
|
236 |
org.gvsig.fmap.mapcontext.layers.vectorial.impl.DefaultGraphicLayer
|
237 |
"""
|
238 |
return self.getMapContext().getGraphicsLayer() |
239 |
|
240 |
def getProjectionCode(self): |
241 |
"""Returns string view projection code name"""
|
242 |
return self.getProjection().getFullCode() |
243 |
|
244 |
def isProjected(self): |
245 |
"""Returns if view projection is projected."""
|
246 |
self.getProjection().isProjected()
|
247 |
|
248 |
class Layers(WrapperToJava): |
249 |
"""Iterable layers set
|
250 |
(org.gvsig.fmap.mapcontext.layers.FLayers)
|
251 |
"""
|
252 |
def __init__(self,layers): |
253 |
WrapperToJava.__init__(self, layers)
|
254 |
|
255 |
def __len__(self): |
256 |
return self.getLayersCount() |
257 |
|
258 |
def __getitem__(self, index): |
259 |
return self.getLayer(index) |
260 |
|
261 |
def __iter__(self): |
262 |
return LayersIterator(self) |
263 |
|
264 |
class LayersIterator(object): |
265 |
|
266 |
def __init__(self,layers): |
267 |
self.__layers = layers
|
268 |
self.__index = -1 |
269 |
|
270 |
def next(self): |
271 |
self.__index+=1 |
272 |
if self.__index >= self.__layers.getLayersCount() : |
273 |
raise StopIteration() |
274 |
return Layer(self.__layers.getLayer(self.__index)) |
275 |
|
276 |
class Store(WrapperToJava): |
277 |
"""Represents gvsig store. It's used as Table/Layer objects store
|
278 |
(org.gvsig.fmap.dal.feature.impl.DefaultFeatureStore)
|
279 |
"""
|
280 |
def __init__(self,store): |
281 |
WrapperToJava.__init__(self, store)
|
282 |
#self.data = None
|
283 |
self.fset = None |
284 |
|
285 |
def features(self, expresion = None, sortBy="", asc=True): |
286 |
"""Returns layer features set (FeatureSet class), with all layer features,
|
287 |
or selected featured if there are (could be empty feature set) or None if
|
288 |
gets an Exception.
|
289 |
:param expresion: filter to apply to the feature set to select
|
290 |
determinates features that match with expression
|
291 |
:type expresion: string
|
292 |
:param sortBy: name of attribute to sort
|
293 |
:type sortby: string
|
294 |
:param: asc: order
|
295 |
:type asc: boolean
|
296 |
:return: FeatureSet
|
297 |
"""
|
298 |
if expresion == None and sortBy =="": |
299 |
self.fset = self.getFeatureSet() |
300 |
else:
|
301 |
try:
|
302 |
application = ApplicationLocator.getManager() |
303 |
datamanager = application.getDataManager() |
304 |
query = self.createFeatureQuery()
|
305 |
if sortBy != "": |
306 |
order = FeatureQueryOrder() |
307 |
order.add(sortBy, asc) |
308 |
query.setOrder(order) |
309 |
if expresion != None: |
310 |
query.setFilter(datamanager.createExpresion(expresion)) |
311 |
self.fset = self.getFeatureSet(query) |
312 |
except Exception, e: |
313 |
return None |
314 |
|
315 |
return FeatureSet(self.fset) |
316 |
|
317 |
def edit(self): |
318 |
"""Set store in edition mode"""
|
319 |
if not self.isEditing(): |
320 |
self().edit()
|
321 |
|
322 |
def append(self, *valuesList, **values): |
323 |
"""
|
324 |
Creates a new feature from given values and insert it in the feature
|
325 |
set. If an error occurs raises RuntimeException.
|
326 |
:param values: dictionary with name property value or list named params
|
327 |
:type values: dict
|
328 |
"""
|
329 |
try:
|
330 |
if len(valuesList) ==1: |
331 |
values.update(valuesList[0])
|
332 |
|
333 |
if not self.isEditing(): |
334 |
self.edit()
|
335 |
f = self.createNewFeature()
|
336 |
|
337 |
if f == None: |
338 |
raise RuntimeError("Failed to create a new Feature") |
339 |
for k,v in values.iteritems(): |
340 |
f.set(k,v) |
341 |
self.insert(f)
|
342 |
except Throwable, ex:
|
343 |
raise RuntimeException("Can't append values %s to layer %s (%s)" % ( |
344 |
repr(values),
|
345 |
self.getName(),
|
346 |
str(ex)
|
347 |
) |
348 |
) |
349 |
|
350 |
def updateSchema(self, schema): |
351 |
"""
|
352 |
Updates store FeatureType. If an error occurs raises
|
353 |
RuntimeException.
|
354 |
"""
|
355 |
try:
|
356 |
self().update(schema._javaobj)
|
357 |
except Throwable, ex:
|
358 |
raise RuntimeException(repr(ex)) |
359 |
|
360 |
def update(self, feature): |
361 |
"""
|
362 |
Updates exist feature in the layer featureSet
|
363 |
:param editableFeature: editableFeature
|
364 |
:type editableFeature: Java editableFeature
|
365 |
"""
|
366 |
if not self.isEditing(): |
367 |
self.edit()
|
368 |
|
369 |
if not isinstance(feature, EditableFeature): |
370 |
feature = feature._javaobj |
371 |
self.fset.update(feature)
|
372 |
|
373 |
def getSchema(self): |
374 |
"""Returns store data attributtes"""
|
375 |
return Schema(self.getDefaultFeatureType()) |
376 |
|
377 |
def commit(self): |
378 |
"""
|
379 |
Finish store edition saving changes. If an error occurs raises Throwable
|
380 |
Exception.
|
381 |
"""
|
382 |
try:
|
383 |
self.finishEditing()
|
384 |
except Throwable, ex:
|
385 |
self.abort()
|
386 |
raise Throwable("Can't finish layer edition, cancelling changes. %s" % repr(ex)) |
387 |
|
388 |
def abort(self): |
389 |
"""Finish store edition withoout saving changes and disposes itself"""
|
390 |
self.cancelEditing()
|
391 |
self.dispose()
|
392 |
|
393 |
def getSelection(self): |
394 |
"""Returns store features selected set"""
|
395 |
return FeatureSet(self().getSelection()) |
396 |
|
397 |
class __DefaultTable__(WrapperToJava): |
398 |
def __init__(self,document, data): |
399 |
self.data = Store(data)
|
400 |
WrapperToJava.__init__(self,document)
|
401 |
self.selection = None |
402 |
|
403 |
def features(self, expresion = None, sortBy="", asc=True): |
404 |
"""
|
405 |
Returns data features set
|
406 |
:param expresion: filter to apply to the feature set to select
|
407 |
determinates features that match with expression
|
408 |
:type expresion: string
|
409 |
:return: FeatureSet
|
410 |
"""
|
411 |
return self.data.features(expresion, sortBy, asc) |
412 |
|
413 |
def edit(self): |
414 |
"""Sets data in edition mode"""
|
415 |
|
416 |
self.data.edit()
|
417 |
|
418 |
def append(self, *valuesList, **values): |
419 |
"""
|
420 |
Creates a new feature from given values and insert it in the feature set
|
421 |
:param values: dictionary with name property value or list named params
|
422 |
:type values: dict
|
423 |
"""
|
424 |
self.data.append(*valuesList, **values)
|
425 |
|
426 |
def updateSchema(self, schema): |
427 |
"""
|
428 |
Updates data data attributes properties with the given schema
|
429 |
"""
|
430 |
self.data.updateSchema(schema)
|
431 |
|
432 |
def update(self, feature): |
433 |
"""
|
434 |
Updates exist feature in the featureSet with the given feature
|
435 |
:param editableFeature: editableFeature
|
436 |
:type editableFeature: Java editableFeature
|
437 |
"""
|
438 |
self.data.update(feature)
|
439 |
|
440 |
def getSchema(self): |
441 |
"""Returns data attributes definition"""
|
442 |
return self.data.getSchema() |
443 |
|
444 |
def commit(self): |
445 |
"""Finish edition saving changes"""
|
446 |
self.data.commit()
|
447 |
|
448 |
def abort(self): |
449 |
"""Finish edition without saving changes"""
|
450 |
self.data.abort()
|
451 |
|
452 |
def getSelection(self): |
453 |
"""Returns features selected set"""
|
454 |
if self.selection == None: |
455 |
self.selection = Selection(self.data.getSelection()) |
456 |
|
457 |
return self.selection |
458 |
|
459 |
def select(self, selection): |
460 |
"""Inserts features in the features selection set"""
|
461 |
self.getSelection().select(selection)
|
462 |
|
463 |
def deselect(self, selection): |
464 |
"""Remove features in the features selection set"""
|
465 |
self.getSelection().deselect(selection)
|
466 |
|
467 |
def isSelected(feature): |
468 |
"""Returns True if given feature is selected"""
|
469 |
self.getSelection().isSelect(feature)
|
470 |
|
471 |
def getProjectionCode(self): |
472 |
"""Returns projection code name"""
|
473 |
return self.getProjection().getFullCode() |
474 |
|
475 |
|
476 |
class Table(__DefaultTable__): |
477 |
"""Represents gvsig table document
|
478 |
(org.gvsig.app.project.documents.table.TableDocument)
|
479 |
"""
|
480 |
def __init__(self,table): |
481 |
__DefaultTable__.__init__(self, table, table.getStore())
|
482 |
|
483 |
def getAssociatedLayer(self): |
484 |
"""Returns table associated layer or None if there're not associated
|
485 |
layer
|
486 |
"""
|
487 |
if self._javaobj.getAssociatedLayer(): |
488 |
return Layer(self._javaobj.getAssociatedLayer()) |
489 |
|
490 |
return None |
491 |
|
492 |
class Layer(__DefaultTable__): |
493 |
"""Represents gvsig layer document. It's a wrapper from
|
494 |
org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect class
|
495 |
"""
|
496 |
def __init__(self,layer): |
497 |
__DefaultTable__.__init__(self, layer, layer.getFeatureStore())
|
498 |
|
499 |
def getTypeVectorLayer(self): |
500 |
"""
|
501 |
Returns layer DefaultGeometryType class
|
502 |
To get the geometryType use DefaultGeometryType getType() method
|
503 |
To get the geometrySubType use DefaultGeometryType getSubType() method
|
504 |
"""
|
505 |
return self().getTypeVectorLayer() |
506 |
|
507 |
class FeatureSet(WrapperToJava): |
508 |
"""Represents gvSIG FeatureSet
|
509 |
(org.gvsig.fmap.dal.feature.impl.featureset.DefaultFeatureSet)
|
510 |
"""
|
511 |
def __init__(self,featureSet): |
512 |
WrapperToJava.__init__(self,featureSet)
|
513 |
|
514 |
def getCount(self): |
515 |
"""Returns the number of elements in the featureSet"""
|
516 |
return self.getSize() |
517 |
|
518 |
def update(self, feature): |
519 |
"""
|
520 |
Updates exist feature in the featureSet
|
521 |
:param editableFeature: editableFeature
|
522 |
:type editableFeature: Java editableFeature
|
523 |
"""
|
524 |
if not isinstance(feature, EditableFeature) and \ |
525 |
not isinstance(feature, DefaultEditableFeature): |
526 |
feature = feature._javaobj |
527 |
self().update(feature)
|
528 |
|
529 |
def __iter__(self): |
530 |
return Iterator(self.fastIterator()) |
531 |
|
532 |
class Selection(FeatureSet): |
533 |
"""Manage selected features set from a store. Represents gvSIG
|
534 |
org.gvsig.fmap.dal.feature.impl.DefaultFeatureSelection.
|
535 |
"""
|
536 |
def __init__(self, featureSet): |
537 |
FeatureSet.__init__(self, featureSet)
|
538 |
|
539 |
def select(self, selection): |
540 |
"""Inserts features in the features selection set"""
|
541 |
if isinstance(selection,Feature) or isinstance(selection, FeatureSet): |
542 |
self._javaobj.select(selection._javaobj)
|
543 |
else:
|
544 |
self._javaobj.select(selection)
|
545 |
|
546 |
def deselect(self, selection): |
547 |
"""Removes features in the features selection set"""
|
548 |
if isinstance(selection,Feature) or isinstance(selection, FeatureSet): |
549 |
self._javaobj.deselect(selection._javaobj)
|
550 |
else:
|
551 |
self._javaobj.deselect(selection)
|
552 |
|
553 |
def isSelected(feature): |
554 |
"""Returns True if given feature is selected"""
|
555 |
if isinstance(feature, Feature): |
556 |
self._javaobj.isSelect(feature._javaobj)
|
557 |
else:
|
558 |
self._javaobj.isSelect(feature)
|
559 |
|
560 |
def getCount(self): |
561 |
"""Returns the number of elements in the selection"""
|
562 |
return self.getSelectedCount() |
563 |
|
564 |
|
565 |
class Iterator(WrapperToJava): |
566 |
|
567 |
def __init__(self,iterator): |
568 |
WrapperToJava.__init__(self,iterator)
|
569 |
|
570 |
def next(self): |
571 |
if not self.hasNext(): |
572 |
raise StopIteration() |
573 |
return Feature(self().next()) |
574 |
|
575 |
class Feature(WrapperToJava): |
576 |
"""Represents feature data It's a wrapper from gvSIG
|
577 |
org.gvsig.fmap.dal.feature.impl.DefaultFeature class
|
578 |
"""
|
579 |
def __init__(self,feature): |
580 |
WrapperToJava.__init__(self,feature)
|
581 |
self.featureNoEditable = None |
582 |
|
583 |
def getCopy(self): |
584 |
return Feature(self._javaobj.getCopy()) |
585 |
|
586 |
def geometry(self): |
587 |
"""Returns feature geometry"""
|
588 |
return self.getDefaultGeometry() |
589 |
|
590 |
def getValues(self): |
591 |
"""Returns dictionary with the pair name, value, feature attributes"""
|
592 |
descriptor = self.getType()
|
593 |
items = dict()
|
594 |
for attr in descriptor.getAttributeDescriptors(): |
595 |
name = attr.getName() |
596 |
value = self.get(attr.getName())
|
597 |
items[name] = value |
598 |
return items
|
599 |
|
600 |
def edit(self): |
601 |
"""Returns editable feature instance"""
|
602 |
if not isinstance(self._javaobj, EditableFeature): |
603 |
self.featureNoEditable = self._javaobj |
604 |
self._javaobj = self._javaobj.getEditable() |
605 |
|
606 |
def getEditable(self): |
607 |
return Feature(self().getEditable()) |
608 |
|
609 |
def __getitem__(self,key): |
610 |
return self.get(key) |
611 |
|
612 |
def __getattr__(self,name): |
613 |
#
|
614 |
# FIX console error when try to introspect feature object
|
615 |
if name in ('__methods__'): |
616 |
return dict() |
617 |
elif name in ('__members__'): |
618 |
return self.getValues().keys() |
619 |
elif name == '__dict__': |
620 |
return self.getValues() |
621 |
|
622 |
try:
|
623 |
v = getattr(self._javaobj, name, None) |
624 |
if v == None: |
625 |
v = self().get(name)
|
626 |
return v
|
627 |
except Throwable, ex:
|
628 |
raise RuntimeException("Can't access to attribute %s of feature (%s)" % (name, str(ex))) |
629 |
|
630 |
class Schema(WrapperToJava): |
631 |
"""Stores data properties definition. Represents gvSIG FeatureType
|
632 |
(org.gvsig.fmap.dal.feature.impl.DefaultFeatureType)
|
633 |
"""
|
634 |
|
635 |
def __init__(self, featureType): |
636 |
WrapperToJava.__init__(self,featureType)
|
637 |
self.featureTypeNoEditable = None |
638 |
|
639 |
def append(self, name, type, size=None, default=None, precision=4): |
640 |
"""Adds new property to feature properties definition. If error occurs
|
641 |
raises RuntimeError.
|
642 |
:param name: Feature property name
|
643 |
:type name: String
|
644 |
:param type: Feature property type
|
645 |
:type name: String
|
646 |
:param size: Feature property size
|
647 |
:type size: int
|
648 |
:param default: Feature property default value
|
649 |
:return: new atribute
|
650 |
"""
|
651 |
if not isinstance(self._javaobj, EditableFeatureType): |
652 |
self.modify()
|
653 |
|
654 |
if isinstance(type, str): |
655 |
try:
|
656 |
application = ApplicationLocator.getManager() |
657 |
datamanager = application.getDataManager() |
658 |
dataTypes = application.getDataTypesManager() |
659 |
type = dataTypes.getType(type) #dataType constant value from string |
660 |
except:
|
661 |
raise RuntimeError( |
662 |
"Feature Property Data type (%s) is not valid. name=%s, type=%s, size=%s, default=%s)" % (
|
663 |
type,
|
664 |
name, |
665 |
type,
|
666 |
size, |
667 |
default |
668 |
) |
669 |
) |
670 |
if isinstance(type, int): |
671 |
try:
|
672 |
type = dataTypes.get(type)
|
673 |
except:
|
674 |
raise RuntimeError( |
675 |
"Data type (%s) is not valid. name=%s, type=%s, size=%s, default=%s)" % (
|
676 |
type,
|
677 |
name, |
678 |
type,
|
679 |
size, |
680 |
default |
681 |
) |
682 |
) |
683 |
|
684 |
attribute = self.add(name, type.getType()) |
685 |
|
686 |
if size != None: |
687 |
attribute.setSize(size) |
688 |
|
689 |
if default != None: |
690 |
attribute.setDefaultValue(default) |
691 |
|
692 |
if precision != None and type.getType() in (DataTypes.DOUBLE, DataTypes.FLOAT): |
693 |
attribute.setPrecision(precision) |
694 |
|
695 |
if type.getType() == DataTypes.GEOMETRY and self.getDefaultGeometryAttributeName()==None: |
696 |
self.setDefaultGeometryAttributeName(name)
|
697 |
|
698 |
return attribute
|
699 |
|
700 |
def __getitem__(self, name): |
701 |
try:
|
702 |
return self._javaobj.getAttributeDescriptor(name) |
703 |
except java.lang.IndexOutOfBoundsException:
|
704 |
raise StopIteration |
705 |
|
706 |
def get(self, name, default=None): |
707 |
"""Returns a feature attribute descriptor that contains information about
|
708 |
one feature attribute, such as its name, data type or precision.
|
709 |
:param name: Attribute name
|
710 |
:type name: string
|
711 |
:param default: Value to return if no attribute name found.
|
712 |
:return: AttributeDescriptor
|
713 |
"""
|
714 |
x = self.getAttributeDescriptor(name)
|
715 |
if x == None: |
716 |
return default
|
717 |
return x
|
718 |
|
719 |
def getAttrNames(self): |
720 |
"""Returns a list with attributes names"""
|
721 |
if not self.getAttributeDescriptors(): |
722 |
return None |
723 |
|
724 |
return [attr.getName() for attr in self.getAttributeDescriptors()] |
725 |
|
726 |
|
727 |
def getCopy(self): |
728 |
"""Returns a itself clone"""
|
729 |
return Schema(self().getCopy()) |
730 |
|
731 |
def modify(self): |
732 |
"""Sets edit mode"""
|
733 |
if not isinstance(self._javaobj, EditableFeatureType): |
734 |
self.featureTypeNoEditable = self._javaobj |
735 |
self._javaobj = self._javaobj.getEditable() |
736 |
|
737 |
|
738 |
#=====================#
|
739 |
# Vectorial Functions #
|
740 |
#=====================#
|
741 |
|
742 |
def createSchema(schema = None): |
743 |
"""Returns attributes definition. If Schema is recived then makes a copy and
|
744 |
returns editable instance. Otherwise returns empty Schema.
|
745 |
:param schema: Schema to make a copy
|
746 |
:type schema: Schema
|
747 |
"""
|
748 |
if isinstance(schema, Schema): |
749 |
try:
|
750 |
s = schema.getCopy() |
751 |
s.modify() |
752 |
return s
|
753 |
except:
|
754 |
pass
|
755 |
|
756 |
application = ApplicationLocator.getManager() |
757 |
datamanager = application.getDataManager() |
758 |
return Schema(datamanager.createFeatureType())
|
759 |
|
760 |
def createLayer(schema, servertype, layertype=None, **parameters): |
761 |
"""
|
762 |
Returns new layer
|
763 |
:param schema: layer data definition
|
764 |
:type schema: Schema
|
765 |
:param servertype:
|
766 |
:type servertype: string
|
767 |
:return: new layer
|
768 |
:rtype: Layer
|
769 |
:raise: RuntimeException
|
770 |
"""
|
771 |
if layertype == None: |
772 |
layertype = servertype |
773 |
servertype = "FilesystemExplorer"
|
774 |
|
775 |
if layertype == "Shape" : |
776 |
if schema.get("GEOMETRY",None) == None: |
777 |
raise RuntimeException("Shape need a field named GEOMETRY in the schema") |
778 |
|
779 |
if parameters["geometryType"] == None: |
780 |
raise RuntimeException("Invalid geometry type for new layer") |
781 |
|
782 |
try:
|
783 |
application = ApplicationLocator.getManager() |
784 |
datamanager = application.getDataManager() |
785 |
|
786 |
mapcontextmanager = application.getMapContextManager() |
787 |
|
788 |
server_parameters = datamanager.createServerExplorerParameters(servertype) |
789 |
copyToDynObject(parameters, server_parameters) |
790 |
|
791 |
server = datamanager.openServerExplorer(servertype, server_parameters) |
792 |
|
793 |
store_parameters = server.getAddParameters(layertype) |
794 |
copyToDynObject(parameters, store_parameters) |
795 |
store_parameters.setDefaultFeatureType(schema()) |
796 |
|
797 |
server.add(layertype, store_parameters, True)
|
798 |
|
799 |
store = datamanager.openStore(layertype, store_parameters) |
800 |
|
801 |
layer = mapcontextmanager.createLayer(store.getName(), store) |
802 |
|
803 |
return Layer(layer)
|
804 |
except Throwable, ex:
|
805 |
raise RuntimeException("Can't create layer, "+ str(ex)) |
806 |
|
807 |
def loadShapeFile(shpFile, CRS="CRS:84"): |
808 |
"""
|
809 |
Add existing shape file to the view. Returns Layer shape file
|
810 |
:param shpFile: absolute file path
|
811 |
:type: shpFile: string
|
812 |
:param CRS: projection code
|
813 |
:type CRS: string
|
814 |
:return: the shape
|
815 |
:type return: Layer
|
816 |
"""
|
817 |
layer = loadLayer('Shape', shpFile=shpFile, CRS=CRS)
|
818 |
currentView().addLayer(layer) |
819 |
layer.setActive(True)
|
820 |
return Layer(layer)
|
821 |
|
822 |
def loadLayer(layerType, **parameters): |
823 |
try:
|
824 |
application = ApplicationLocator.getManager() |
825 |
datamanager = application.getDataManager() |
826 |
mapcontextmanager = application.getMapContextManager() |
827 |
store_parameters = datamanager.createStoreParameters(layerType) |
828 |
copyToDynObject(parameters, store_parameters) |
829 |
store = datamanager.openStore(layerType, store_parameters) |
830 |
layer = mapcontextmanager.createLayer(store.getName(), store) |
831 |
except Throwable, ex:
|
832 |
raise RuntimeException("Can't load layer, "+ str(ex)) |
833 |
|
834 |
return layer
|
835 |
|
836 |
def createShape(definition, filename, geometryType, CRS="CRS:84"): |
837 |
"""
|
838 |
Return new shape layer
|
839 |
:param definition: layer data definition
|
840 |
:type definition: Schema
|
841 |
:param filename: absolute path for shape files.
|
842 |
:type filename: string
|
843 |
:param geometryType: geometry type for shape
|
844 |
:type geometryType: string
|
845 |
:return: new shape layer
|
846 |
:rtype: Layer
|
847 |
"""
|
848 |
return createLayer(
|
849 |
definition, |
850 |
"FilesystemExplorer",
|
851 |
"Shape",
|
852 |
shpFile=filename, |
853 |
CRS=CRS, |
854 |
geometryType = geometryType |
855 |
) |
856 |
|
857 |
def createTable(schema, servertype, tableType=None, **parameters): |
858 |
"""Creates a new Table document"""
|
859 |
if tableType == None: |
860 |
tableType = servertype |
861 |
servertype = "FilesystemExplorer"
|
862 |
|
863 |
try:
|
864 |
application = ApplicationLocator.getManager() |
865 |
datamanager = application.getDataManager() |
866 |
|
867 |
server_parameters = datamanager.createServerExplorerParameters(servertype) |
868 |
copyToDynObject(parameters, server_parameters) |
869 |
|
870 |
server = datamanager.openServerExplorer(servertype, server_parameters) |
871 |
|
872 |
store_parameters = server.getAddParameters(tableType) |
873 |
copyToDynObject(parameters, store_parameters) |
874 |
store_parameters.setDefaultFeatureType(schema()) |
875 |
|
876 |
server.add(tableType, store_parameters, True)
|
877 |
|
878 |
store = datamanager.openStore(tableType, store_parameters) |
879 |
|
880 |
return Table(store)
|
881 |
|
882 |
except Throwable, ex:
|
883 |
raise RuntimeException("Can't create table, "+ str(ex)) |
884 |
|
885 |
def createDBF(definition, DbfFile, CRS="CRS:84"): |
886 |
"""
|
887 |
Creates a new dbf document
|
888 |
:param definition: layer data definition
|
889 |
:type definition: Schema
|
890 |
:param DbfFile: absolute path for shape files.
|
891 |
:type DbfFile: string
|
892 |
:return: new dbf
|
893 |
:rtype: Table
|
894 |
"""
|
895 |
return createTable(
|
896 |
definition, |
897 |
"FilesystemExplorer",
|
898 |
"DBF",
|
899 |
DbfFile=DbfFile, |
900 |
CRS=CRS, |
901 |
) |
902 |
|
903 |
#=====================#
|
904 |
# Documents Functions #
|
905 |
#=====================#
|
906 |
|
907 |
def currentProject(): |
908 |
"""
|
909 |
Returns current gvSIG proyect
|
910 |
:return: Proyect
|
911 |
"""
|
912 |
application = ApplicationLocator.getManager() |
913 |
project = application.getCurrentProject() |
914 |
return Project(project)
|
915 |
|
916 |
def currentDocument(documentClass = None): |
917 |
"""
|
918 |
Returns the current active document if it's a DocumentTable or
|
919 |
DocumentView2D return None
|
920 |
:return: Active document, None
|
921 |
"""
|
922 |
application = ApplicationLocator.getManager() |
923 |
|
924 |
if documentClass == None: |
925 |
doc = application.getActiveDocument() |
926 |
else:
|
927 |
doc = application.getActiveDocument(documentClass) |
928 |
if isinstance(doc, TableDocument): |
929 |
return Table(doc)
|
930 |
if isinstance(doc, ViewDocument): |
931 |
return View(doc)
|
932 |
|
933 |
return None |
934 |
|
935 |
def currentTable(): |
936 |
"""
|
937 |
Returns active table document or None
|
938 |
:return: Table or None
|
939 |
"""
|
940 |
return currentDocument(TableDocument)
|
941 |
|
942 |
def currentView(): |
943 |
"""
|
944 |
Returns the current active view document or None
|
945 |
:return: View or None
|
946 |
"""
|
947 |
return currentDocument(ViewDocument)
|
948 |
|
949 |
def currentLayer(): |
950 |
"""
|
951 |
Returns current view active layer or None
|
952 |
:return: gvSIG active layer
|
953 |
"""
|
954 |
try:
|
955 |
return currentView().getLayer()
|
956 |
except:
|
957 |
return None |
958 |
|
959 |
#=====================#
|
960 |
# Simbology Functions #
|
961 |
#=====================#
|
962 |
COLORS = { |
963 |
'black': Color.black,
|
964 |
'blue': Color.blue,
|
965 |
'cyan': Color.cyan,
|
966 |
'darkGray': Color.darkGray,
|
967 |
'gray': Color.gray,
|
968 |
'green': Color.green,
|
969 |
'lightGray': Color.lightGray,
|
970 |
'magenta': Color.magenta,
|
971 |
'orange': Color.orange,
|
972 |
'pink': Color.pink,
|
973 |
'red': Color.red,
|
974 |
'white': Color.white,
|
975 |
'yellow': Color.yellow,
|
976 |
} |
977 |
|
978 |
def simplePointSymbol(color=None): |
979 |
"""
|
980 |
Returns simple point symbol using parameter color. If no color
|
981 |
use a ramdom color
|
982 |
:param color: String color name or Java awt Color
|
983 |
:return: gvSIG point symbol
|
984 |
"""
|
985 |
if isinstance(color, str) and COLORS.has_key(color.lower()): |
986 |
color = COLORS.get(color) |
987 |
|
988 |
if not isinstance(color, Color): |
989 |
color = getDefaultColor() |
990 |
|
991 |
return MapContextLocator.getSymbolManager().createSymbol(
|
992 |
Geometry.TYPES.POINT, color) |
993 |
|
994 |
def simpleLineSymbol(color=None): |
995 |
"""
|
996 |
Returns simple line symbol using parameter color. If no color use a
|
997 |
ramdom color
|
998 |
:param color: String color name or Java awt Color
|
999 |
:return: gvSIG line symbol
|
1000 |
|
1001 |
"""
|
1002 |
if isinstance(color, str) and COLORS.has_key(color.lower()): |
1003 |
color = COLORS.get(color) |
1004 |
|
1005 |
if not isinstance(color, Color): |
1006 |
color = getDefaultColor() |
1007 |
|
1008 |
return MapContextLocator.getSymbolManager().createSymbol(
|
1009 |
Geometry.TYPES.CURVE, color) |
1010 |
|
1011 |
def simplePolygonSymbol(color = None): |
1012 |
"""
|
1013 |
Returns simple polygon symbol using parameter color. If no color
|
1014 |
use a ramdom color.
|
1015 |
:param color: String color name or Java awt Color
|
1016 |
:return: gvSIG polygon symbol
|
1017 |
"""
|
1018 |
if isinstance(color, str) and COLORS.has_key(color.lower()): |
1019 |
color = COLORS.get(color) |
1020 |
|
1021 |
if not isinstance(color, Color): |
1022 |
color = getDefaultColor() |
1023 |
|
1024 |
return MapContextLocator.getSymbolManager().createSymbol(
|
1025 |
Geometry.TYPES.SURFACE, color) |
1026 |
|
1027 |
|
1028 |
#=========================================#
|
1029 |
# gvSIG Application Preferences Functions #
|
1030 |
#=========================================#
|
1031 |
|
1032 |
def getDataFolder(): |
1033 |
"""
|
1034 |
Returns gvSIG data folder. This folder is defined in application
|
1035 |
preferences. If is not defined returns None.
|
1036 |
"""
|
1037 |
return Preferences.userRoot().node("gvsig.foldering").get('DataFolder', None) |
1038 |
|
1039 |
def getProjectsFolder(): |
1040 |
"""
|
1041 |
Returns gvSIG projects folder. This folder is defined in application
|
1042 |
preferences. If is not defined returns None.
|
1043 |
"""
|
1044 |
return Preferences.userRoot().node("gvsig.foldering").get( |
1045 |
'ProjectsFolder', None) |
1046 |
|
1047 |
def getColorFromRGB(r, g, b, a=None): |
1048 |
"""
|
1049 |
Returns an sRGB color with the specified red, green, blue, and alpha
|
1050 |
(optional) values in the range (0 - 255).
|
1051 |
"""
|
1052 |
if a:
|
1053 |
color = Color(r, g, b, a) |
1054 |
else:
|
1055 |
color = Color(r, g, b) |
1056 |
|
1057 |
return color
|
1058 |
|
1059 |
def getDefaultColor(c = None): |
1060 |
"""Returns gvsig default symbol fill color or ramdom color"""
|
1061 |
if MapContextLocator.getSymbolManager().isDefaultSymbolFillColorAleatory():
|
1062 |
color = Color(random.randint(0-255), |
1063 |
random.randint(0-255), |
1064 |
random.randint(0-255) |
1065 |
) |
1066 |
else:
|
1067 |
sp = MapContextLocator.getSymbolManager().getSymbolPreferences() |
1068 |
color = sp.getDefaultSymbolFillColor() |
1069 |
|
1070 |
return color
|
1071 |
|
1072 |
#================#
|
1073 |
# OTHER #
|
1074 |
#================#
|
1075 |
|
1076 |
def getCRS(crs): |
1077 |
"""Returns Projection from string code (i.e. CRS:84) if exist or None if
|
1078 |
not.
|
1079 |
"""
|
1080 |
try:
|
1081 |
return CRSFactory.getCRS(crs)
|
1082 |
except:
|
1083 |
return None |
1084 |
|
1085 |
def copyToDynObject(values, target): |
1086 |
definition = target.getDynClass(); |
1087 |
fields = definition.getDynFields(); |
1088 |
for field in fields: |
1089 |
name = field.getName() |
1090 |
keys = values.keys() |
1091 |
for k in keys: |
1092 |
if k.lower() == name.lower():
|
1093 |
target.setDynValue(name, values[name]) |
1094 |
break
|
1095 |
# ====================================
|
1096 |
#
|
1097 |
|
1098 |
def main(): |
1099 |
layer = currentLayer() |
1100 |
schema = createSchema() |
1101 |
schema.append("ID", "String", 50) |
1102 |
schema.append("GEOMETRY", "Geometry") |
1103 |
|
1104 |
output = createLayer( |
1105 |
schema, |
1106 |
"FilesystemExplorer",
|
1107 |
"Shape",
|
1108 |
shpFile="/tmp/pp.shp",
|
1109 |
CRS="EPSG:23030",
|
1110 |
geometryType=POINT |
1111 |
) |
1112 |
|
1113 |
for feature in layer.features(): |
1114 |
point = feature.geometry().centroid() |
1115 |
output.append(ID=feature.ID, GEOMETRY=point) |
1116 |
|
1117 |
output.commit() |
1118 |
|
1119 |
currentView().addLayer(output()) |