|
From: LSA <ls...@ng...> - 2011-07-19 08:33:39
|
Our clients complained that layer with 25000 point features (complex
stylings) took about 2 sec to render. Redraws are often enough since
some operations on map are performed.
These stylings show some specifics of data and besides, show selection
on map.
After my optimizations (dont know should I put this word in quotes
:joke:) rendering time changed from 2 sec to 700 miliseconds.
What I did:
0) Profiled my application with YourKit profiler (you can get a fully
functional 1 month trial copy for free) - where I found problems.
1) Replaced all CQL quieries like "Attr=1 OR Attr=5 OR Attr=7" with my
own AttributeInFilter class (attached). This AttributeInFilter (being a
dirty hack) just check the value of specific feature attribute to belong
to set of possible values.
2) Replaced all CQL quieries like "(TeamId=1 AND PersonId=2) OR
(TeamId=2 AND PersonId=7) OR (TeamId=3 AND PersonId=10)" with my own
AttributesInFilter class (attached). This AttributesInFilter (being a
dirty hack) checks the tupple of values of specific feature to be
contained in particular tupple set.
3) Due to some reasons, I had filters like and(and(f1,not(f2)),f3). I
replaced them with and(f1,not(f2),f3).
4) At CashingFeatureSource there is:
protected Iterator openIterator() {
Iterator it = features.iterator();
if(filter != null) {
it = new FilteringIterator<Feature>(it, filter);
}
if(targetSchema != sourceSchema) {
it = new ReTypingIterator(it, sourceSchema, targetSchema);
}
return it;
}
I changed it to (commented out the ReTypingIterator):
protected Iterator openIterator() {
Iterator it = features.iterator();
if(filter != null) {
it = new FilteringIterator<Feature>(it, filter);
}
/* if(targetSchema != sourceSchema) {
it = new ReTypingIterator(it, sourceSchema, targetSchema);
}*/
return it;
}
Dont know exactly why it was here, but it works without it, anyway.
5) At FidFilterImplementation (my version is attached) - I added
specific code to work with SimpleFeature.
OLD Version:
public boolean evaluate(Object feature) {
if (feature == null) {
return false;
}
final Set fids = fids();
final String attPath = "@id";
PropertyAccessor accessor =
PropertyAccessors.findPropertyAccessor(feature, attPath, null, null);
if (accessor == null) {
return false;
}
Object id = accessor.get(feature, attPath, null);
return fids.contains(id);
}
NEW Version:
public boolean evaluate(Object feature) {
if (feature == null) {
return false;
}
final Set fids = fids();
/// BEGIN ADDED CODE
if (feature instanceof SimpleFeature){
SimpleFeature simpleFeature = (SimpleFeature)feature;
return fids.contains(simpleFeature.getID());
}
/// END ADDED CODE
final String attPath = "@id";
PropertyAccessor accessor =
PropertyAccessors.findPropertyAccessor(feature, attPath, null, null);
if (accessor == null) {
return false;
}
Object id = accessor.get(feature, attPath, null);
return fids.contains(id);
}
I understand this to be non-universal and error prone, but for
shapefiles (which is the only case for me) this seems to be working.
Hope this helps,
Sergey
|