Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting.app / trunk / org.gvsig.scripting.app / org.gvsig.scripting.app.extension / src / main / resources-plugin / scripting / lib / gvsig_2_0_0.py @ 446

History | View | Annotate | Download (31.4 KB)

1
# -*- coding: utf-8 -*-
2
#
3
# File: gvsig.py
4
#
5
# Copyright (c) 2011 by Model Driven Development sl and Antonio Carrasco Valero
6
#
7
# GNU General Public License (GPL)
8
#
9
# This program is free software; you can redistribute it and/or
10
# modify it under the terms of the GNU General Public License
11
# as published by the Free Software Foundation; either version 2
12
# of the License, or (at your option) any later version.
13
#
14
# This program is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
# GNU General Public License for more details.
18
#
19
# You should have received a copy of the GNU General Public License
20
# along with this program; if not, write to the Free Software
21
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22
# 02110-1301, USA.
23
#
24
#
25

    
26
"""
27
This module contains classes and functions to manage gvSIG Project, 
28
gvSIG DocumentView, gvSIG TableDocument and Layers.
29
Also contais functions to manage vectorial data and other utility 
30
functions
31
"""
32

    
33
__author__ = """Antonio Carrasco Valero
34
Model Driven Development sl and Antonio Carrasco Valero
35
<carrasco@modeldd.org>
36
Victor Acevedo Royer <vacevedor@gvsig.com>, <vacevedor@gmail.com>
37
"""
38

    
39
__docformat__ = 'plaintext'
40

    
41
from java.awt import Color
42

    
43
from java.lang import RuntimeException
44
from java.lang import Throwable
45
import java.lang.IndexOutOfBoundsException
46

    
47
from java.util.prefs import Preferences
48

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

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

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

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

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

    
65
from org.gvsig.tools import ToolsLocator
66

    
67
import thread
68
import random
69

    
70

    
71
def runTask(name, function, *args):
72
  manager = ToolsLocator.getTaskStatusManager()
73
  status = manager.createDefaultSimpleTaskStatus(name)
74
  status.add()
75
  args = list(args)
76
  args.append(status)
77
  try:
78
    thread.start_new_thread(function, tuple(args))
79
    status.terminate()
80
  except Exception,e:
81
    status.abort()
82
    raise e
83
     
84

    
85
class WrapperToJava(object):
86
  """Creates a wrapper that allows python object access to the Java object
87
  properties and methods
88
  """
89
  def __init__(self, javaobj):
90
    if javaobj == None:
91
      raise RuntimeException("Can't create "+ self.__class__.__name__)
92
    self._javaobj = javaobj
93

    
94
  def __call__(self):
95
    return self._javaobj
96

    
97
  def __getattr__(self,name):
98
    return getattr(self._javaobj,name)
99

    
100
class Project(WrapperToJava):
101
  """Represents a gvSIG project (org.gvsig.app.project.DefaultProject)"""
102

    
103
  def __init__(self, project):
104
    WrapperToJava.__init__(self, project)
105
  
106
  def getViews(self):
107
    views = self().getViews()
108
    return ViewsIterator(views)
109

    
110
  def getView(self, name=None):
111
    """
112
    Returns active view, or view called 'name'  or None
113
    :param name: view name
114
    :type name: string    
115
    """
116
    if name == None:
117
      try:
118
        activeDocument = self.getActiveDocument()
119
        if activeDocument == None:
120
            return None
121
        if isinstance(activeDocument, ViewDocument):
122
            return View(activeDocument)
123
      except Exception, ex:
124
        raise Exception("%s"%repr(ex))
125
    else:
126
      views = self.getViews()
127
      if len(views) >0:
128
        for view in views:
129
          if name == view.getName():
130
            return View(view)
131

    
132
    return None
133
    
134
  def getTable(self, name=None):
135
    """
136
    Returns active Table Document, or Table Document called 'name'  or None
137
    :param name: Table Document name
138
    :type name: string
139
    """
140
    if name == None:
141
      try:
142
        activeDocument = self.getActiveDocument()
143
        if activeDocument == None:
144
            return None
145
        if isinstance(activeDocument, TableDocument):
146
            return Table(activeDocument)
147
      except Exception, ex:
148
        raise Exception("%s"%repr(ex))
149
    else:
150
      tables = self.getDocuments("project.document.table")
151
      if len(tables) >0:
152
        for table in tables:
153
          if name == table.getName():
154
            return Table(table)
155
            
156
    return None   
157
    
158
  def getProjectionCode(self):
159
    """Returns Project projection code name string. This value is the 
160
    projects default projection that is fixed in Preferences tool, View 
161
    options. It's used when no view projection is defined.
162
    
163
    """
164
    return self.getProjection().getFullCode()
165

    
166
class ViewsIterator(object):
167

    
168
  def __init__(self,views):
169
    self.__views = views
170
    self.__index = -1
171

    
172
  def next(self):
173
    self.__index+=1
174
    if self.__index >= self.__views.size() :
175
      raise StopIteration()
176
    return View(self.__views.get(self.__index))      
177

    
178
class View(WrapperToJava):
179
  """
180
  Represents gvSIG view document 
181
  (org.gvsig.app.project.documents.view.DefaultViewDocument).  
182
  """
183
  def __init__(self,view):
184
    WrapperToJava.__init__(self,view)
185
    
186
  def getLayer(self, name=None):
187
    """
188
    Returns one view layer. If name is None returns active 
189
    layer if the view has one, if name is not None returns layer called name 
190
    else returns None.
191
    :param name: view name in Table Of Contents
192
    :type name: string
193
    :return: View
194
    :return: None  
195
    """
196
    map = self.getMapContext();
197
    if name == None:
198
      activeLayers = map.getLayers().getActives()
199
      if len(activeLayers) != 1 :
200
        return None
201
      for layer in activeLayers:
202
        if not isinstance(layer, FLayers):
203
          return Layer(layer)
204
      return None
205
    
206
    ls = self.getLayers()
207
    for i in xrange(ls.getLayersCount()):
208
      l = ls.getLayer(i)
209
      if l.name == name:
210
        return Layer(l)
211
    
212
    return None
213
    
214
  def getMap(self):
215
    # org.gvsig.fmap.mapcontext.MapContext
216
    """Returns view mapContext"""
217
    return self.getMapContext();
218
 
219
  def addLayer(self, layer):
220
    """
221
    Adds a new layer to the view
222
    :param layer: layer to add
223
    :type layer: Layer  
224
    """
225
    if isinstance(layer, Layer):
226
      layer =layer()
227
    self.getMapContext().getLayers().addLayer(layer)
228
  
229
  def getLayers(self):
230
    """Returns iterable view layers set"""
231
    map = self.getMapContext()
232
    return Layers(map.getLayers())
233
    
234
  def getGraphicsLayer(self):
235
    """Returns view graphics layer 
236
    org.gvsig.fmap.mapcontext.layers.vectorial.impl.DefaultGraphicLayer
237
    """
238
    return self.getMapContext().getGraphicsLayer()
239
    
240
  def getProjectionCode(self):
241
    """Returns string view projection code name"""
242
    return self.getProjection().getFullCode()
243
    
244
  def isProjected(self):
245
    """Returns if view projection is projected."""
246
    self.getProjection().isProjected()
247
      
248
class Layers(WrapperToJava):
249
  """Iterable layers set 
250
  (org.gvsig.fmap.mapcontext.layers.FLayers)  
251
  """
252
  def __init__(self,layers):
253
    WrapperToJava.__init__(self, layers)
254

    
255
  def __len__(self):
256
    return self.getLayersCount()
257

    
258
  def __getitem__(self, index):
259
    return self.getLayer(index)
260

    
261
  def __iter__(self):
262
    return LayersIterator(self)
263

    
264
class LayersIterator(object):
265

    
266
  def __init__(self,layers):
267
    self.__layers = layers
268
    self.__index = -1
269

    
270
  def next(self):
271
    self.__index+=1
272
    if self.__index >= self.__layers.getLayersCount() :
273
      raise StopIteration()
274
    return Layer(self.__layers.getLayer(self.__index))    
275
  
276
class Store(WrapperToJava):
277
  """Represents gvsig store. It's used as Table/Layer objects store  
278
  (org.gvsig.fmap.dal.feature.impl.DefaultFeatureStore)
279
  """
280
  def __init__(self,store):
281
    WrapperToJava.__init__(self, store)
282
    #self.data = None
283
    self.fset = None
284
  
285
  def features(self, expresion = None, sortBy="", asc=True):
286
    """Returns layer features set (FeatureSet class), with all layer features, 
287
    or selected featured if there are (could be empty feature set) or None if
288
    gets an Exception.
289
    :param expresion: filter to apply to the feature set to select
290
        determinates features that match with expression
291
    :type expresion: string
292
    :param sortBy: name of attribute to sort
293
    :type sortby: string
294
    :param: asc: order
295
    :type asc: boolean
296
    :return: FeatureSet
297
    """   
298
    if expresion == None and sortBy =="":
299
      self.fset = self.getFeatureSet()         
300
    else:
301
      try:
302
        application = ApplicationLocator.getManager()
303
        datamanager =  application.getDataManager()
304
        query = self.createFeatureQuery()
305
        if sortBy != "":
306
            order = FeatureQueryOrder()
307
            order.add(sortBy, asc)
308
            query.setOrder(order)
309
        if expresion != None:
310
            query.setFilter(datamanager.createExpresion(expresion))
311
        self.fset = self.getFeatureSet(query)
312
      except Exception, e:
313
        return None
314
    
315
    return FeatureSet(self.fset)    
316

    
317
  def edit(self):
318
    """Set store in edition mode"""     
319
    if not self.isEditing():
320
        self().edit() 
321
     
322
  def append(self, *valuesList, **values):
323
    """
324
    Creates a new feature from given values and insert it in the feature 
325
    set. If an error occurs raises RuntimeException.
326
    :param values: dictionary with name property value or list named params
327
    :type values: dict
328
    """
329
    try:
330
      if len(valuesList) ==1:
331
        values.update(valuesList[0])
332
      
333
      if not self.isEditing():
334
        self.edit() 
335
      f = self.createNewFeature()
336
      
337
      if f == None:
338
        raise RuntimeError("Failed to create a new Feature")
339
      for k,v in values.iteritems():
340
        f.set(k,v)
341
        self.insert(f)
342
    except Throwable, ex:
343
      raise RuntimeException("Can't append values %s to layer %s (%s)" % (
344
        repr(values), 
345
        self.getName(), 
346
        str(ex)
347
        )
348
      )
349

    
350
  def updateSchema(self, schema):
351
    """
352
    Updates store FeatureType. If an error occurs raises 
353
    RuntimeException.
354
    """
355
    try:
356
      self().update(schema._javaobj)
357
    except Throwable, ex:
358
      raise RuntimeException(repr(ex))
359
    
360
  def update(self, feature):
361
    """
362
    Updates exist feature in the layer featureSet
363
    :param editableFeature: editableFeature
364
    :type editableFeature: Java editableFeature
365
    """
366
    if not self.isEditing():
367
      self.edit() 
368
    
369
    if not isinstance(feature, EditableFeature):
370
      feature = feature._javaobj
371
    self.fset.update(feature)
372
  
373
  def getSchema(self):
374
    """Returns store data attributtes"""
375
    return Schema(self.getDefaultFeatureType())
376

    
377
  def commit(self):
378
    """
379
    Finish store edition saving changes. If an error occurs raises Throwable 
380
    Exception.
381
    """
382
    try:
383
      self.finishEditing()          
384
    except Throwable, ex:
385
      self.abort()
386
      raise Throwable("Can't finish layer edition, cancelling changes. %s" % repr(ex))
387
  
388
  def abort(self):
389
    """Finish store edition withoout saving changes and disposes itself"""
390
    self.cancelEditing() 
391
    self.dispose()
392

    
393
  def getSelection(self):
394
    """Returns store features selected set"""
395
    return FeatureSet(self().getSelection())
396

    
397
class __DefaultTable__(WrapperToJava):
398
  def __init__(self,document, data):
399
    self.data = Store(data)
400
    WrapperToJava.__init__(self,document)
401
    self.selection = None
402

    
403
  def features(self, expresion = None, sortBy="", asc=True):
404
    """
405
    Returns data features set
406
    :param expresion: filter to apply to the feature set to select
407
         determinates features that match with expression
408
    :type expresion: string
409
    :return: FeatureSet
410
    """
411
    return self.data.features(expresion, sortBy, asc)
412

    
413
  def edit(self):
414
    """Sets data in edition mode"""
415
     
416
    self.data.edit() 
417
     
418
  def append(self, *valuesList, **values):
419
    """
420
    Creates a new feature from given values and insert it in the feature set
421
    :param values: dictionary with name property value or list named params
422
    :type values: dict
423
    """
424
    self.data.append(*valuesList, **values)
425
    
426
  def updateSchema(self, schema):
427
    """
428
    Updates data data attributes properties with the given schema
429
    """
430
    self.data.updateSchema(schema)
431
    
432
  def update(self, feature):
433
    """
434
    Updates exist feature in the featureSet with the given feature
435
    :param editableFeature: editableFeature
436
    :type editableFeature: Java editableFeature
437
    """
438
    self.data.update(feature)
439
  
440
  def getSchema(self):
441
    """Returns data attributes definition"""
442
    return self.data.getSchema()
443

    
444
  def commit(self):
445
    """Finish edition saving changes"""
446
    self.data.commit()
447
  
448
  def abort(self):
449
    """Finish edition without saving changes"""
450
    self.data.abort()
451
    
452
  def getSelection(self):
453
    """Returns features selected set"""
454
    if self.selection == None:
455
      self.selection = Selection(self.data.getSelection())
456
      
457
    return self.selection
458
  
459
  def select(self, selection):
460
    """Inserts features in the features selection set"""
461
    self.getSelection().select(selection)
462

    
463
  def deselect(self, selection):
464
    """Remove features in the features selection set"""
465
    self.getSelection().deselect(selection)
466

    
467
  def isSelected(feature):
468
    """Returns True if given feature is selected"""
469
    self.getSelection().isSelect(feature)
470

    
471
  def getProjectionCode(self):
472
    """Returns projection code name"""
473
    return self.getProjection().getFullCode()
474

    
475

    
476
class Table(__DefaultTable__):
477
  """Represents gvsig table document 
478
  (org.gvsig.app.project.documents.table.TableDocument)
479
  """
480
  def __init__(self,table):
481
    __DefaultTable__.__init__(self, table, table.getStore())
482
    
483
  def getAssociatedLayer(self):
484
    """Returns table associated layer or None if there're not associated 
485
    layer
486
    """    
487
    if self._javaobj.getAssociatedLayer():
488
      return Layer(self._javaobj.getAssociatedLayer())
489
        
490
    return None
491

    
492
class Layer(__DefaultTable__):
493
  """Represents gvsig layer document. It's a wrapper from 
494
  org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect class
495
  """
496
  def __init__(self,layer):
497
    __DefaultTable__.__init__(self, layer, layer.getFeatureStore())
498
    
499
  def getTypeVectorLayer(self):
500
    """
501
    Returns layer DefaultGeometryType class 
502
    To get the geometryType use DefaultGeometryType getType() method
503
    To get the geometrySubType use DefaultGeometryType getSubType() method
504
    """
505
    return self().getTypeVectorLayer()
506
        
507
class FeatureSet(WrapperToJava):
508
  """Represents gvSIG FeatureSet 
509
  (org.gvsig.fmap.dal.feature.impl.featureset.DefaultFeatureSet)
510
  """
511
  def __init__(self,featureSet):
512
    WrapperToJava.__init__(self,featureSet)
513
    
514
  def getCount(self):
515
    """Returns the number of elements in the featureSet"""
516
    return self.getSize()
517
  
518
  def update(self, feature):
519
    """
520
    Updates exist feature in the featureSet
521
    :param editableFeature: editableFeature
522
    :type editableFeature: Java editableFeature
523
    """
524
    if not isinstance(feature, EditableFeature) and \
525
            not isinstance(feature, DefaultEditableFeature):
526
      feature = feature._javaobj
527
    self().update(feature)
528
  
529
  def __iter__(self):
530
    return  Iterator(self.fastIterator())
531
    
532
class Selection(FeatureSet):
533
  """Manage selected features set from a store. Represents gvSIG 
534
  org.gvsig.fmap.dal.feature.impl.DefaultFeatureSelection.  
535
  """
536
  def __init__(self, featureSet):
537
    FeatureSet.__init__(self, featureSet)
538
      
539
  def select(self, selection):
540
    """Inserts features in the features selection set"""
541
    if isinstance(selection,Feature) or isinstance(selection, FeatureSet):
542
      self._javaobj.select(selection._javaobj)
543
    else:
544
      self._javaobj.select(selection)
545

    
546
  def deselect(self, selection):
547
    """Removes features in the features selection set"""
548
    if isinstance(selection,Feature) or isinstance(selection, FeatureSet):
549
      self._javaobj.deselect(selection._javaobj)
550
    else:
551
      self._javaobj.deselect(selection)
552

    
553
  def isSelected(feature):
554
    """Returns True if given feature is selected"""
555
    if isinstance(feature, Feature):
556
      self._javaobj.isSelect(feature._javaobj)
557
    else:
558
      self._javaobj.isSelect(feature)
559
      
560
  def getCount(self):
561
    """Returns the number of elements in the selection"""
562
    return self.getSelectedCount()
563
    
564
    
565
class Iterator(WrapperToJava):
566

    
567
  def __init__(self,iterator):
568
    WrapperToJava.__init__(self,iterator)
569

    
570
  def next(self):
571
    if not self.hasNext():
572
      raise StopIteration()
573
    return Feature(self().next())
574
    
575
class Feature(WrapperToJava):
576
  """Represents feature data It's a wrapper from gvSIG 
577
  org.gvsig.fmap.dal.feature.impl.DefaultFeature class
578
  """
579
  def __init__(self,feature):
580
    WrapperToJava.__init__(self,feature)
581
    self.featureNoEditable = None
582

    
583
  def getCopy(self):
584
    return Feature(self._javaobj.getCopy())
585

    
586
  def geometry(self):
587
    """Returns feature geometry"""
588
    return self.getDefaultGeometry()
589
   
590
  def getValues(self):
591
    """Returns dictionary with the pair name, value, feature attributes"""
592
    descriptor = self.getType()
593
    items = dict()
594
    for attr in descriptor.getAttributeDescriptors():
595
      name = attr.getName()
596
      value = self.get(attr.getName())
597
      items[name] = value
598
    return items 
599
  
600
  def edit(self):
601
    """Returns editable feature instance"""
602
    if not isinstance(self._javaobj, EditableFeature):
603
      self.featureNoEditable = self._javaobj
604
      self._javaobj = self._javaobj.getEditable()
605
  
606
  def getEditable(self):
607
    return Feature(self().getEditable())
608

    
609
  def __getitem__(self,key):
610
    return self.get(key)
611
  
612
  def __getattr__(self,name):
613
    #
614
    # FIX console error when try to introspect feature object
615
    if name in ('__methods__'):
616
        return dict()
617
    elif name in ('__members__'):
618
        return self.getValues().keys()
619
    elif name == '__dict__':
620
        return self.getValues()      
621
        
622
    try:
623
      v = getattr(self._javaobj, name, None)
624
      if v == None:
625
        v = self().get(name)        
626
      return v
627
    except Throwable, ex:
628
      raise RuntimeException("Can't access to attribute %s of feature (%s)" % (name, str(ex)))    
629

    
630
class Schema(WrapperToJava):
631
  """Stores data properties definition. Represents gvSIG FeatureType
632
  (org.gvsig.fmap.dal.feature.impl.DefaultFeatureType)
633
  """
634

    
635
  def __init__(self, featureType):
636
    WrapperToJava.__init__(self,featureType)
637
    self.featureTypeNoEditable = None
638
  
639
  def append(self, name, type, size=None, default=None, precision=4):
640
    """Adds new property to feature properties definition. If error occurs 
641
    raises RuntimeError.    
642
    :param name: Feature property name
643
    :type name: String
644
    :param type: Feature property type
645
    :type name: String
646
    :param size: Feature property size
647
    :type size: int
648
    :param default: Feature property default value
649
    :return: new atribute
650
    """
651
    if not isinstance(self._javaobj, EditableFeatureType):
652
        self.modify()
653
    
654
    if isinstance(type, str):
655
      try:
656
        application = ApplicationLocator.getManager()
657
        datamanager =  application.getDataManager()
658
        dataTypes = application.getDataTypesManager()
659
        type = dataTypes.getType(type) #dataType constant value from string
660
      except:
661
        raise RuntimeError(
662
            "Feature Property Data type (%s) is not valid.  name=%s, type=%s, size=%s, default=%s)" % (
663
                type, 
664
                name, 
665
                type, 
666
                size, 
667
                default
668
            )
669
        )
670
    if isinstance(type, int):
671
      try:
672
        type = dataTypes.get(type)
673
      except:
674
        raise RuntimeError(
675
            "Data type (%s) is not valid.  name=%s, type=%s, size=%s, default=%s)" % (
676
                type, 
677
                name, 
678
                type, 
679
                size, 
680
                default
681
            )
682
        )
683
      
684
    attribute = self.add(name, type.getType())
685
 
686
    if size != None: 
687
      attribute.setSize(size)
688
    
689
    if default != None:
690
      attribute.setDefaultValue(default)
691
      
692
    if precision != None and type.getType() in (DataTypes.DOUBLE, DataTypes.FLOAT):
693
      attribute.setPrecision(precision)
694
    
695
    if type.getType() == DataTypes.GEOMETRY and self.getDefaultGeometryAttributeName()==None:
696
      self.setDefaultGeometryAttributeName(name)
697
    
698
    return attribute
699

    
700
  def __getitem__(self, name):
701
    try:
702
      return self._javaobj.getAttributeDescriptor(name)
703
    except java.lang.IndexOutOfBoundsException:
704
      raise StopIteration
705

    
706
  def get(self, name, default=None):
707
    """Returns a feature attribute descriptor that contains information about 
708
    one feature attribute, such as its name, data type or precision. 
709
    :param name: Attribute name
710
    :type name: string
711
    :param default: Value to return if no attribute name found. 
712
    :return: AttributeDescriptor
713
    """
714
    x = self.getAttributeDescriptor(name)
715
    if x == None:
716
      return default
717
    return x
718
  
719
  def getAttrNames(self):
720
    """Returns a list with attributes names"""
721
    if not self.getAttributeDescriptors():
722
      return None
723
        
724
    return [attr.getName() for attr in self.getAttributeDescriptors()]
725
    
726
    
727
  def getCopy(self):
728
    """Returns a itself clone"""
729
    return Schema(self().getCopy())
730
  
731
  def modify(self):
732
    """Sets edit mode"""
733
    if not isinstance(self._javaobj, EditableFeatureType):
734
      self.featureTypeNoEditable = self._javaobj
735
      self._javaobj = self._javaobj.getEditable()
736

    
737
      
738
#=====================#
739
# Vectorial Functions #
740
#=====================#
741

    
742
def createSchema(schema = None):
743
  """Returns attributes definition. If Schema is recived then makes a copy and 
744
  returns editable instance. Otherwise returns empty Schema.
745
  :param schema: Schema to make a copy
746
  :type schema: Schema
747
  """
748
  if isinstance(schema, Schema):
749
    try:  
750
      s = schema.getCopy()
751
      s.modify()
752
      return s
753
    except:
754
      pass
755
    
756
  application = ApplicationLocator.getManager()
757
  datamanager =  application.getDataManager()
758
  return Schema(datamanager.createFeatureType())
759

    
760
def createLayer(schema, servertype, layertype=None, **parameters):
761
  """
762
  Returns new layer
763
  :param schema: layer data definition
764
  :type schema: Schema
765
  :param servertype: 
766
  :type servertype: string
767
  :return: new layer
768
  :rtype: Layer
769
  :raise: RuntimeException
770
  """
771
  if layertype == None:
772
    layertype = servertype
773
    servertype = "FilesystemExplorer"
774

    
775
  if layertype == "Shape" :
776
    if schema.get("GEOMETRY",None) == None:
777
      raise RuntimeException("Shape need a field named GEOMETRY in the schema")
778
    
779
  if parameters["geometryType"] == None:
780
    raise RuntimeException("Invalid geometry type for new layer")
781
      
782
  try:
783
    application = ApplicationLocator.getManager()
784
    datamanager =  application.getDataManager()
785

    
786
    mapcontextmanager = application.getMapContextManager()
787

    
788
    server_parameters = datamanager.createServerExplorerParameters(servertype)
789
    copyToDynObject(parameters, server_parameters)
790

    
791
    server = datamanager.openServerExplorer(servertype, server_parameters)
792

    
793
    store_parameters = server.getAddParameters(layertype)
794
    copyToDynObject(parameters, store_parameters)
795
    store_parameters.setDefaultFeatureType(schema())
796

    
797
    server.add(layertype, store_parameters, True)
798

    
799
    store = datamanager.openStore(layertype, store_parameters)
800

    
801
    layer = mapcontextmanager.createLayer(store.getName(), store)
802

    
803
    return Layer(layer)
804
  except Throwable, ex:
805
    raise RuntimeException("Can't create layer, "+ str(ex))
806

    
807
def loadShapeFile(shpFile, CRS="CRS:84"):
808
    """
809
    Add existing shape file to the view. Returns Layer shape file
810
    :param shpFile: absolute file path
811
    :type: shpFile: string
812
    :param CRS: projection code
813
    :type CRS: string
814
    :return: the shape
815
    :type return: Layer
816
    """
817
    layer = loadLayer('Shape', shpFile=shpFile, CRS=CRS)
818
    currentView().addLayer(layer)
819
    layer.setActive(True)
820
    return Layer(layer)
821
    
822
def loadLayer(layerType, **parameters):
823
    try:
824
        application = ApplicationLocator.getManager()
825
        datamanager =  application.getDataManager()
826
        mapcontextmanager = application.getMapContextManager()
827
        store_parameters = datamanager.createStoreParameters(layerType)
828
        copyToDynObject(parameters, store_parameters)
829
        store = datamanager.openStore(layerType, store_parameters)        
830
        layer = mapcontextmanager.createLayer(store.getName(), store)
831
    except Throwable, ex:
832
        raise RuntimeException("Can't load layer, "+ str(ex))  
833

    
834
    return layer
835
    
836
def createShape(definition, filename, geometryType, CRS="CRS:84"):
837
  """
838
  Return new shape layer 
839
  :param definition: layer data definition
840
  :type definition: Schema
841
  :param filename: absolute path for shape files. 
842
  :type filename: string
843
  :param geometryType: geometry type for shape
844
  :type geometryType: string
845
  :return: new shape layer
846
  :rtype: Layer
847
  """
848
  return createLayer(
849
    definition, 
850
    "FilesystemExplorer", 
851
    "Shape", 
852
    shpFile=filename, 
853
    CRS=CRS,
854
    geometryType = geometryType
855
  )
856

    
857
def createTable(schema, servertype, tableType=None, **parameters):
858
  """Creates a new Table document"""
859
  if tableType == None:
860
    tableType = servertype
861
    servertype = "FilesystemExplorer"
862

    
863
  try:
864
    application = ApplicationLocator.getManager()
865
    datamanager =  application.getDataManager()
866
    
867
    server_parameters = datamanager.createServerExplorerParameters(servertype)
868
    copyToDynObject(parameters, server_parameters)
869

    
870
    server = datamanager.openServerExplorer(servertype, server_parameters)
871
    
872
    store_parameters = server.getAddParameters(tableType)
873
    copyToDynObject(parameters, store_parameters)
874
    store_parameters.setDefaultFeatureType(schema())
875
    
876
    server.add(tableType, store_parameters, True)
877

    
878
    store = datamanager.openStore(tableType, store_parameters)
879
    
880
    return Table(store)
881
  
882
  except Throwable, ex:
883
    raise RuntimeException("Can't create table, "+ str(ex))
884
  
885
def createDBF(definition, DbfFile, CRS="CRS:84"):
886
  """
887
  Creates a new dbf document 
888
  :param definition: layer data definition
889
  :type definition: Schema
890
  :param DbfFile: absolute path for shape files. 
891
  :type DbfFile: string
892
  :return: new dbf
893
  :rtype: Table    
894
  """
895
  return createTable(
896
    definition, 
897
    "FilesystemExplorer", 
898
    "DBF", 
899
    DbfFile=DbfFile, 
900
    CRS=CRS,
901
  )
902

    
903
#=====================#
904
# Documents Functions #
905
#=====================#  
906

    
907
def currentProject():
908
  """
909
  Returns current gvSIG proyect
910
  :return: Proyect
911
  """
912
  application = ApplicationLocator.getManager()
913
  project = application.getCurrentProject()
914
  return Project(project)
915

    
916
def currentDocument(documentClass = None):
917
  """
918
  Returns the current active document if it's a DocumentTable or 
919
  DocumentView2D return None
920
  :return: Active document, None
921
  """
922
  application = ApplicationLocator.getManager()
923
  
924
  if documentClass == None:
925
    doc = application.getActiveDocument()
926
  else:
927
    doc = application.getActiveDocument(documentClass)
928
  if isinstance(doc, TableDocument):
929
    return Table(doc)
930
  if isinstance(doc, ViewDocument):
931
    return View(doc)  
932

    
933
  return None  
934
  
935
def currentTable():
936
  """
937
  Returns active table document or None 
938
  :return: Table or None
939
  """  
940
  return currentDocument(TableDocument)
941
  
942
def currentView():
943
  """
944
  Returns the current active view document or None 
945
  :return: View or None
946
  """ 
947
  return currentDocument(ViewDocument)
948

    
949
def currentLayer():
950
  """
951
  Returns current view active layer or None
952
  :return: gvSIG active layer
953
  """
954
  try:
955
    return currentView().getLayer()
956
  except:
957
    return None
958

    
959
#=====================#
960
# Simbology Functions #
961
#=====================#  
962
COLORS = {
963
    'black': Color.black,
964
    'blue': Color.blue,
965
    'cyan': Color.cyan,
966
    'darkGray': Color.darkGray,
967
    'gray': Color.gray,
968
    'green': Color.green,
969
    'lightGray': Color.lightGray,
970
    'magenta': Color.magenta,
971
    'orange': Color.orange,
972
    'pink': Color.pink,
973
    'red': Color.red,
974
    'white': Color.white,
975
    'yellow': Color.yellow,
976
}
977
  
978
def simplePointSymbol(color=None):
979
  """
980
  Returns simple point symbol using parameter color. If no color 
981
  use a ramdom color
982
  :param color: String color name or Java awt Color
983
  :return: gvSIG point symbol
984
  """
985
  if isinstance(color, str) and COLORS.has_key(color.lower()):
986
    color = COLORS.get(color)
987
    
988
  if not isinstance(color, Color):
989
      color = getDefaultColor()
990
      
991
  return MapContextLocator.getSymbolManager().createSymbol(
992
        Geometry.TYPES.POINT, color)
993

    
994
def simpleLineSymbol(color=None):
995
  """
996
  Returns simple line symbol using parameter color. If no color use a 
997
  ramdom color  
998
  :param color: String color name or Java awt Color
999
  :return: gvSIG line symbol
1000
  
1001
  """
1002
  if isinstance(color, str) and COLORS.has_key(color.lower()):
1003
    color = COLORS.get(color)
1004

    
1005
  if not isinstance(color, Color):
1006
      color = getDefaultColor()
1007
      
1008
  return MapContextLocator.getSymbolManager().createSymbol(
1009
        Geometry.TYPES.CURVE, color)
1010

    
1011
def simplePolygonSymbol(color = None):
1012
  """
1013
  Returns simple polygon symbol using parameter color. If no color 
1014
  use a ramdom color.  
1015
  :param color: String color name or Java awt Color
1016
  :return: gvSIG polygon symbol
1017
  """
1018
  if isinstance(color, str) and COLORS.has_key(color.lower()):
1019
    color = COLORS.get(color)
1020

    
1021
  if not isinstance(color, Color):
1022
      color = getDefaultColor()
1023
  
1024
  return MapContextLocator.getSymbolManager().createSymbol(
1025
        Geometry.TYPES.SURFACE, color)
1026
  
1027

    
1028
#=========================================#
1029
# gvSIG Application Preferences Functions #
1030
#=========================================#  
1031

    
1032
def getDataFolder():
1033
  """
1034
  Returns gvSIG data folder. This folder is defined in application 
1035
  preferences. If is not defined returns None.
1036
  """
1037
  return Preferences.userRoot().node("gvsig.foldering").get('DataFolder', None)
1038
  
1039
def getProjectsFolder():
1040
  """
1041
  Returns gvSIG projects folder. This folder is defined in application 
1042
  preferences. If is not defined returns None.
1043
  """
1044
  return Preferences.userRoot().node("gvsig.foldering").get(
1045
        'ProjectsFolder', None)
1046

    
1047
def getColorFromRGB(r, g, b, a=None):
1048
  """
1049
  Returns an sRGB color with the specified red, green, blue, and alpha 
1050
  (optional) values in the range (0 - 255).
1051
  """
1052
  if a:
1053
    color = Color(r, g, b, a)
1054
  else:
1055
    color = Color(r, g, b)
1056
  
1057
  return color
1058
  
1059
def getDefaultColor(c = None):
1060
  """Returns gvsig default symbol fill color or ramdom color"""
1061
  if MapContextLocator.getSymbolManager().isDefaultSymbolFillColorAleatory():
1062
    color = Color(random.randint(0-255), 
1063
                random.randint(0-255), 
1064
                random.randint(0-255)
1065
            )
1066
  else:
1067
    sp = MapContextLocator.getSymbolManager().getSymbolPreferences()
1068
    color = sp.getDefaultSymbolFillColor()    
1069

    
1070
  return color  
1071
  
1072
#================#
1073
# OTHER          #
1074
#================#
1075

    
1076
def getCRS(crs):
1077
  """Returns Projection from string code (i.e. CRS:84) if exist or None if 
1078
  not.  
1079
  """
1080
  try:
1081
    return CRSFactory.getCRS(crs)
1082
  except:
1083
    return None
1084

    
1085
def copyToDynObject(values, target):
1086
  definition = target.getDynClass();
1087
  fields = definition.getDynFields();
1088
  for field in fields:
1089
    name = field.getName()
1090
    keys = values.keys()
1091
    for k in keys:
1092
      if k.lower() == name.lower():
1093
        target.setDynValue(name, values[name])
1094
        break
1095
# ====================================
1096
#
1097

    
1098
def main():
1099
  layer = currentLayer()
1100
  schema = createSchema()
1101
  schema.append("ID", "String", 50)
1102
  schema.append("GEOMETRY", "Geometry")
1103
  
1104
  output = createLayer(
1105
      schema, 
1106
      "FilesystemExplorer", 
1107
      "Shape", 
1108
      shpFile="/tmp/pp.shp", 
1109
      CRS="EPSG:23030", 
1110
      geometryType=POINT
1111
  )
1112
  
1113
  for feature in layer.features():
1114
    point = feature.geometry().centroid()
1115
    output.append(ID=feature.ID, GEOMETRY=point)
1116
      
1117
  output.commit() 
1118
  
1119
  currentView().addLayer(output())