Developer Discussions

Discuss topics with other Hexagon Geospatial Power Portfolio developers and experts to get the most out of our products.
Showing results for 
Search instead for 
Do you mean 
Reply
jai
Contributor
Posts: 41
Registered: ‎10-12-2015
Accepted Solution

Tool tip and symbology on new feature in offline mode.

Hi Team,

 

Need help in implementing Tool tip and symbology on new feature in offline mode.

 

Thanks,

Jai Ram Gaur

Community Manager
Posts: 173
Registered: ‎10-09-2015

Re: Tool tip and symbology on new feature in offline mode.

And what exactly do you need?

 

Regards

Thomas Anzinger
Community Manager
thomas.anzinger@hexagongeospatial.com
jai
Contributor
Posts: 41
Registered: ‎10-12-2015

Re: Tool tip and symbology on new feature in offline mode.

Hi Thomas,

 

Client want to add new feature in offline mode and want to see symbology, tool tip and dynamic labelling.

E.g. a user add new point feature in offline mode and one of its attribute need to be visible always as label and another attribute on tool tip.

 

If we have any existing sample will help.

 

Thanks,

Jai Ram Gaur

Community Manager
Posts: 173
Registered: ‎10-09-2015

Re: Tool tip and symbology on new feature in offline mode.

And what should happen to the feature when the user is back online?

Is this just a temp feature for the user on the client side?

Thomas Anzinger
Community Manager
thomas.anzinger@hexagongeospatial.com
jai
Contributor
Posts: 41
Registered: ‎10-12-2015

Re: Tool tip and symbology on new feature in offline mode.

Hi Thomas,

 

It's on existing feature which is synchronized from online to offline. It is not new and temp feature on client side.

 

Thanks,

Jai Ram Gaur

Community Manager
Posts: 173
Registered: ‎10-09-2015

Re: Tool tip and symbology on new feature in offline mode.

So standard offline capabilities should do the job.

Create an offline form associated with this feature in GMSC and if your symbology and your tooltip are configured correctly, the item will show up correctly once it is persisted in offline mode. 

Thomas Anzinger
Community Manager
thomas.anzinger@hexagongeospatial.com
jai
Contributor
Posts: 41
Registered: ‎10-12-2015

Re: Tool tip and symbology on new feature in offline mode.

Hi Thomas,

 

Offline it works for existing geometry in the feature but when we add new geometry it does not show tool tip, symbology and label.

 

Thanks,

Jai Ram Gaur

Community Manager
Posts: 173
Registered: ‎10-09-2015

Re: Tool tip and symbology on new feature in offline mode.

Jai,

this does not sound like a developer issue as we are talking about standard GMSC usage and configuration.

Please contact standard support for this.

In general GMSC does not support custom symbology for features that were modified (new or updated) offline. These elements get a special symbology and this behavior may not be changed.

 

Within this board we should only talk about programming issues.

 

Regards 

Thomas Anzinger
Community Manager
thomas.anzinger@hexagongeospatial.com
Highlighted
Occasional Contributor
Posts: 9
Registered: ‎01-15-2016

Re: Tool tip and symbology on new feature in offline mode.

Hi All,

 

We solved the symbology part of this in the past by creating a GLayerFilter that would process any geometries in a feature layer.

For this to work, you need to have all of your styling rules pre-setup in GMSC Administrator.

We also downloaded a copy of the RPI_SYMBOLOGYDISPLAYRULE table to our local H2 database ( That is a default part of our framework ), but you can define rules in XML or java code if you like.

 

The Filter would call what we called a FilterAgent.

In the filter agent we created a temporary in memory database, created a table in that database with a column set the same as the set of attributes on the geometry, added the record and then used that record to interpret the style's predicate. ( Saved us writing a SQL parser )

 

You might ask if creating so many tables, populating them and interrogating them is very effecient, but it only has to do it once while the features are being prepared.

 

 

Hope this helps.

 

John

 

package com.intergraph.sgi.offline.plugin.rendering.filter;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Iterator;
import java.util.Map;

import com.intergraph.web.viewer.data.GPrimitive;
import com.intergraph.web.viewer.reader.gdoplus.CustomValue;
import com.intergraph.web.viewer.reader.gdoplus.ValueType;

public class FilterAgent {

	public static Connection memConn = null;
	
	
	
	public static Connection getMemoryConnection() throws Exception{
		
		if ( memConn == null){
			Class.forName("org.h2.Driver");
			String url = "jdbc:h2:mem:";
			
			memConn = DriverManager.getConnection(url);
		}
		
		return memConn;
	}
	
	public static void insertRecord( GPrimitive pr ) throws Exception {
		
		Map< String, CustomValue > values = pr.getCustomValues();
		
		Iterator<String> iter = values.keySet().iterator();

		StringBuffer sql = new StringBuffer( "INSERT INTO TABLE$$TMP$$ (" );
		StringBuffer paramSql = new StringBuffer( ") VALUES (" );

		boolean first = true;

		while (iter.hasNext()) {
			
			String cName = iter.next();
			
			CustomValue customValue = values.get( cName );
			if ( customValue != null ){
				
				if ( !first){
					sql.append(",");
					paramSql.append(",");
				}
				
				sql.append( cName );
				paramSql.append(" ?");
				
				first = false;
			}
		}		
		
		sql.append(paramSql);
		sql.append(")");
		
		Connection con = getMemoryConnection();
		
		PreparedStatement pstmt = con.prepareStatement( sql.toString() );

		iter = values.keySet().iterator();

		int i =1;
		
		while (iter.hasNext()) {
			
			String cName = iter.next();
			
			CustomValue customValue = values.get( cName );
			if ( customValue != null ){
				pstmt.setObject(i++, customValue.getValue());
			}
		}
	
		pstmt.execute();
		
		pstmt.close();
		
	}
	
	public static boolean criteriaSatisfied( String predicate ) throws Exception {
		
		boolean rtn = false;
		
		if ( predicate == null ){
			return true;
		}
		
		String sql = "select * from TABLE$$TMP$$ where " + predicate;
		
		Connection con = getMemoryConnection();
		
		ResultSet rs = con.createStatement().executeQuery(sql);
	
		while (rs.next()) {
			rtn = true;
		
		}
		rs.close();
		
		return rtn;
		
	}
	
	
	public static void createTable( GPrimitive pr  ) throws Exception {
		
		Map< String, CustomValue > values = pr.getCustomValues();
		
		Iterator<String> iter = values.keySet().iterator();

		StringBuffer sql = new StringBuffer( "CREATE TABLE TABLE$$TMP$$ (" );

		boolean first = true;
		while (iter.hasNext()) {
			String cName = iter.next();
			if ( !first ){
				sql.append(",");
			}
			CustomValue customValue = values.get( cName );
			if ( customValue != null ){

				sql.append( cName );
				sql.append(" ");
				sql.append( getDataType(customValue));
				first = false;
			}
		}
		
		sql.append( ")" );
		
		Connection con = getMemoryConnection();
		
		Statement stmt = con.createStatement();
		
		stmt.execute( sql.toString() );
		
		stmt.close();
		
	}
	
	public static void dropTable( ) throws Exception {
		

		StringBuffer sql = new StringBuffer( "drop TABLE IF EXISTS TABLE$$TMP$$" );

		Connection con = getMemoryConnection();
		
		Statement stmt = con.createStatement();
		
		stmt.execute( sql.toString() );
		
		stmt.close();
		
	}

	private static String getDataType( CustomValue value ){
		
		String rtn = "NUMBER";

		if (  value.getValueType() == ValueType.TIMESTAMP ){
			return "TIMESTAMP";
		}		
		if (  value.getValueType() == ValueType.GUID ){
			return "VARCHAR2";
		}		
		
		if (  value.getValueType() == ValueType.STRING ){
			return "VARCHAR2";
		}		
		
		return rtn;
	}
	
}
package com.intergraph.sgi.offline.plugin.rendering.filter;

import com.intergraph.web.core.data.Project;
import com.intergraph.web.core.data.feature.Feature;
import com.intergraph.web.core.kernel.ApplicationContext;
import com.intergraph.web.viewer.data.GLayerFilter;

public class RendererFilter {
	
	public RendererFilter(){
		
	}
	
	public void applyFilter( String featureId ){
	
	//http://smartclient.intergraph.at/GMSC/en/API/Java/com/intergraph/web/viewer/data/GLayerFilter.html
    
	Feature feature = ApplicationContext.getProject().getFeatureByTitleOrID(featureId);
	Project p = ApplicationContext.getProject();
	
	boolean add = true;
	
	if ( feature != null ){
	    
    	GLayerFilter filter = feature.getFilter();
    	
    	while ( add && filter != null ){
    		if ( filter instanceof SGIGLayerFilter ){
    			add = false;
    		}
   			filter = filter.getChildFilter();
    	}
		
	    
	    if ( add ){
	    	GLayerFilter defaultFilter = feature.getFilter();

	    	GLayerFilter offlineLayerFilter = new SGIGLayerFilter( featureId );

		    if(defaultFilter == null){
		           feature.addFilter(offlineLayerFilter);
		           feature.reload();
		    }
		    else{
		           defaultFilter.addChildFilter(offlineLayerFilter);
		    	}
			}
		}
	}
}
package com.intergraph.sgi.offline.plugin.rendering.filter;

import java.util.Iterator;
import java.util.List;
import java.util.UUID;

import com.intergraph.sgi.offline.plugin.db.metadata.RPIFeature;
import com.intergraph.sgi.offline.plugin.model.RPIFeatureModel;
import com.intergraph.sgi.offline.plugin.model.RPISymbologyDisplayRule;
import com.intergraph.web.core.data.feature.Feature;
import com.intergraph.web.core.kernel.ApplicationContext;
import com.intergraph.web.viewer.data.GAction;
import com.intergraph.web.viewer.data.GDefaultDataLayer;
import com.intergraph.web.viewer.data.GLayerFilter;
import com.intergraph.web.viewer.data.GPrimitive;
import com.intergraph.web.viewer.map.style.GFeatureTypeStyleManager;

public class SGIGLayerFilter extends GLayerFilter {

	

	public String featureId = null;
	
	public SGIGLayerFilter( String featureId ){
		this.featureId = featureId;
	}
    @Override
    protected FilterType process(GDefaultDataLayer layer, FilteredObject filteredObject) {
    	
    	FilterType rtn = FilterType.Original;
    	
    	GPrimitive copiedPrimitive = null;
        
    	Feature fea = ApplicationContext.getProject().getFeatureByTitleOrID(featureId);
    	
    	List< UUID > styleRules = fea.getStyleIdList();
    	
    	int nFeas = fea.getRowCount();
    	
    	if ( nFeas > 0 ){
    	
	    	try {
		    	UUID styleId = fea.getStyleIdList().get(0);
		    	
		    	try {
		    		styleId = interpretRules( styleRules , filteredObject.getOriginal());
				} catch (Exception e) {
					//For now consume this as it is just for styling.
				}
		    	
		    	if ( layer != null && filteredObject != null ){

		        
		    		GPrimitive toFilter = filteredObject.getOriginal();
		
		    		if ( rtn != null ){
		    			if ( rtn == FilterType.Changed ){
		    				toFilter = filteredObject.filtered;
		    			}
		    			rtn =  FilterType.Original;
		    		}
		    		UUID id = toFilter.getStyle().getUniqueId();
		    		if ( !id.equals( styleId ) ){
		    			
		    			GAction action = filteredObject.getOriginal().getAction().clone();
		    			
		    			copiedPrimitive = toFilter.copy(action,GFeatureTypeStyleManager.getInstance().getStyle(styleId), 0.0, 0.0);
		    	        
		    			filteredObject.original = copiedPrimitive;
		    		}
		    		
		    	} 
		          
		    }catch (Exception e) {
		    	e.printStackTrace();
		    }
		}
        if(copiedPrimitive!=null){
       	
        	rtn = GLayerFilter.FilterType.Original;
        }
          
          return rtn;
    }
    
    public UUID interpretRules (List< UUID > styles, GPrimitive fea ) throws Exception{

    	RPIFeatureModel m = RPIFeature.getInstance().getModelForName(featureId);
    	

    	UUID rtn = styles.get(0);

    	if ( m.getSymbologyRules()!=null && m.getSymbologyRules().size() > 1 ){

    		FilterAgent.dropTable();
    		FilterAgent.createTable( fea );
    		FilterAgent.insertRecord( fea );
        	//prepareFeature( fea );

    		Iterator< RPISymbologyDisplayRule > rules = m.getSymbologyRules().iterator();
    		
    		boolean found = false;
    		
    		while (rules.hasNext() && !found) {
				RPISymbologyDisplayRule rule = (RPISymbologyDisplayRule) rules.next();
				
				if ( FilterAgent.criteriaSatisfied( rule.getFilter() ) ){
					found = true;
					rtn = UUID.fromString( rule.getSymbologyId() );
				}
			}
    		
    		FilterAgent.dropTable();
	   
		}
    	
    	return rtn;
    }
	

    @Override
    public GLayerFilter copy() {
          // TODO Auto-generated method stub
    	GLayerFilter filter = new SGIGLayerFilter(featureId);
    	if ( getChildFilter() != null ){
    		if ( ! (getChildFilter() instanceof SGIGLayerFilter )){
    			filter.addChildFilter( getChildFilter().copy() );
    		}
    	}
    	return filter;
    }
    
    @Override
    protected void clear() {
          // TODO Auto-generated method stub
          
    }
}


Community Manager
Posts: 173
Registered: ‎10-09-2015

Re: Tool tip and symbology on new feature in offline mode.

If I could give you more than 1 HexPoints I would do so!

Great work!

 

Regards

Thomas

Thomas Anzinger
Community Manager
thomas.anzinger@hexagongeospatial.com