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