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 @ 425

History | View | Annotate | Download (30.8 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

    
46
from java.util.prefs import Preferences
47

    
48
from org.gvsig.app import ApplicationLocator
49
from org.gvsig.app.project.documents.view import ViewDocument 
50
from org.gvsig.app.project.documents.table import TableDocument
51

    
52
from org.gvsig.fmap.crs import CRSFactory
53

    
54
from org.gvsig.fmap.mapcontext import MapContextLocator
55
from org.gvsig.fmap.mapcontext.layers import FLayers
56

    
57
from org.gvsig.fmap.dal import DALLocator, DataTypes
58
from org.gvsig.fmap.dal.feature import EditableFeature, \
59
    EditableFeatureType, FeatureQueryOrder
60
from org.gvsig.fmap.dal.feature.impl import DefaultEditableFeature
61

    
62
from org.gvsig.fmap.geom import Geometry
63

    
64
from org.gvsig.tools import ToolsLocator
65

    
66
import thread
67
import random
68

    
69

    
70
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
  """Creates a wrapper that allows python object access to the Java object
86
  properties and methods
87
  """
88
  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
  """Represents a gvSIG project (org.gvsig.app.project.DefaultProject)"""
101

    
102
  def __init__(self, project):
103
    WrapperToJava.__init__(self, project)
104
  
105
  def getView(self, name=None):
106
    """
107
    Returns active view, or view called 'name'  or None
108
    :param name: view name
109
    :type name: string    
110
    """
111
    if name == None:
112
      try:
113
        activeDocument = self.getActiveDocument()
114
        if activeDocument == None:
115
            return None
116
        if isinstance(activeDocument, ViewDocument):
117
            return View(activeDocument)
118
      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
            return View(view)
126

    
127
    return None
128
    
129
  def getTable(self, name=None):
130
    """
131
    Returns active Table Document, or Table Document called 'name'  or None
132
    :param name: Table Document name
133
    :type name: string
134
    """
135
    if name == None:
136
      try:
137
        activeDocument = self.getActiveDocument()
138
        if activeDocument == None:
139
            return None
140
        if isinstance(activeDocument, TableDocument):
141
            return Table(activeDocument)
142
      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
            return Table(table)
150
            
151
    return None   
152
    
153
  def getProjectionCode(self):
154
    """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
    return self.getProjection().getFullCode()
160
    
161

    
162
class View(WrapperToJava):
163
  """
164
  Represents gvSIG view document 
165
  (org.gvsig.app.project.documents.view.DefaultViewDocument).  
166
  """
167
  def __init__(self,view):
168
    WrapperToJava.__init__(self,view)
169
    
170
  def getLayer(self, name=None):
171
    """
172
    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
    """
180
    map = self.getMapContext();
181
    if name == None:
182
      activeLayers = map.getLayers().getActives()
183
      if len(activeLayers) != 1 :
184
        return None
185
      for layer in activeLayers:
186
        if not isinstance(layer, FLayers):
187
          return Layer(layer)
188
      return None
189
    
190
    ls = self.getLayers()
191
    for i in xrange(ls.getLayersCount()):
192
      l = ls.getLayer(i)
193
      if l.name == name:
194
        return Layer(l)
195
    
196
    return None
197
    
198
  def getMap(self):
199
    # org.gvsig.fmap.mapcontext.MapContext
200
    """Returns view mapContext"""
201
    return self.getMapContext();
202
 
203
  def addLayer(self, layer):
204
    """
205
    Adds a new layer to the view
206
    :param layer: layer to add
207
    :type layer: Layer  
208
    """
209
    if isinstance(layer, Layer):
210
      layer =layer()
211
    self.getMapContext().getLayers().addLayer(layer)
212
  
213
  def getLayers(self):
214
    """Returns iterable view layers set"""
215
    map = self.getMapContext()
216
    return Layers(map.getLayers())
217
    
218
  def getGraphicsLayer(self):
219
    """Returns view graphics layer 
220
    org.gvsig.fmap.mapcontext.layers.vectorial.impl.DefaultGraphicLayer
221
    """
222
    return self.getMapContext().getGraphicsLayer()
223
    
224
  def getProjectionCode(self):
225
    """Returns string view projection code name"""
226
    return self.getProjection().getFullCode()
227
    
228
  def isProjected(self):
229
    """Returns if view projection is projected."""
230
    self.getProjection().isProjected()
231
      
232
class Layers(WrapperToJava):
233
  """Iterable layers set 
234
  (org.gvsig.fmap.mapcontext.layers.FLayers)  
235
  """
236
  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
    self.__index = -1
253

    
254
  def next(self):
255
    self.__index+=1
256
    if self.__index >= self.__layers.getLayersCount() :
257
      raise StopIteration()
258
    return Layer(self.__layers.getLayer(self.__index))    
259
  
260
class Store(WrapperToJava):
261
  """Represents gvsig store. It's used as Table/Layer objects store  
262
  (org.gvsig.fmap.dal.feature.impl.DefaultFeatureStore)
263
  """
264
  def __init__(self,store):
265
    WrapperToJava.__init__(self, store)
266
    #self.data = None
267
    self.fset = None
268
  
269
  def features(self, expresion = None, sortBy="", asc=True):
270
    """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
        determinates features that match with expression
275
    :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
    if expresion == None and sortBy =="":
283
      self.fset = self.getFeatureSet()         
284
    else:
285
      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
    
299
    return FeatureSet(self.fset)    
300

    
301
  def edit(self):
302
    """Set store in edition mode"""     
303
    if not self.isEditing():
304
        self().edit() 
305
     
306
  def append(self, *valuesList, **values):
307
    """
308
    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
    """
313
    try:
314
      if len(valuesList) ==1:
315
        values.update(valuesList[0])
316
      
317
      if not self.isEditing():
318
        self.edit() 
319
      f = self.createNewFeature()
320
      
321
      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
        self.insert(f)
326
    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
  def updateSchema(self, schema):
335
    """
336
    Updates store FeatureType. If an error occurs raises 
337
    RuntimeException.
338
    """
339
    try:
340
      self().update(schema._javaobj)
341
    except Throwable, ex:
342
      raise RuntimeException(repr(ex))
343
    
344
  def update(self, feature):
345
    """
346
    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
    
353
    if not isinstance(feature, EditableFeature):
354
      feature = feature._javaobj
355
    self.fset.update(feature)
356
  
357
  def getSchema(self):
358
    """Returns store data attributtes"""
359
    return Schema(self.getDefaultFeatureType())
360

    
361
  def commit(self):
362
    """
363
    Finish store edition saving changes. If an error occurs raises Throwable 
364
    Exception.
365
    """
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
  
372
  def abort(self):
373
    """Finish store edition withoout saving changes and disposes itself"""
374
    self.cancelEditing() 
375
    self.dispose()
376

    
377
  def getSelection(self):
378
    """Returns store features selected set"""
379
    return FeatureSet(self().getSelection())
380

    
381
class __DefaultTable__(WrapperToJava):
382
  def __init__(self,document, data):
383
    self.data = Store(data)
384
    WrapperToJava.__init__(self,document)
385
    self.selection = None
386

    
387
  def features(self, expresion = None, sortBy="", asc=True):
388
    """
389
    Returns data features set
390
    :param expresion: filter to apply to the feature set to select
391
         determinates features that match with expression
392
    :type expresion: string
393
    :return: FeatureSet
394
    """
395
    return self.data.features(expresion, sortBy, asc)
396

    
397
  def edit(self):
398
    """Sets data in edition mode"""
399
     
400
    self.data.edit() 
401
     
402
  def append(self, *valuesList, **values):
403
    """
404
    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
    """
408
    self.data.append(*valuesList, **values)
409
    
410
  def updateSchema(self, schema):
411
    """
412
    Updates data data attributes properties with the given schema
413
    """
414
    self.data.updateSchema(schema)
415
    
416
  def update(self, feature):
417
    """
418
    Updates exist feature in the featureSet with the given feature
419
    :param editableFeature: editableFeature
420
    :type editableFeature: Java editableFeature
421
    """
422
    self.data.update(feature)
423
  
424
  def getSchema(self):
425
    """Returns data attributes definition"""
426
    return self.data.getSchema()
427

    
428
  def commit(self):
429
    """Finish edition saving changes"""
430
    self.data.commit()
431
  
432
  def abort(self):
433
    """Finish edition without saving changes"""
434
    self.data.abort()
435
    
436
  def getSelection(self):
437
    """Returns features selected set"""
438
    if self.selection == None:
439
      self.selection = Selection(self.data.getSelection())
440
      
441
    return self.selection
442
  
443
  def select(self, selection):
444
    """Inserts features in the features selection set"""
445
    self.getSelection().select(selection)
446

    
447
  def deselect(self, selection):
448
    """Remove features in the features selection set"""
449
    self.getSelection().deselect(selection)
450

    
451
  def isSelected(feature):
452
    """Returns True if given feature is selected"""
453
    self.getSelection().isSelect(feature)
454

    
455
  def getProjectionCode(self):
456
    """Returns projection code name"""
457
    return self.getProjection().getFullCode()
458

    
459

    
460
class Table(__DefaultTable__):
461
  """Represents gvsig table document 
462
  (org.gvsig.app.project.documents.table.TableDocument)
463
  """
464
  def __init__(self,table):
465
    __DefaultTable__.__init__(self, table, table.getStore())
466
    
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

    
476
class Layer(__DefaultTable__):
477
  """Represents gvsig layer document. It's a wrapper from 
478
  org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect class
479
  """
480
  def __init__(self,layer):
481
    __DefaultTable__.__init__(self, layer, layer.getFeatureStore())
482
    
483
  def getTypeVectorLayer(self):
484
    """
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
    return self().getTypeVectorLayer()
490
        
491
class FeatureSet(WrapperToJava):
492
  """Represents gvSIG FeatureSet 
493
  (org.gvsig.fmap.dal.feature.impl.featureset.DefaultFeatureSet)
494
  """
495
  def __init__(self,featureSet):
496
    WrapperToJava.__init__(self,featureSet)
497
    
498
  def getCount(self):
499
    """Returns the number of elements in the featureSet"""
500
    return self.getSize()
501
  
502
  def update(self, feature):
503
    """
504
    Updates exist feature in the featureSet
505
    :param editableFeature: editableFeature
506
    :type editableFeature: Java editableFeature
507
    """
508
    if not isinstance(feature, EditableFeature) and \
509
            not isinstance(feature, DefaultEditableFeature):
510
      feature = feature._javaobj
511
    self().update(feature)
512
  
513
  def __iter__(self):
514
    return  Iterator(self.fastIterator())
515
    
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
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
  """Represents feature data It's a wrapper from gvSIG 
561
  org.gvsig.fmap.dal.feature.impl.DefaultFeature class
562
  """
563
  def __init__(self,feature):
564
    WrapperToJava.__init__(self,feature)
565
    self.featureNoEditable = None
566

    
567
  def geometry(self):
568
    """Returns feature geometry"""
569
    return self.getDefaultGeometry()
570
   
571
  def getValues(self):
572
    """Returns dictionary with the pair name, value, feature attributes"""
573
    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
  
581
  def edit(self):
582
    """Returns editable feature instance"""
583
    if not isinstance(self._javaobj, EditableFeature):
584
      self.featureNoEditable = self._javaobj
585
      self._javaobj = self._javaobj.getEditable()
586
  
587
  def __getitem__(self,key):
588
    return self.get(key)
589
  
590
  def __getattr__(self,name):
591
    #
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
        return self.getValues()      
599
        
600
    try:
601
      v = getattr(self._javaobj, name, None)
602
      if v == None:
603
        v = self().get(name)        
604
      return v
605
    except Throwable, ex:
606
      raise RuntimeException("Can't access to attribute %s of feature (%s)" % (name, str(ex)))    
607

    
608
class Schema(WrapperToJava):
609
  """Stores data properties definition. Represents gvSIG FeatureType
610
  (org.gvsig.fmap.dal.feature.impl.DefaultFeatureType)
611
  """
612

    
613
  def __init__(self, featureType):
614
    WrapperToJava.__init__(self,featureType)
615
    self.featureTypeNoEditable = None
616
  
617
  def append(self, name, type, size=None, default=None, precision=4):
618
    """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
    """
629
    if not isinstance(self._javaobj, EditableFeatureType):
630
        self.modify()
631
    
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
    attribute = self.add(name, type.getType())
663
 
664
    if size != None: 
665
      attribute.setSize(size)
666
    
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
    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
    """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
    """
689
    x = self.getAttributeDescriptor(name)
690
    if x == None:
691
      return default
692
    return x
693
  
694
  def getAttrNames(self):
695
    """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
    
701
    
702
  def getCopy(self):
703
    """Returns a itself clone"""
704
    return Schema(self().getCopy())
705
  
706
  def modify(self):
707
    """Sets edit mode"""
708
    if not isinstance(self._javaobj, EditableFeatureType):
709
      self.featureTypeNoEditable = self._javaobj
710
      self._javaobj = self._javaobj.getEditable()
711

    
712
      
713
#=====================#
714
# Vectorial Functions #
715
#=====================#
716

    
717
def createSchema(schema = None):
718
  """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
  """
723
  if isinstance(schema, Schema):
724
    try:  
725
      s = schema.getCopy()
726
      s.modify()
727
      return s
728
    except:
729
      pass
730
    
731
  application = ApplicationLocator.getManager()
732
  datamanager =  application.getDataManager()
733
  return Schema(datamanager.createFeatureType())
734

    
735
def createLayer(schema, servertype, layertype=None, **parameters):
736
  """
737
  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
  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
    
754
  if parameters["geometryType"] == None:
755
    raise RuntimeException("Invalid geometry type for new layer")
756
      
757
  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
def loadShapeFile(shpFile, CRS="CRS:84"):
783
    """
784
    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
    """
792
    layer = loadLayer('Shape', shpFile=shpFile, CRS=CRS)
793
    currentView().addLayer(layer)
794
    layer.setActive(True)
795
    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
        store = datamanager.openStore(layerType, store_parameters)        
805
        layer = mapcontextmanager.createLayer(store.getName(), store)
806
    except Throwable, ex:
807
        raise RuntimeException("Can't load layer, "+ str(ex))  
808

    
809
    return layer
810
    
811
def createShape(definition, filename, geometryType, CRS="CRS:84"):
812
  """
813
  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
  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
  """Creates a new Table document"""
834
  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
  
857
  except Throwable, ex:
858
    raise RuntimeException("Can't create table, "+ str(ex))
859
  
860
def createDBF(definition, DbfFile, CRS="CRS:84"):
861
  """
862
  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
  return createTable(
871
    definition, 
872
    "FilesystemExplorer", 
873
    "DBF", 
874
    DbfFile=DbfFile, 
875
    CRS=CRS,
876
  )
877

    
878
#=====================#
879
# Documents Functions #
880
#=====================#  
881

    
882
def currentProject():
883
  """
884
  Returns current gvSIG proyect
885
  :return: Proyect
886
  """
887
  application = ApplicationLocator.getManager()
888
  project = application.getCurrentProject()
889
  return Project(project)
890

    
891
def currentDocument(documentClass = None):
892
  """
893
  Returns the current active document if it's a DocumentTable or 
894
  DocumentView2D return None
895
  :return: Active document, None
896
  """
897
  application = ApplicationLocator.getManager()
898
  
899
  if documentClass == None:
900
    doc = application.getActiveDocument()
901
  else:
902
    doc = application.getActiveDocument(documentClass)
903
  if isinstance(doc, TableDocument):
904
    return Table(doc)
905
  if isinstance(doc, ViewDocument):
906
    return View(doc)  
907

    
908
  return None  
909
  
910
def currentTable():
911
  """
912
  Returns active table document or None 
913
  :return: Table or None
914
  """  
915
  return currentDocument(TableDocument)
916
  
917
def currentView():
918
  """
919
  Returns the current active view document or None 
920
  :return: View or None
921
  """ 
922
  return currentDocument(ViewDocument)
923

    
924
def currentLayer():
925
  """
926
  Returns current view active layer or None
927
  :return: gvSIG active layer
928
  """
929
  try:
930
    return currentView().getLayer()
931
  except:
932
    return None
933

    
934
#=====================#
935
# Simbology Functions #
936
#=====================#  
937
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
  
953
def simplePointSymbol(color=None):
954
  """
955
  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
  """
960
  if isinstance(color, str) and COLORS.has_key(color.lower()):
961
    color = COLORS.get(color)
962
    
963
  if not isinstance(color, Color):
964
      color = getDefaultColor()
965
      
966
  return MapContextLocator.getSymbolManager().createSymbol(
967
        Geometry.TYPES.POINT, color)
968

    
969
def simpleLineSymbol(color=None):
970
  """
971
  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
  
976
  """
977
  if isinstance(color, str) and COLORS.has_key(color.lower()):
978
    color = COLORS.get(color)
979

    
980
  if not isinstance(color, Color):
981
      color = getDefaultColor()
982
      
983
  return MapContextLocator.getSymbolManager().createSymbol(
984
        Geometry.TYPES.CURVE, color)
985

    
986
def simplePolygonSymbol(color = None):
987
  """
988
  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
  """
993
  if isinstance(color, str) and COLORS.has_key(color.lower()):
994
    color = COLORS.get(color)
995

    
996
  if not isinstance(color, Color):
997
      color = getDefaultColor()
998
  
999
  return MapContextLocator.getSymbolManager().createSymbol(
1000
        Geometry.TYPES.SURFACE, color)
1001
  
1002

    
1003
#=========================================#
1004
# gvSIG Application Preferences Functions #
1005
#=========================================#  
1006

    
1007
def getDataFolder():
1008
  """
1009
  Returns gvSIG data folder. This folder is defined in application 
1010
  preferences. If is not defined returns None.
1011
  """
1012
  return Preferences.userRoot().node("gvsig.foldering").get('DataFolder', None)
1013
  
1014
def getProjectsFolder():
1015
  """
1016
  Returns gvSIG projects folder. This folder is defined in application 
1017
  preferences. If is not defined returns None.
1018
  """
1019
  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
  
1032
  return color
1033
  
1034
def getDefaultColor(c = None):
1035
  """Returns gvsig default symbol fill color or ramdom color"""
1036
  if MapContextLocator.getSymbolManager().isDefaultSymbolFillColorAleatory():
1037
    color = Color(random.randint(0-255), 
1038
                random.randint(0-255), 
1039
                random.randint(0-255)
1040
            )
1041
  else:
1042
    sp = MapContextLocator.getSymbolManager().getSymbolPreferences()
1043
    color = sp.getDefaultSymbolFillColor()    
1044

    
1045
  return color  
1046
  
1047
#================#
1048
# OTHER          #
1049
#================#
1050

    
1051
def getCRS(crs):
1052
  """Returns Projection from string code (i.e. CRS:84) if exist or None if 
1053
  not.  
1054
  """
1055
  try:
1056
    return CRSFactory.getCRS(crs)
1057
  except:
1058
    return None
1059

    
1060
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
        break
1070
# ====================================
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
      geometryType=POINT
1086
  )
1087
  
1088
  for feature in layer.features():
1089
    point = feature.geometry().centroid()
1090
    output.append(ID=feature.ID, GEOMETRY=point)
1091
      
1092
  output.commit() 
1093
  
1094
  currentView().addLayer(output())