@Override public ProjectedIndex<O, O> instantiate(Relation<O> relation) { if (!proj.getInputDataTypeInformation() .isAssignableFromType(relation.getDataTypeInformation())) { return null; } proj.initialize(relation.getDataTypeInformation()); final Relation<O> view; if (materialize) { DBIDs ids = relation.getDBIDs(); WritableDataStore<O> content = DataStoreUtil.makeStorage( ids, DataStoreFactory.HINT_DB, proj.getOutputDataTypeInformation().getRestrictionClass()); for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { content.put(iter, proj.project(relation.get(iter))); } view = new MaterializedRelation<>( "ECEF Projection", "ecef-projection", proj.getOutputDataTypeInformation(), content, ids); } else { view = new ProjectedView<>(relation, proj); } Index inneri = inner.instantiate(view); if (inneri == null) { return null; } return new LngLatAsECEFIndex<>(relation, proj, view, inneri, norefine); }
/** * Preprocessing step: determine the radii of interest for each point. * * @param ids IDs to process * @param rangeQuery Range query * @param interestingDistances Distances of interest */ protected void precomputeInterestingRadii( DBIDs ids, RangeQuery<O> rangeQuery, WritableDataStore<DoubleIntArrayList> interestingDistances) { FiniteProgress progressPreproc = LOG.isVerbose() ? new FiniteProgress("LOCI preprocessing", ids.size(), LOG) : null; for (DBIDIter iditer = ids.iter(); iditer.valid(); iditer.advance()) { DoubleDBIDList neighbors = rangeQuery.getRangeForDBID(iditer, rmax); // build list of critical distances DoubleIntArrayList cdist = new DoubleIntArrayList(neighbors.size() << 1); { int i = 0; DoubleDBIDListIter ni = neighbors.iter(); while (ni.valid()) { final double curdist = ni.doubleValue(); ++i; ni.advance(); // Skip, if tied to the next object: if (ni.valid() && curdist == ni.doubleValue()) { continue; } cdist.append(curdist, i); // Scale radius, and reinsert if (alpha != 1.) { final double ri = curdist / alpha; if (ri <= rmax) { cdist.append(ri, Integer.MIN_VALUE); } } } } cdist.sort(); // fill the gaps to have fast lookups of number of neighbors at a given // distance. int lastk = 0; for (int i = 0, size = cdist.size(); i < size; i++) { final int k = cdist.getInt(i); if (k == Integer.MIN_VALUE) { cdist.setValue(i, lastk); } else { lastk = k; } } // TODO: shrink the list, removing duplicate radii? interestingDistances.put(iditer, cdist); LOG.incrementProcessed(progressPreproc); } LOG.ensureCompleted(progressPreproc); }