// Path: src/main/java/com/nextgis/maplib/api/IJSONStore.java
// public interface IJSONStore
// {
//     /**
//      * Store object in json
//      * @return json object with stored data
//      * @throws JSONException
//      */
//     JSONObject toJSON()
//             throws JSONException;
// 
//     /**
//      * Restore object from json
//      * @param jsonObject where the stored data are
//      * @throws JSONException
//      */
//     void fromJSON(JSONObject jsonObject)
//             throws JSONException;
// }
// 
// Path: src/main/java/com/nextgis/maplib/api/IStyleRule.java
// public interface IStyleRule
// {
//     /**
//      * Set style parameters
//      * @param style New style
//      * @param featureId The feature identifier to set style
//      */
//     void setStyleParams(
//             Style style,
//             long featureId);
// }
// 
// Path: src/main/java/com/nextgis/maplib/map/Layer.java
// public class Layer extends Table
//         implements ILayerView, IRenderer
// {
//     protected boolean     mIsVisible;
//     protected float       mMaxZoom;
//     protected float       mMinZoom;
//     protected IRenderer   mRenderer;
//     protected GeoEnvelope mExtents;
// 
// 
//     public Layer(
//             Context context,
//             File path)
//     {
//         super(context, path);
//         mExtents = new GeoEnvelope();
//     }
// 
//     @Override
//     public void runDraw(GISDisplay display)
//     {
//         if (mRenderer != null) {
//             mRenderer.runDraw(display);
//             //onDrawFinished(this.getId(), 1.0f);
//         }
//     }
// 
//     @Override
//     public void cancelDraw()
//     {
//         if (mRenderer != null) {
//             mRenderer.cancelDraw();
//         }
//     }
// 
//     @Override
//     public boolean isVisible()
//     {
//         return mIsVisible;
//     }
// 
//     @Override
//     public void setVisible(boolean visible)
//     {
//         mIsVisible = visible;
//         notifyLayerChanged();
//     }
// 
//     @Override
//     public float getMaxZoom()
//     {
//         return Float.compare(mMaxZoom, mMinZoom) == 0 ? GeoConstants.DEFAULT_MAX_ZOOM : mMaxZoom;
//     }
// 
//     @Override
//     public void setMaxZoom(float maxZoom)
//     {
//         mMaxZoom = maxZoom;
//     }
// 
//     @Override
//     public float getMinZoom()
//     {
//         return mMinZoom;
//     }
// 
//     @Override
//     public void setMinZoom(float minZoom)
//     {
//         mMinZoom = minZoom;
//     }
// 
//     @Override
//     public JSONObject toJSON()
//             throws JSONException
//     {
//         JSONObject rootConfig = super.toJSON();
//         rootConfig.put(JSON_MAXLEVEL_KEY, getMaxZoom());
//         rootConfig.put(JSON_MINLEVEL_KEY, getMinZoom());
//         rootConfig.put(JSON_VISIBILITY_KEY, isVisible());
//         return rootConfig;
//     }
// 
//     @Override
//     public void fromJSON(JSONObject jsonObject)
//             throws JSONException
//     {
//         super.fromJSON(jsonObject);
//         if (jsonObject.has(JSON_MAXLEVEL_KEY)) {
//             mMaxZoom = (float) jsonObject.getDouble(JSON_MAXLEVEL_KEY);
//         } else {
//             mMaxZoom = GeoConstants.DEFAULT_MAX_ZOOM;
//         }
//         if (jsonObject.has(JSON_MINLEVEL_KEY)) {
//             mMinZoom = (float) jsonObject.getDouble(JSON_MINLEVEL_KEY);
//         } else {
//             mMinZoom = GeoConstants.DEFAULT_MIN_ZOOM;
//         }
// 
//         mIsVisible = jsonObject.getBoolean(JSON_VISIBILITY_KEY);
// 
//         if(Constants.DEBUG_MODE){
//             Log.d(Constants.TAG, "Layer " + getName() + " is visible " + mIsVisible);
//             Log.d(Constants.TAG, "Layer " + getName() + " zoom limits from " + mMinZoom + " to " + mMaxZoom);
//         }
//     }
// 
//     @Override
//     public void onDrawFinished(
//             int id,
//             float percent)
//     {
//         if (mParent != null && mParent instanceof ILayerView) {
//             ILayerView layerView = (ILayerView) mParent;
//             layerView.onDrawFinished(id, percent);
//         }
//     }
// 
//     @Override
//     public void setViewSize(
//             int w,
//             int h)
//     {
// 
//     }
// 
//     @Override
//     public GeoEnvelope getExtents()
//     {
//         return mExtents;
//     }
// 
//     @Override
//     public IRenderer getRenderer()
//     {
//         return mRenderer;
//     }
// 
//     @Override
//     public void setRenderer(IRenderer renderer) {
//         mRenderer = renderer;
//     }
// }


import static com.nextgis.maplib.util.Constants.JSON_STYLE_RULE_KEY;
import com.nextgis.maplib.api.IJSONStore;
import com.nextgis.maplib.api.IStyleRule;
import com.nextgis.maplib.map.Layer;
import org.json.JSONException;
import org.json.JSONObject;
import static com.nextgis.maplib.util.Constants.JSON_NAME_KEY;
            Style styleClone = mStyle.clone();
            mStyleRule.setStyleParams(styleClone, featureId);
            applyField(styleClone, featureId);
            return styleClone;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return super.getStyle(featureId);
        }
    }


    public IStyleRule getStyleRule()
    {
        return mStyleRule;
    }


    public void setStyleRule(IStyleRule styleRule)
    {
        mStyleRule = styleRule;
    }


    @Override
    public JSONObject toJSON()
            throws JSONException
    {
        JSONObject rootJsonObject = super.toJSON();
        rootJsonObject.put(JSON_NAME_KEY, "RuleFeatureRenderer");

// Path: src/main/java/com/nextgis/maplib/api/IJSONStore.java
// public interface IJSONStore
// {
//     /**
//      * Store object in json
//      * @return json object with stored data
//      * @throws JSONException
//      */
//     JSONObject toJSON()
//             throws JSONException;
// 
//     /**
//      * Restore object from json
//      * @param jsonObject where the stored data are
//      * @throws JSONException
//      */
//     void fromJSON(JSONObject jsonObject)
//             throws JSONException;
// }
// 
// Path: src/main/java/com/nextgis/maplib/api/IStyleRule.java
// public interface IStyleRule
// {
//     /**
//      * Set style parameters
//      * @param style New style
//      * @param featureId The feature identifier to set style
//      */
//     void setStyleParams(
//             Style style,
//             long featureId);
// }
// 
// Path: src/main/java/com/nextgis/maplib/map/Layer.java
// public class Layer extends Table
//         implements ILayerView, IRenderer
// {
//     protected boolean     mIsVisible;
//     protected float       mMaxZoom;
//     protected float       mMinZoom;
//     protected IRenderer   mRenderer;
//     protected GeoEnvelope mExtents;
// 
// 
//     public Layer(
//             Context context,
//             File path)
//     {
//         super(context, path);
//         mExtents = new GeoEnvelope();
//     }
// 
//     @Override
//     public void runDraw(GISDisplay display)
//     {
//         if (mRenderer != null) {
//             mRenderer.runDraw(display);
//             //onDrawFinished(this.getId(), 1.0f);
//         }
//     }
// 
//     @Override
//     public void cancelDraw()
//     {
//         if (mRenderer != null) {
//             mRenderer.cancelDraw();
//         }
//     }
// 
//     @Override
//     public boolean isVisible()
//     {
//         return mIsVisible;
//     }
// 
//     @Override
//     public void setVisible(boolean visible)
//     {
//         mIsVisible = visible;
//         notifyLayerChanged();
//     }
// 
//     @Override
//     public float getMaxZoom()
//     {
//         return Float.compare(mMaxZoom, mMinZoom) == 0 ? GeoConstants.DEFAULT_MAX_ZOOM : mMaxZoom;
//     }
// 
//     @Override
//     public void setMaxZoom(float maxZoom)
//     {
//         mMaxZoom = maxZoom;
//     }
// 
//     @Override
//     public float getMinZoom()
//     {
//         return mMinZoom;
//     }
// 
//     @Override
//     public void setMinZoom(float minZoom)
//     {
//         mMinZoom = minZoom;
//     }
// 
//     @Override
//     public JSONObject toJSON()
//             throws JSONException
//     {
//         JSONObject rootConfig = super.toJSON();
//         rootConfig.put(JSON_MAXLEVEL_KEY, getMaxZoom());
//         rootConfig.put(JSON_MINLEVEL_KEY, getMinZoom());
//         rootConfig.put(JSON_VISIBILITY_KEY, isVisible());
//         return rootConfig;
//     }
// 
//     @Override
//     public void fromJSON(JSONObject jsonObject)
//             throws JSONException
//     {
//         super.fromJSON(jsonObject);
//         if (jsonObject.has(JSON_MAXLEVEL_KEY)) {
//             mMaxZoom = (float) jsonObject.getDouble(JSON_MAXLEVEL_KEY);
//         } else {
//             mMaxZoom = GeoConstants.DEFAULT_MAX_ZOOM;
//         }
//         if (jsonObject.has(JSON_MINLEVEL_KEY)) {
//             mMinZoom = (float) jsonObject.getDouble(JSON_MINLEVEL_KEY);
//         } else {
//             mMinZoom = GeoConstants.DEFAULT_MIN_ZOOM;
//         }
// 
//         mIsVisible = jsonObject.getBoolean(JSON_VISIBILITY_KEY);
// 
//         if(Constants.DEBUG_MODE){
//             Log.d(Constants.TAG, "Layer " + getName() + " is visible " + mIsVisible);
//             Log.d(Constants.TAG, "Layer " + getName() + " zoom limits from " + mMinZoom + " to " + mMaxZoom);
//         }
//     }
// 
//     @Override
//     public void onDrawFinished(
//             int id,
//             float percent)
//     {
//         if (mParent != null && mParent instanceof ILayerView) {
//             ILayerView layerView = (ILayerView) mParent;
//             layerView.onDrawFinished(id, percent);
//         }
//     }
// 
//     @Override
//     public void setViewSize(
//             int w,
//             int h)
//     {
// 
//     }
// 
//     @Override
//     public GeoEnvelope getExtents()
//     {
//         return mExtents;
//     }
// 
//     @Override
//     public IRenderer getRenderer()
//     {
//         return mRenderer;
//     }
// 
//     @Override
//     public void setRenderer(IRenderer renderer) {
//         mRenderer = renderer;
//     }
// }


// Path: src/main/java/com/nextgis/maplib/display/RuleFeatureRenderer.java
import static com.nextgis.maplib.util.Constants.JSON_STYLE_RULE_KEY;
import com.nextgis.maplib.api.IJSONStore;
import com.nextgis.maplib.api.IStyleRule;
import com.nextgis.maplib.map.Layer;
import org.json.JSONException;
import org.json.JSONObject;
import static com.nextgis.maplib.util.Constants.JSON_NAME_KEY;

            Style styleClone = mStyle.clone();
            mStyleRule.setStyleParams(styleClone, featureId);
            applyField(styleClone, featureId);
            return styleClone;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return super.getStyle(featureId);
        }
    }


    public IStyleRule getStyleRule()
    {
        return mStyleRule;
    }


    public void setStyleRule(IStyleRule styleRule)
    {
        mStyleRule = styleRule;
    }


    @Override
    public JSONObject toJSON()
            throws JSONException
    {
        JSONObject rootJsonObject = super.toJSON();
        rootJsonObject.put(JSON_NAME_KEY, "RuleFeatureRenderer");

        if (mStyleRule instanceof IJSONStore)