Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting.app / trunk / org.gvsig.scripting.app / org.gvsig.scripting.app.extension / src / main / resources / scripting / lib / gvsig.py @ 424

History | View | Annotate | Download (30.8 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 424 vacevedo
Also contais functions to manage vectorial data and other utility
30
functions
31 401 vacevedo
"""
32
33 355 jjdelcerro
__author__ = """Antonio Carrasco Valero
34
Model Driven Development sl and Antonio Carrasco Valero
35 362 vacevedo
<carrasco@modeldd.org>
36 383 vacevedo
Victor Acevedo Royer <vacevedor@gvsig.com>, <vacevedor@gmail.com>
37 362 vacevedo
"""
38
39 355 jjdelcerro
__docformat__ = 'plaintext'
40
41 388 vacevedo
from java.awt import Color
42 355 jjdelcerro
43
from java.lang import RuntimeException
44
from java.lang import Throwable
45
46 383 vacevedo
from java.util.prefs import Preferences
47
48 355 jjdelcerro
from org.gvsig.app import ApplicationLocator
49 362 vacevedo
from org.gvsig.app.project.documents.view import ViewDocument
50 401 vacevedo
from org.gvsig.app.project.documents.table import TableDocument
51 355 jjdelcerro
52 417 vacevedo
from org.gvsig.fmap.crs import CRSFactory
53
54 362 vacevedo
from org.gvsig.fmap.mapcontext import MapContextLocator
55
from org.gvsig.fmap.mapcontext.layers import FLayers
56 417 vacevedo
57 362 vacevedo
from org.gvsig.fmap.dal import DALLocator, DataTypes
58 424 vacevedo
from org.gvsig.fmap.dal.feature import EditableFeature, \
59
    EditableFeatureType, FeatureQueryOrder
60 383 vacevedo
from org.gvsig.fmap.dal.feature.impl import DefaultEditableFeature
61 355 jjdelcerro
62 417 vacevedo
from org.gvsig.fmap.geom import Geometry
63
64 355 jjdelcerro
from org.gvsig.tools import ToolsLocator
65
66
import thread
67 388 vacevedo
import random
68 355 jjdelcerro
69 362 vacevedo
70 355 jjdelcerro
def runTask(name, function, *args):
71
  manager = ToolsLocator.getTaskStatusManager()
72
  status = manager.createDefaultSimpleTaskStatus(name)
73
  status.add()
74
  args = list(args)
75
  args.append(status)
76
  try:
77
    thread.start_new_thread(function, tuple(args))
78
    status.terminate()
79
  except Exception,e:
80
    status.abort()
81
    raise e
82
83
84
class WrapperToJava(object):
85 424 vacevedo
  """Creates a wrapper that allows python object access to the Java object
86 362 vacevedo
  properties and methods
87
  """
88 355 jjdelcerro
  def __init__(self, javaobj):
89
    if javaobj == None:
90
      raise RuntimeException("Can't create "+ self.__class__.__name__)
91
    self._javaobj = javaobj
92
93
  def __call__(self):
94
    return self._javaobj
95
96
  def __getattr__(self,name):
97
    return getattr(self._javaobj,name)
98
99
class Project(WrapperToJava):
100 424 vacevedo
  """Represents a gvSIG project (org.gvsig.app.project.DefaultProject)"""
101
102 362 vacevedo
  def __init__(self, project):
103
    WrapperToJava.__init__(self, project)
104
105 355 jjdelcerro
  def getView(self, name=None):
106 362 vacevedo
    """
107 424 vacevedo
    Returns active view, or view called 'name'  or None
108
    :param name: view name
109
    :type name: string
110 362 vacevedo
    """
111 355 jjdelcerro
    if name == None:
112 362 vacevedo
      try:
113
        activeDocument = self.getActiveDocument()
114 402 vacevedo
        if activeDocument == None:
115
            return None
116
        if isinstance(activeDocument, ViewDocument):
117
            return View(activeDocument)
118 362 vacevedo
      except Exception, ex:
119
        raise Exception("%s"%repr(ex))
120
    else:
121
      views = self.getViews()
122
      if len(views) >0:
123
        for view in views:
124
          if name == view.getName():
125 402 vacevedo
            return View(view)
126 355 jjdelcerro
127 402 vacevedo
    return None
128 362 vacevedo
129
  def getTable(self, name=None):
130
    """
131 424 vacevedo
    Returns active Table Document, or Table Document called 'name'  or None
132
    :param name: Table Document name
133
    :type name: string
134 362 vacevedo
    """
135
    if name == None:
136
      try:
137
        activeDocument = self.getActiveDocument()
138 402 vacevedo
        if activeDocument == None:
139
            return None
140
        if isinstance(activeDocument, TableDocument):
141
            return Table(activeDocument)
142 362 vacevedo
      except Exception, ex:
143
        raise Exception("%s"%repr(ex))
144
    else:
145
      tables = self.getDocuments("project.document.table")
146
      if len(tables) >0:
147
        for table in tables:
148
          if name == table.getName():
149 402 vacevedo
            return Table(table)
150 362 vacevedo
151 417 vacevedo
    return None
152 383 vacevedo
153
  def getProjectionCode(self):
154 424 vacevedo
    """Returns Project projection code name string. This value is the
155
    projects default projection that is fixed in Preferences tool, View
156
    options. It's used when no view projection is defined.
157

158
    """
159 383 vacevedo
    return self.getProjection().getFullCode()
160 424 vacevedo
161 355 jjdelcerro
162
class View(WrapperToJava):
163 362 vacevedo
  """
164 424 vacevedo
  Represents gvSIG view document
165
  (org.gvsig.app.project.documents.view.DefaultViewDocument).
166 362 vacevedo
  """
167 355 jjdelcerro
  def __init__(self,view):
168
    WrapperToJava.__init__(self,view)
169 362 vacevedo
170 355 jjdelcerro
  def getLayer(self, name=None):
171 362 vacevedo
    """
172 424 vacevedo
    Returns one view layer. If name is None returns active
173
    layer if the view has one, if name is not None returns layer called name
174
    else returns None.
175
    :param name: view name in Table Of Contents
176
    :type name: string
177
    :return: View
178
    :return: None
179 362 vacevedo
    """
180
    map = self.getMapContext();
181 355 jjdelcerro
    if name == None:
182
      activeLayers = map.getLayers().getActives()
183
      if len(activeLayers) != 1 :
184 417 vacevedo
        return None
185 362 vacevedo
      for layer in activeLayers:
186
        if not isinstance(layer, FLayers):
187
          return Layer(layer)
188 417 vacevedo
      return None
189 355 jjdelcerro
190 362 vacevedo
    ls = self.getLayers()
191
    for i in xrange(ls.getLayersCount()):
192
      l = ls.getLayer(i)
193
      if l.name == name:
194 355 jjdelcerro
        return Layer(l)
195
196 362 vacevedo
    return None
197 355 jjdelcerro
198
  def getMap(self):
199 424 vacevedo
    # org.gvsig.fmap.mapcontext.MapContext
200
    """Returns view mapContext"""
201 355 jjdelcerro
    return self.getMapContext();
202
203
  def addLayer(self, layer):
204 424 vacevedo
    """
205
    Adds a new layer to the view
206
    :param layer: layer to add
207
    :type layer: Layer
208
    """
209 362 vacevedo
    if isinstance(layer, Layer):
210
      layer =layer()
211 355 jjdelcerro
    self.getMapContext().getLayers().addLayer(layer)
212
213
  def getLayers(self):
214 424 vacevedo
    """Returns iterable view layers set"""
215 417 vacevedo
    map = self.getMapContext()
216 355 jjdelcerro
    return Layers(map.getLayers())
217
218
  def getGraphicsLayer(self):
219 424 vacevedo
    """Returns view graphics layer
220
    org.gvsig.fmap.mapcontext.layers.vectorial.impl.DefaultGraphicLayer
221 362 vacevedo
    """
222 355 jjdelcerro
    return self.getMapContext().getGraphicsLayer()
223
224 383 vacevedo
  def getProjectionCode(self):
225 424 vacevedo
    """Returns string view projection code name"""
226 383 vacevedo
    return self.getProjection().getFullCode()
227
228 424 vacevedo
  def isProjected(self):
229
    """Returns if view projection is projected."""
230
    self.getProjection().isProjected():
231
232 355 jjdelcerro
class Layers(WrapperToJava):
233 424 vacevedo
  """Iterable layers set
234
  (org.gvsig.fmap.mapcontext.layers.FLayers)
235 362 vacevedo
  """
236 355 jjdelcerro
  def __init__(self,layers):
237
    WrapperToJava.__init__(self, layers)
238
239
  def __len__(self):
240
    return self.getLayersCount()
241
242
  def __getitem__(self, index):
243
    return self.getLayer(index)
244
245
  def __iter__(self):
246
    return LayersIterator(self)
247
248
class LayersIterator(object):
249
250
  def __init__(self,layers):
251
    self.__layers = layers
252 383 vacevedo
    self.__index = -1
253 355 jjdelcerro
254
  def next(self):
255 383 vacevedo
    self.__index+=1
256
    if self.__index >= self.__layers.getLayersCount() :
257 355 jjdelcerro
      raise StopIteration()
258 383 vacevedo
    return Layer(self.__layers.getLayer(self.__index))
259 362 vacevedo
260
class Store(WrapperToJava):
261 424 vacevedo
  """Represents gvsig store. It's used as Table/Layer objects store
262
  (org.gvsig.fmap.dal.feature.impl.DefaultFeatureStore)
263 362 vacevedo
  """
264
  def __init__(self,store):
265
    WrapperToJava.__init__(self, store)
266
    #self.data = None
267
    self.fset = None
268
269 383 vacevedo
  def features(self, expresion = None, sortBy="", asc=True):
270 424 vacevedo
    """Returns layer features set (FeatureSet class), with all layer features,
271
    or selected featured if there are (could be empty feature set) or None if
272
    gets an Exception.
273
    :param expresion: filter to apply to the feature set to select
274 417 vacevedo
        determinates features that match with expression
275 424 vacevedo
    :type expresion: string
276
    :param sortBy: name of attribute to sort
277
    :type sortby: string
278
    :param: asc: order
279
    :type asc: boolean
280
    :return: FeatureSet
281
    """
282 383 vacevedo
    if expresion == None and sortBy =="":
283 362 vacevedo
      self.fset = self.getFeatureSet()
284
    else:
285 424 vacevedo
      try:
286
        application = ApplicationLocator.getManager()
287
        datamanager =  application.getDataManager()
288
        query = self.createFeatureQuery()
289
        if sortBy != "":
290
            order = FeatureQueryOrder()
291
            order.add(sortBy, asc)
292
            query.setOrder(order)
293
        if expresion != None:
294
            query.setFilter(datamanager.createExpresion(expresion))
295
        self.fset = self.getFeatureSet(query)
296
      except Exception, e:
297
        return None
298 362 vacevedo
299 383 vacevedo
    return FeatureSet(self.fset)
300 355 jjdelcerro
301 362 vacevedo
  def edit(self):
302 424 vacevedo
    """Set store in edition mode"""
303 362 vacevedo
    if not self.isEditing():
304
        self().edit()
305
306
  def append(self, *valuesList, **values):
307
    """
308 424 vacevedo
    Creates a new feature from given values and insert it in the feature
309
    set. If an error occurs raises RuntimeException.
310
    :param values: dictionary with name property value or list named params
311
    :type values: dict
312 362 vacevedo
    """
313 355 jjdelcerro
    try:
314 362 vacevedo
      if len(valuesList) ==1:
315
        values.update(valuesList[0])
316
317
      if not self.isEditing():
318
        self.edit()
319
      f = self.createNewFeature()
320
321 355 jjdelcerro
      if f == None:
322
        raise RuntimeError("Failed to create a new Feature")
323
      for k,v in values.iteritems():
324
        f.set(k,v)
325 362 vacevedo
        self.insert(f)
326 355 jjdelcerro
    except Throwable, ex:
327
      raise RuntimeException("Can't append values %s to layer %s (%s)" % (
328
        repr(values),
329
        self.getName(),
330
        str(ex)
331
        )
332
      )
333
334 362 vacevedo
  def updateSchema(self, schema):
335 424 vacevedo
    """
336
    Updates store FeatureType. If an error occurs raises
337
    RuntimeException.
338
    """
339 362 vacevedo
    try:
340
      self().update(schema._javaobj)
341
    except Throwable, ex:
342
      raise RuntimeException(repr(ex))
343
344
  def update(self, feature):
345
    """
346 424 vacevedo
    Updates exist feature in the layer featureSet
347
    :param editableFeature: editableFeature
348
    :type editableFeature: Java editableFeature
349
    """
350
    if not self.isEditing():
351
      self.edit()
352 362 vacevedo
353
    if not isinstance(feature, EditableFeature):
354
      feature = feature._javaobj
355
    self.fset.update(feature)
356
357
  def getSchema(self):
358 424 vacevedo
    """Returns store data attributtes"""
359 362 vacevedo
    return Schema(self.getDefaultFeatureType())
360
361 355 jjdelcerro
  def commit(self):
362 362 vacevedo
    """
363 424 vacevedo
    Finish store edition saving changes. If an error occurs raises Throwable
364
    Exception.
365 362 vacevedo
    """
366
    try:
367
      self.finishEditing()
368
    except Throwable, ex:
369
      self.abort()
370
      raise Throwable("Can't finish layer edition, cancelling changes. %s" % repr(ex))
371 355 jjdelcerro
372
  def abort(self):
373 424 vacevedo
    """Finish store edition withoout saving changes and disposes itself"""
374 362 vacevedo
    self.cancelEditing()
375
    self.dispose()
376 355 jjdelcerro
377
  def getSelection(self):
378 424 vacevedo
    """Returns store features selected set"""
379 383 vacevedo
    return FeatureSet(self().getSelection())
380 362 vacevedo
381
class __DefaultTable__(WrapperToJava):
382
  def __init__(self,document, data):
383
    self.data = Store(data)
384
    WrapperToJava.__init__(self,document)
385 385 vacevedo
    self.selection = None
386 362 vacevedo
387 383 vacevedo
  def features(self, expresion = None, sortBy="", asc=True):
388 362 vacevedo
    """
389 424 vacevedo
    Returns data features set
390
    :param expresion: filter to apply to the feature set to select
391 417 vacevedo
         determinates features that match with expression
392 424 vacevedo
    :type expresion: string
393
    :return: FeatureSet
394 362 vacevedo
    """
395 383 vacevedo
    return self.data.features(expresion, sortBy, asc)
396 362 vacevedo
397
  def edit(self):
398 424 vacevedo
    """Sets data in edition mode"""
399 362 vacevedo
400
    self.data.edit()
401
402
  def append(self, *valuesList, **values):
403
    """
404 424 vacevedo
    Creates a new feature from given values and insert it in the feature set
405
    :param values: dictionary with name property value or list named params
406
    :type values: dict
407 362 vacevedo
    """
408
    self.data.append(*valuesList, **values)
409
410
  def updateSchema(self, schema):
411 385 vacevedo
    """
412 424 vacevedo
    Updates data data attributes properties with the given schema
413 385 vacevedo
    """
414 362 vacevedo
    self.data.updateSchema(schema)
415
416
  def update(self, feature):
417
    """
418 424 vacevedo
    Updates exist feature in the featureSet with the given feature
419
    :param editableFeature: editableFeature
420
    :type editableFeature: Java editableFeature
421 362 vacevedo
    """
422
    self.data.update(feature)
423
424
  def getSchema(self):
425 424 vacevedo
    """Returns data attributes definition"""
426 362 vacevedo
    return self.data.getSchema()
427
428
  def commit(self):
429 424 vacevedo
    """Finish edition saving changes"""
430 362 vacevedo
    self.data.commit()
431
432
  def abort(self):
433 424 vacevedo
    """Finish edition without saving changes"""
434 362 vacevedo
    self.data.abort()
435
436
  def getSelection(self):
437 424 vacevedo
    """Returns features selected set"""
438 385 vacevedo
    if self.selection == None:
439 424 vacevedo
      self.selection = Selection(self.data.getSelection())
440 385 vacevedo
441
    return self.selection
442 383 vacevedo
443 385 vacevedo
  def select(self, selection):
444 424 vacevedo
    """Inserts features in the features selection set"""
445
    self.getSelection().select(selection)
446 385 vacevedo
447
  def deselect(self, selection):
448 424 vacevedo
    """Remove features in the features selection set"""
449
    self.getSelection().deselect(selection)
450 385 vacevedo
451
  def isSelected(feature):
452 424 vacevedo
    """Returns True if given feature is selected"""
453
    self.getSelection().isSelect(feature)
454 385 vacevedo
455 383 vacevedo
  def getProjectionCode(self):
456 424 vacevedo
    """Returns projection code name"""
457 383 vacevedo
    return self.getProjection().getFullCode()
458 362 vacevedo
459 385 vacevedo
460 362 vacevedo
class Table(__DefaultTable__):
461 424 vacevedo
  """Represents gvsig table document
462
  (org.gvsig.app.project.documents.table.TableDocument)
463 362 vacevedo
  """
464
  def __init__(self,table):
465
    __DefaultTable__.__init__(self, table, table.getStore())
466 424 vacevedo
467
  def getAssociatedLayer(self):
468
    """Returns table associated layer or None if there're not associated
469
    layer
470
    """
471
    if self._javaobj.getAssociatedLayer():
472
      return Layer(self._javaobj.getAssociatedLayer())
473
474
    return None
475 362 vacevedo
476
class Layer(__DefaultTable__):
477 424 vacevedo
  """Represents gvsig layer document. It's a wrapper from
478
  org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect class
479 362 vacevedo
  """
480
  def __init__(self,layer):
481
    __DefaultTable__.__init__(self, layer, layer.getFeatureStore())
482 383 vacevedo
483
  def getTypeVectorLayer(self):
484 424 vacevedo
    """
485
    Returns layer DefaultGeometryType class
486
    To get the geometryType use DefaultGeometryType getType() method
487
    To get the geometrySubType use DefaultGeometryType getSubType() method
488
    """
489 383 vacevedo
    return self().getTypeVectorLayer()
490 362 vacevedo
491 355 jjdelcerro
class FeatureSet(WrapperToJava):
492 424 vacevedo
  """Represents gvSIG FeatureSet
493
  (org.gvsig.fmap.dal.feature.impl.featureset.DefaultFeatureSet)
494
  """
495 355 jjdelcerro
  def __init__(self,featureSet):
496
    WrapperToJava.__init__(self,featureSet)
497 362 vacevedo
498
  def getCount(self):
499 424 vacevedo
    """Returns the number of elements in the featureSet"""
500 362 vacevedo
    return self.getSize()
501
502
  def update(self, feature):
503
    """
504 424 vacevedo
    Updates exist feature in the featureSet
505
    :param editableFeature: editableFeature
506
    :type editableFeature: Java editableFeature
507 362 vacevedo
    """
508 424 vacevedo
    if not isinstance(feature, EditableFeature) and \
509
            not isinstance(feature, DefaultEditableFeature):
510 362 vacevedo
      feature = feature._javaobj
511
    self().update(feature)
512
513 355 jjdelcerro
  def __iter__(self):
514
    return  Iterator(self.fastIterator())
515 424 vacevedo
516
class Selection(FeatureSet):
517
  """Manage selected features set from a store. Represents gvSIG
518
  org.gvsig.fmap.dal.feature.impl.DefaultFeatureSelection.
519
  """
520
  def __init__(self, featureSet):
521
    FeatureSet.__init__(self, featureSet)
522
523
  def select(self, selection):
524
    """Inserts features in the features selection set"""
525
    if isinstance(selection,Feature) or isinstance(selection, FeatureSet):
526
      self._javaobj.select(selection._javaobj)
527
    else:
528
      self._javaobj.select(selection)
529
530
  def deselect(self, selection):
531
    """Removes features in the features selection set"""
532
    if isinstance(selection,Feature) or isinstance(selection, FeatureSet):
533
      self._javaobj.deselect(selection._javaobj)
534
    else:
535
      self._javaobj.deselect(selection)
536
537
  def isSelected(feature):
538
    """Returns True if given feature is selected"""
539
    if isinstance(feature, Feature):
540
      self._javaobj.isSelect(feature._javaobj)
541
    else:
542
      self._javaobj.isSelect(feature)
543
544
  def getCount(self):
545
    """Returns the number of elements in the selection"""
546
    return self.getSelectedCount()
547
548
549 355 jjdelcerro
class Iterator(WrapperToJava):
550
551
  def __init__(self,iterator):
552
    WrapperToJava.__init__(self,iterator)
553
554
  def next(self):
555
    if not self.hasNext():
556
      raise StopIteration()
557
    return Feature(self().next())
558
559
class Feature(WrapperToJava):
560 424 vacevedo
  """Represents feature data It's a wrapper from gvSIG
561
  org.gvsig.fmap.dal.feature.impl.DefaultFeature class
562 362 vacevedo
  """
563 355 jjdelcerro
  def __init__(self,feature):
564
    WrapperToJava.__init__(self,feature)
565 362 vacevedo
    self.featureNoEditable = None
566 355 jjdelcerro
567
  def geometry(self):
568 424 vacevedo
    """Returns feature geometry"""
569 355 jjdelcerro
    return self.getDefaultGeometry()
570 362 vacevedo
571
  def getValues(self):
572 424 vacevedo
    """Returns dictionary with the pair name, value, feature attributes"""
573 362 vacevedo
    descriptor = self.getType()
574
    items = dict()
575
    for attr in descriptor.getAttributeDescriptors():
576
      name = attr.getName()
577
      value = self.get(attr.getName())
578
      items[name] = value
579
    return items
580 355 jjdelcerro
581 362 vacevedo
  def edit(self):
582 424 vacevedo
    """Returns editable feature instance"""
583 362 vacevedo
    if not isinstance(self._javaobj, EditableFeature):
584
      self.featureNoEditable = self._javaobj
585
      self._javaobj = self._javaobj.getEditable()
586
587 355 jjdelcerro
  def __getitem__(self,key):
588
    return self.get(key)
589
590
  def __getattr__(self,name):
591 403 vacevedo
    #
592
    #FIX console error when try to introspect feature object
593
    if name in ('__methods__'):
594
        return dict()
595
    elif name in ('__members__'):
596
        return self.getValues().keys()
597
    elif name == '__dict__':
598 417 vacevedo
        return self.getValues()
599 403 vacevedo
600 355 jjdelcerro
    try:
601 401 vacevedo
      v = getattr(self._javaobj, name, None)
602 355 jjdelcerro
      if v == None:
603 362 vacevedo
        v = self().get(name)
604 355 jjdelcerro
      return v
605
    except Throwable, ex:
606 362 vacevedo
      raise RuntimeException("Can't access to attribute %s of feature (%s)" % (name, str(ex)))
607 355 jjdelcerro
608
class Schema(WrapperToJava):
609 424 vacevedo
  """Stores data properties definition. Represents gvSIG FeatureType
610
  (org.gvsig.fmap.dal.feature.impl.DefaultFeatureType)
611 362 vacevedo
  """
612 355 jjdelcerro
613
  def __init__(self, featureType):
614
    WrapperToJava.__init__(self,featureType)
615 362 vacevedo
    self.featureTypeNoEditable = None
616 355 jjdelcerro
617 362 vacevedo
  def append(self, name, type, size=None, default=None, precision=4):
618 424 vacevedo
    """Adds new property to feature properties definition. If error occurs
619
    raises RuntimeError.
620
    :param name: Feature property name
621
    :type name: String
622
    :param type: Feature property type
623
    :type name: String
624
    :param size: Feature property size
625
    :type size: int
626
    :param default: Feature property default value
627
    :return: new atribute
628 362 vacevedo
    """
629
    if not isinstance(self._javaobj, EditableFeatureType):
630 424 vacevedo
        self.modify()
631 362 vacevedo
632
    if isinstance(type, str):
633
      try:
634
        application = ApplicationLocator.getManager()
635
        datamanager =  application.getDataManager()
636
        dataTypes = application.getDataTypesManager()
637
        type = dataTypes.getType(type) #dataType constant value from string
638
      except:
639
        raise RuntimeError(
640
            "Feature Property Data type (%s) is not valid.  name=%s, type=%s, size=%s, default=%s)" % (
641
                type,
642
                name,
643
                type,
644
                size,
645
                default
646
            )
647
        )
648
    if isinstance(type, int):
649
      try:
650
        type = dataTypes.get(type)
651
      except:
652
        raise RuntimeError(
653
            "Data type (%s) is not valid.  name=%s, type=%s, size=%s, default=%s)" % (
654
                type,
655
                name,
656
                type,
657
                size,
658
                default
659
            )
660
        )
661
662 355 jjdelcerro
    attribute = self.add(name, type.getType())
663 362 vacevedo
664
    if size != None:
665 355 jjdelcerro
      attribute.setSize(size)
666 362 vacevedo
667
    if default != None:
668
      attribute.setDefaultValue(default)
669
670
    if precision != None and type.getType() in (DataTypes.DOUBLE, DataTypes.FLOAT):
671
      attribute.setPrecision(precision)
672
673 355 jjdelcerro
    if type.getType() == DataTypes.GEOMETRY and self.getDefaultGeometryAttributeName()==None:
674
      self.setDefaultGeometryAttributeName(name)
675
676
    return attribute
677
678
  def __getitem__(self, name):
679
    return self.getAttributeDescriptor(name)
680
681
  def get(self, name, default=None):
682 424 vacevedo
    """Returns a feature attribute descriptor that contains information about
683
    one feature attribute, such as its name, data type or precision.
684
    :param name: Attribute name
685
    :type name: string
686
    :param default: Value to return if no attribute name found.
687
    :return: AttributeDescriptor
688 383 vacevedo
    """
689 355 jjdelcerro
    x = self.getAttributeDescriptor(name)
690
    if x == None:
691
      return default
692
    return x
693 362 vacevedo
694 385 vacevedo
  def getAttrNames(self):
695 424 vacevedo
    """Returns a list with attributes names"""
696
    if not self.getAttributeDescriptors():
697
      return None
698
699
    return [attr.getName() for attr in self.getAttributeDescriptors()]
700 383 vacevedo
701 424 vacevedo
702 383 vacevedo
  def getCopy(self):
703 424 vacevedo
    """Returns a itself clone"""
704 383 vacevedo
    return Schema(self().getCopy())
705
706 362 vacevedo
  def modify(self):
707 424 vacevedo
    """Sets edit mode"""
708 362 vacevedo
    if not isinstance(self._javaobj, EditableFeatureType):
709
      self.featureTypeNoEditable = self._javaobj
710
      self._javaobj = self._javaobj.getEditable()
711 383 vacevedo
712
713
#=====================#
714
# Vectorial Functions #
715
#=====================#
716
717 362 vacevedo
def createSchema(schema = None):
718 424 vacevedo
  """Returns attributes definition. If Schema is recived then makes a copy and
719
  returns editable instance. Otherwise returns empty Schema.
720
  :param schema: Schema to make a copy
721
  :type schema: Schema
722 362 vacevedo
  """
723 424 vacevedo
  if isinstance(schema, Schema):
724
    try:
725
      s = schema.getCopy()
726
      s.modify()
727
      return s
728
    except:
729
      pass
730 362 vacevedo
731 355 jjdelcerro
  application = ApplicationLocator.getManager()
732
  datamanager =  application.getDataManager()
733
  return Schema(datamanager.createFeatureType())
734
735
def createLayer(schema, servertype, layertype=None, **parameters):
736 362 vacevedo
  """
737 424 vacevedo
  Returns new layer
738
  :param schema: layer data definition
739
  :type schema: Schema
740
  :param servertype:
741
  :type servertype: string
742
  :return: new layer
743
  :rtype: Layer
744
  :raise: RuntimeException
745
  """
746 355 jjdelcerro
  if layertype == None:
747
    layertype = servertype
748
    servertype = "FilesystemExplorer"
749
750
  if layertype == "Shape" :
751
    if schema.get("GEOMETRY",None) == None:
752
      raise RuntimeException("Shape need a field named GEOMETRY in the schema")
753 362 vacevedo
754
  if parameters["geometryType"] == None:
755
    raise RuntimeException("Invalid geometry type for new layer")
756
757 355 jjdelcerro
  try:
758
    application = ApplicationLocator.getManager()
759
    datamanager =  application.getDataManager()
760
761
    mapcontextmanager = application.getMapContextManager()
762
763
    server_parameters = datamanager.createServerExplorerParameters(servertype)
764
    copyToDynObject(parameters, server_parameters)
765
766
    server = datamanager.openServerExplorer(servertype, server_parameters)
767
768
    store_parameters = server.getAddParameters(layertype)
769
    copyToDynObject(parameters, store_parameters)
770
    store_parameters.setDefaultFeatureType(schema())
771
772
    server.add(layertype, store_parameters, True)
773
774
    store = datamanager.openStore(layertype, store_parameters)
775
776
    layer = mapcontextmanager.createLayer(store.getName(), store)
777
778
    return Layer(layer)
779
  except Throwable, ex:
780
    raise RuntimeException("Can't create layer, "+ str(ex))
781
782 417 vacevedo
def loadShapeFile(shpFile, CRS="CRS:84"):
783 404 vacevedo
    """
784 424 vacevedo
    Add existing shape file to the view. Returns Layer shape file
785
    :param shpFile: absolute file path
786
    :type: shpFile: string
787
    :param CRS: projection code
788
    :type CRS: string
789
    :return: the shape
790
    :type return: Layer
791 404 vacevedo
    """
792
    layer = loadLayer('Shape', shpFile=shpFile, CRS=CRS)
793
    currentView().addLayer(layer)
794 417 vacevedo
    layer.setActive(True)
795 404 vacevedo
    return Layer(layer)
796
797
def loadLayer(layerType, **parameters):
798
    try:
799
        application = ApplicationLocator.getManager()
800
        datamanager =  application.getDataManager()
801
        mapcontextmanager = application.getMapContextManager()
802
        store_parameters = datamanager.createStoreParameters(layerType)
803
        copyToDynObject(parameters, store_parameters)
804 417 vacevedo
        store = datamanager.openStore(layerType, store_parameters)
805 404 vacevedo
        layer = mapcontextmanager.createLayer(store.getName(), store)
806
    except Throwable, ex:
807
        raise RuntimeException("Can't load layer, "+ str(ex))
808 417 vacevedo
809
    return layer
810 404 vacevedo
811 417 vacevedo
def createShape(definition, filename, geometryType, CRS="CRS:84"):
812 362 vacevedo
  """
813 424 vacevedo
  Return new shape layer
814
  :param definition: layer data definition
815
  :type definition: Schema
816
  :param filename: absolute path for shape files.
817
  :type filename: string
818
  :param geometryType: geometry type for shape
819
  :type geometryType: string
820
  :return: new shape layer
821
  :rtype: Layer
822
  """
823 362 vacevedo
  return createLayer(
824
    definition,
825
    "FilesystemExplorer",
826
    "Shape",
827
    shpFile=filename,
828
    CRS=CRS,
829
    geometryType = geometryType
830
  )
831
832
def createTable(schema, servertype, tableType=None, **parameters):
833 424 vacevedo
  """Creates a new Table document"""
834 362 vacevedo
  if tableType == None:
835
    tableType = servertype
836
    servertype = "FilesystemExplorer"
837
838
  try:
839
    application = ApplicationLocator.getManager()
840
    datamanager =  application.getDataManager()
841
842
    server_parameters = datamanager.createServerExplorerParameters(servertype)
843
    copyToDynObject(parameters, server_parameters)
844
845
    server = datamanager.openServerExplorer(servertype, server_parameters)
846
847
    store_parameters = server.getAddParameters(tableType)
848
    copyToDynObject(parameters, store_parameters)
849
    store_parameters.setDefaultFeatureType(schema())
850
851
    server.add(tableType, store_parameters, True)
852
853
    store = datamanager.openStore(tableType, store_parameters)
854
855
    return Table(store)
856 355 jjdelcerro
857 362 vacevedo
  except Throwable, ex:
858
    raise RuntimeException("Can't create table, "+ str(ex))
859
860 424 vacevedo
def createDBF(definition, DbfFile, CRS="CRS:84"):
861 362 vacevedo
  """
862 424 vacevedo
  Creates a new dbf document
863
  :param definition: layer data definition
864
  :type definition: Schema
865
  :param DbfFile: absolute path for shape files.
866
  :type DbfFile: string
867
  :return: new dbf
868
  :rtype: Table
869
  """
870 362 vacevedo
  return createTable(
871
    definition,
872
    "FilesystemExplorer",
873
    "DBF",
874
    DbfFile=DbfFile,
875
    CRS=CRS,
876
  )
877 383 vacevedo
878
#=====================#
879
# Documents Functions #
880
#=====================#
881
882 355 jjdelcerro
def currentProject():
883 362 vacevedo
  """
884 424 vacevedo
  Returns current gvSIG proyect
885
  :return: Proyect
886 362 vacevedo
  """
887 355 jjdelcerro
  application = ApplicationLocator.getManager()
888
  project = application.getCurrentProject()
889
  return Project(project)
890
891 402 vacevedo
def currentDocument(documentClass = None):
892 362 vacevedo
  """
893 424 vacevedo
  Returns the current active document if it's a DocumentTable or
894
  DocumentView2D return None
895
  :return: Active document, None
896 362 vacevedo
  """
897 355 jjdelcerro
  application = ApplicationLocator.getManager()
898 362 vacevedo
899 402 vacevedo
  if documentClass == None:
900
    doc = application.getActiveDocument()
901
  else:
902
    doc = application.getActiveDocument(documentClass)
903 424 vacevedo
  if isinstance(doc, TableDocument):
904 362 vacevedo
    return Table(doc)
905 424 vacevedo
  if isinstance(doc, ViewDocument):
906 362 vacevedo
    return View(doc)
907 355 jjdelcerro
908 362 vacevedo
  return None
909
910 383 vacevedo
def currentTable():
911
  """
912 424 vacevedo
  Returns active table document or None
913
  :return: Table or None
914 383 vacevedo
  """
915 402 vacevedo
  return currentDocument(TableDocument)
916 383 vacevedo
917 362 vacevedo
def currentView():
918
  """
919 424 vacevedo
  Returns the current active view document or None
920
  :return: View or None
921 402 vacevedo
  """
922
  return currentDocument(ViewDocument)
923 362 vacevedo
924 355 jjdelcerro
def currentLayer():
925 362 vacevedo
  """
926 424 vacevedo
  Returns current view active layer or None
927
  :return: gvSIG active layer
928
  """
929 417 vacevedo
  try:
930
    return currentView().getLayer()
931
  except:
932
    return None
933 355 jjdelcerro
934 383 vacevedo
#=====================#
935
# Simbology Functions #
936
#=====================#
937 424 vacevedo
COLORS = {
938
    'black': Color.black,
939
    'blue': Color.blue,
940
    'cyan': Color.cyan,
941
    'darkGray': Color.darkGray,
942
    'gray': Color.gray,
943
    'green': Color.green,
944
    'lightGray': Color.lightGray,
945
    'magenta': Color.magenta,
946
    'orange': Color.orange,
947
    'pink': Color.pink,
948
    'red': Color.red,
949
    'white': Color.white,
950
    'yellow': Color.yellow,
951
}
952 383 vacevedo
953 388 vacevedo
def simplePointSymbol(color=None):
954 355 jjdelcerro
  """
955 424 vacevedo
  Returns simple point symbol using parameter color. If no color
956
  use a ramdom color
957
  :param color: String color name or Java awt Color
958
  :return: gvSIG point symbol
959 355 jjdelcerro
  """
960 424 vacevedo
  if isinstance(color, str) and COLORS.has_key(color.lower()):
961
    color = COLORS.get(color)
962
963 388 vacevedo
  if not isinstance(color, Color):
964 424 vacevedo
      color = getDefaultColor()
965 388 vacevedo
966 424 vacevedo
  return MapContextLocator.getSymbolManager().createSymbol(
967
        Geometry.TYPES.POINT, color)
968 355 jjdelcerro
969 388 vacevedo
def simpleLineSymbol(color=None):
970 362 vacevedo
  """
971 424 vacevedo
  Returns simple line symbol using parameter color. If no color use a
972
  ramdom color
973
  :param color: String color name or Java awt Color
974
  :return: gvSIG line symbol
975 362 vacevedo

976
  """
977 424 vacevedo
  if isinstance(color, str) and COLORS.has_key(color.lower()):
978
    color = COLORS.get(color)
979
980 388 vacevedo
  if not isinstance(color, Color):
981 424 vacevedo
      color = getDefaultColor()
982 388 vacevedo
983 424 vacevedo
  return MapContextLocator.getSymbolManager().createSymbol(
984
        Geometry.TYPES.CURVE, color)
985 362 vacevedo
986 401 vacevedo
def simplePolygonSymbol(color = None):
987 362 vacevedo
  """
988 424 vacevedo
  Returns simple polygon symbol using parameter color. If no color
989
  use a ramdom color.
990
  :param color: String color name or Java awt Color
991
  :return: gvSIG polygon symbol
992 362 vacevedo
  """
993 424 vacevedo
  if isinstance(color, str) and COLORS.has_key(color.lower()):
994
    color = COLORS.get(color)
995
996 388 vacevedo
  if not isinstance(color, Color):
997 424 vacevedo
      color = getDefaultColor()
998 362 vacevedo
999 424 vacevedo
  return MapContextLocator.getSymbolManager().createSymbol(
1000
        Geometry.TYPES.SURFACE, color)
1001 388 vacevedo
1002 362 vacevedo
1003 383 vacevedo
#=========================================#
1004
# gvSIG Application Preferences Functions #
1005
#=========================================#
1006
1007
def getDataFolder():
1008
  """
1009 424 vacevedo
  Returns gvSIG data folder. This folder is defined in application
1010
  preferences. If is not defined returns None.
1011 383 vacevedo
  """
1012
  return Preferences.userRoot().node("gvsig.foldering").get('DataFolder', None)
1013
1014
def getProjectsFolder():
1015
  """
1016 424 vacevedo
  Returns gvSIG projects folder. This folder is defined in application
1017
  preferences. If is not defined returns None.
1018 383 vacevedo
  """
1019 424 vacevedo
  return Preferences.userRoot().node("gvsig.foldering").get(
1020
        'ProjectsFolder', None)
1021
1022
def getColorFromRGB(r, g, b, a=None):
1023
  """
1024
  Returns an sRGB color with the specified red, green, blue, and alpha
1025
  (optional) values in the range (0 - 255).
1026
  """
1027
  if a:
1028
    color = Color(r, g, b, a)
1029
  else:
1030
    color = Color(r, g, b)
1031 383 vacevedo
1032 424 vacevedo
  return color
1033
1034
def getDefaultColor(c = None):
1035
  """Returns gvsig default symbol fill color or ramdom color"""
1036 388 vacevedo
  if MapContextLocator.getSymbolManager().isDefaultSymbolFillColorAleatory():
1037
    color = Color(random.randint(0-255),
1038 424 vacevedo
                random.randint(0-255),
1039
                random.randint(0-255)
1040 388 vacevedo
            )
1041
  else:
1042 424 vacevedo
    sp = MapContextLocator.getSymbolManager().getSymbolPreferences()
1043
    color = sp.getDefaultSymbolFillColor()
1044
1045 388 vacevedo
  return color
1046 383 vacevedo
1047 388 vacevedo
#================#
1048
# OTHER          #
1049
#================#
1050 417 vacevedo
1051
def getCRS(crs):
1052 424 vacevedo
  """Returns Projection from string code (i.e. CRS:84) if exist or None if
1053
  not.
1054 417 vacevedo
  """
1055
  try:
1056
    return CRSFactory.getCRS(crs)
1057
  except:
1058
    return None
1059
1060 362 vacevedo
def copyToDynObject(values, target):
1061
  definition = target.getDynClass();
1062
  fields = definition.getDynFields();
1063
  for field in fields:
1064
    name = field.getName()
1065
    keys = values.keys()
1066
    for k in keys:
1067
      if k.lower() == name.lower():
1068
        target.setDynValue(name, values[name])
1069 388 vacevedo
        break
1070 355 jjdelcerro
# ====================================
1071
#
1072
1073
def main():
1074
  layer = currentLayer()
1075
  schema = createSchema()
1076
  schema.append("ID", "String", 50)
1077
  schema.append("GEOMETRY", "Geometry")
1078
1079
  output = createLayer(
1080
      schema,
1081
      "FilesystemExplorer",
1082
      "Shape",
1083
      shpFile="/tmp/pp.shp",
1084
      CRS="EPSG:23030",
1085 366 vacevedo
      geometryType=POINT
1086 355 jjdelcerro
  )
1087
1088
  for feature in layer.features():
1089 362 vacevedo
    point = feature.geometry().centroid()
1090
    output.append(ID=feature.ID, GEOMETRY=point)
1091
1092 355 jjdelcerro
  output.commit()
1093
1094 362 vacevedo
  currentView().addLayer(output())