jiayuasu commented on code in PR #3312:
URL: https://github.com/apache/sedona/pull/3312#discussion_r3939865839


##########
common/src/main/java/org/apache/sedona/common/utils/PropertyMaskedRenderedImage.java:
##########
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.common.utils;
+
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+import java.util.Arrays;
+import java.util.Vector;
+
+/**
+ * A {@link RenderedImage} that delegates everything to a source image but 
hides a single property.
+ *
+ * <p>Image properties cannot be removed in place: {@link 
javax.media.jai.RenderedImageAdapter}
+ * declares {@code getProperty} final and answers from the source, so {@code 
removeProperty} cannot
+ * mask an inherited value. Wrapping is also the only way to drop a property 
without touching pixels
+ * — copying the raster would materialize a lazily decoded image and lose a 
non-zero image origin.
+ */
+public class PropertyMaskedRenderedImage implements RenderedImage {
+  private final RenderedImage source;
+  private final String maskedProperty;
+
+  private PropertyMaskedRenderedImage(RenderedImage source, String 
maskedProperty) {
+    this.source = source;
+    this.maskedProperty = maskedProperty;
+  }
+
+  /**
+   * Wrap {@code source} so that {@code propertyName} reads back as {@link 
Image#UndefinedProperty}.
+   * Returns the source unchanged when it does not carry the property.
+   */
+  public static RenderedImage mask(RenderedImage source, String propertyName) {
+    if (source.getProperty(propertyName) == Image.UndefinedProperty) {
+      return source;
+    }
+    return new PropertyMaskedRenderedImage(source, propertyName);

Review Comment:
   Could we preserve `WritableRenderedImage` when the source is writable? 
Clearing NoData currently makes an editable coverage read-only. I reproduced 
this through the Java API:
   
   ```java
   import java.awt.image.WritableRenderedImage;
   import javax.media.jai.PlanarImage;
   import it.geosolutions.jaiext.range.NoDataContainer;
   import org.apache.sedona.common.raster.*;
   
   var raster = RasterConstructors.makeEmptyRaster(1, "d", 4, 3, 0, 0, 1);
   raster = RasterBandEditors.setBandNoDataValue(raster, 1, -9999.0);
   ((PlanarImage) raster.getRenderedImage()).setProperty(
       NoDataContainer.GC_NODATA, new NoDataContainer(-9999.0));
   
   System.out.println(raster.isDataEditable()); // true
   var cleared = RasterBandEditors.setBandNoDataValue(raster, 1, null);
   System.out.println(cleared.isDataEditable()); // false
   ((WritableRenderedImage) cleared.getRenderedImage()).getWritableTile(0, 0);
   // ClassCastException
   ```
   
   This affects Java/GeoTools callers using writable tiles; I haven't found a 
Spark SQL failure from it. A writable subclass selected only for writable 
sources, forwarding the eight `WritableRenderedImage` methods, looks like a 
small way to preserve that capability while keeping the lazy wrapper. A test 
that acquires, writes, and releases a tile after clearing would cover it.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to