Thanks Andrea..that's a nice design -- similar to the EMF command designs -- though they aren't really suited here mostly because I need a lighter weight (better performing solution).
However...they did give me exactly the pointers I needed for how to accomplish what I wanted. Mimicking what the SetAttributeEditCommand is doing, I'm able to update the attribute in the shape file itself.
Here's my test code on the chance it will be useful for others..I'm just walking through each attribute and assigning it a random color.
public void createPartControl(Composite parent) {
...
URL resourceId = new URL(
style = styleFactory.createStyle();
ICatalog localCatalog = CatalogPlugin.getDefault().getLocalCatalog();
List<IService> services = CatalogPlugin.getDefault().getServiceFactory().createService(resourceId);
IService service = services.get(0);
localCatalog.add(services.get(0));
resource = service.resources(null).get(0);
featureSource = resource.resolve(FeatureSource.class, null);
try {
FeatureCollection<SimpleFeatureType, SimpleFeature> shapeFeatures = featureSource.getFeatures();
features = DataUtilities.collection(shapeFeatures);
layer = getMap().getLayerFactory().createLayer(resource);
getMap().getLayersInternal().add(layer);
layer.getStyleBlackboard().put(SLDContent.ID, style);
featureStore = service.resolve(ShapefileDataStore.class, null);
} catch (IOException e1) {
throw new RuntimeException(e1);
}
createStyle();
...
new Thread() {
public void run() {
while (true) {
try {
sleep(500); //Need a delay to avoid buffering issues..
} catch (InterruptedException e) {
}
try {
// setDirty(true); doesn't seem neccesary..
viewer.getRenderManager().refresh(null);
modMap();
} catch (Exception e) {
System.err.println(e);
}
}
};
}.start();
Iterator iterator = features.iterator();
try {
// DefaultTransaction transaction = new DefaultTransaction("test");
FeatureWriter<SimpleFeatureType, SimpleFeature> writer = featureStore
.getFeatureWriter(Transaction.AUTO_COMMIT);
for (Feature feature = (Feature) iterator.next(); iterator.hasNext(); feature = (Feature) iterator.next()) {
SimpleFeature sf = (SimpleFeature) feature;
Long l = (long) (Math.random() * features.size());
try {
SimpleFeature next = writer.next();
next.setAttribute("MY_ATTR", l);
writer.write();
} catch (IOException e) {
throw new RuntimeException(e);
}
// try {
// transaction.commit();
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
}
writer.close();
// transaction.commit();
// transaction.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
features.close(iterator);
On Aug 13, 2010, at 1:23 PM, andrea antonello wrote:
Hi Miles,
On Fri, Aug 13, 2010 at 9:47 PM, Miles Parker <
milesparker@xxxxxxxxx> wrote:
Hi,
I hope this is the appropriate place to ask this question -- not sure if it
is a geotools issue or if that even matters.
I got the map viewer (IViewPart implementation) working well, and I was able
to get styles to update dynamically, so I think I more or less have the
basic patterns worked out. But I'm having trouble figuring out the recipe
for my key use case:
"Change feature attributes dynamically and have those changes reflected on
the map."
I will try to stop here at first and point you to this:
http://udig.refractions.net/confluence/display/DEV/4+Edit+Commandswhich is part of:
http://udig.refractions.net/confluence/display/DEV/04+Commands
It shows how to delete a feature but I remember there is also a create
feature and set attribute/geometry. Just look into the Type Hierarchy
and you will have them.
Hope that helps, else let me know,
Ciao
Andrea
I have the first part, in that I figured out how that the ShapeFileDataStore
was read only. So I created a MemoryDataStore for that. I gather that that
is slow, but I couldn't see a better way of making the shape file
modifiable. Now, I can get the attributes to change to new values. As I
mentioned, I can also get a map to update regularly. But I can't get the
values to hook up with the map.
First, I load in the shape file like so:
URL resourceId = new URL(
"file:///blah/blah/shapefiles/blah/foo.shp");
ICatalog localCatalog =
CatalogPlugin.getDefault().getLocalCatalog();
List<IService> services =
CatalogPlugin.getDefault().getServiceFactory().createService(resourceId);
for (IService service : services) {
localCatalog.add(service);
for (IGeoResource resource : service.resources(null)) {
FeatureSource<SimpleFeatureType, SimpleFeature>
featureSource = resource
.resolve(FeatureSource.class, null);
Then, I copy the feature into the memory store (I think..)
FeatureCollection<SimpleFeatureType, SimpleFeature>
shapeFeatures = featureSource.getFeatures();
features = DataUtilities.collection(shapeFeatures);
MemoryDataStore mds = new MemoryDataStore(features);
mdsStore =
mds.getFeatureSource(featureSource.getName());
Now, I can add the original resource into the map..and as I say form that it
displays properly, I can modify styles, etc..
Layer createLayer =
getMap().getLayerFactory().createLayer(resource);
getMap().getLayersInternal().add(createLayer);
createLayer.getStyleBlackboard().put(SLDContent.ID,
style);
Here's where I'm stuck, but perhaps there is a better approach altogether..
I can't actually figure out how to get an IGeoResource for the MapDataStore
to add it into the set of layers. I mean, this has to be straightforward
but..?
thanks for any hints,
Miles
_______________________________________________
User-friendly Desktop Internet GIS (uDig)
http://udig.refractions.net
http://lists.refractions.net/mailman/listinfo/udig-devel
_______________________________________________
User-friendly Desktop Internet GIS (uDig)
http://udig.refractions.net
http://lists.refractions.net/mailman/listinfo/udig-devel