To perform a GetFeatureInfo request, you must get an instance of a TLcdWMTSClient. The TLcdWMTSModelDecoder creates a model that has a domain object implementing the ILcdWMTSClientProvider interface. Using that domain object, you can retrieve the TLcdWMTSClient from the model:

ILcdModel model = layer.getModel();
if (!(model.getModelDescriptor() instanceof TLcdWMTSModelDescriptor)) {
  throw new IllegalArgumentException("Not a WMTS model");

try (TLcdLockUtil.Lock ignored = TLcdLockUtil.readLock(model)) {
  Enumeration<ILcdWMTSClientProvider> elements = model.elements();
  if (!elements.hasMoreElements()) {
    throw new IllegalArgumentException("No WMTS client found");

  TLcdWMTSClient client = elements.nextElement().getClient();

You also need a TLcdWMTSGetFeatureInfoContext. You can construct it with one of the public factory methods.

TLcdWMTSGetFeatureInfoContext getFeatureInfoContext = TLcdWMTSGetFeatureInfoContext.createContext(view, layer, x, y);

Finally, you can use the TLcdWMTSClient and the TLcdWMTSGetFeatureInfoContext to perform the GetFeatureInfo request and receive a GetFeatureInfo response. The GetFeatureInfo request implementation focuses on the use of "application/json" (GeoJSON) as feature info exchange format, so we can use a TLcdGeoJsonModelDecoder to read the response and create a model for it.

try (InputStream featureInfoInputStream = client.getFeatureInfo(getFeatureInfoContext)) {
  if (featureInfoInputStream != null) {
    // Setup the model decoder with an input stream factory that always returns aInputStream
    TLcdGeoJsonModelDecoder modelDecoder = new TLcdGeoJsonModelDecoder();
    modelDecoder.setInputStreamFactory(aIgnored -> featureInfoInputStream);

    // Source name doesn't exist. This doesn't really matter since we always use aInputStream.
    ALcdModel model = (ALcdModel) modelDecoder.decode("getFeatureInfo.json");